From 145abc15d57fb29701a12e8a14dcb9c1fd72e9be Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Mon, 7 Dec 2020 22:58:44 +0900 Subject: Renaming of files in preparation for code style tools. Signed-off-by: Michele Calgaro --- ksysguard/gui/SensorDisplayLib/BarGraph.cc | 177 ---- ksysguard/gui/SensorDisplayLib/BarGraph.cpp | 177 ++++ ksysguard/gui/SensorDisplayLib/CMakeLists.txt | 12 +- ksysguard/gui/SensorDisplayLib/DancingBars.cc | 353 -------- ksysguard/gui/SensorDisplayLib/DancingBars.cpp | 353 ++++++++ .../gui/SensorDisplayLib/DancingBarsSettings.cc | 398 --------- .../gui/SensorDisplayLib/DancingBarsSettings.cpp | 398 +++++++++ ksysguard/gui/SensorDisplayLib/DummyDisplay.cc | 58 -- ksysguard/gui/SensorDisplayLib/DummyDisplay.cpp | 58 ++ ksysguard/gui/SensorDisplayLib/FancyPlotter.cc | 457 ---------- ksysguard/gui/SensorDisplayLib/FancyPlotter.cpp | 457 ++++++++++ .../gui/SensorDisplayLib/FancyPlotterSettings.cc | 637 -------------- .../gui/SensorDisplayLib/FancyPlotterSettings.cpp | 637 ++++++++++++++ ksysguard/gui/SensorDisplayLib/ListView.cc | 371 -------- ksysguard/gui/SensorDisplayLib/ListView.cpp | 371 ++++++++ ksysguard/gui/SensorDisplayLib/ListViewSettings.cc | 73 -- .../gui/SensorDisplayLib/ListViewSettings.cpp | 73 ++ ksysguard/gui/SensorDisplayLib/LogFile.cc | 285 ------ ksysguard/gui/SensorDisplayLib/LogFile.cpp | 285 ++++++ ksysguard/gui/SensorDisplayLib/Makefile.am | 38 +- ksysguard/gui/SensorDisplayLib/MultiMeter.cc | 258 ------ ksysguard/gui/SensorDisplayLib/MultiMeter.cpp | 258 ++++++ .../gui/SensorDisplayLib/MultiMeterSettings.cc | 123 --- .../gui/SensorDisplayLib/MultiMeterSettings.cpp | 123 +++ .../gui/SensorDisplayLib/ProcessController.cc | 472 ---------- .../gui/SensorDisplayLib/ProcessController.cpp | 472 ++++++++++ ksysguard/gui/SensorDisplayLib/ProcessList.cc | 977 --------------------- ksysguard/gui/SensorDisplayLib/ProcessList.cpp | 977 +++++++++++++++++++++ ksysguard/gui/SensorDisplayLib/ReniceDlg.cc | 70 -- ksysguard/gui/SensorDisplayLib/ReniceDlg.cpp | 70 ++ ksysguard/gui/SensorDisplayLib/SensorDisplay.cc | 611 ------------- ksysguard/gui/SensorDisplayLib/SensorDisplay.cpp | 611 +++++++++++++ ksysguard/gui/SensorDisplayLib/SensorLogger.cc | 437 --------- ksysguard/gui/SensorDisplayLib/SensorLogger.cpp | 437 +++++++++ ksysguard/gui/SensorDisplayLib/SensorLoggerDlg.cc | 102 --- ksysguard/gui/SensorDisplayLib/SensorLoggerDlg.cpp | 102 +++ .../gui/SensorDisplayLib/SensorLoggerSettings.cc | 73 -- .../gui/SensorDisplayLib/SensorLoggerSettings.cpp | 73 ++ ksysguard/gui/SensorDisplayLib/SignalPlotter.cc | 648 -------------- ksysguard/gui/SensorDisplayLib/SignalPlotter.cpp | 648 ++++++++++++++ 40 files changed, 6605 insertions(+), 6605 deletions(-) delete mode 100644 ksysguard/gui/SensorDisplayLib/BarGraph.cc create mode 100644 ksysguard/gui/SensorDisplayLib/BarGraph.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/DancingBars.cc create mode 100644 ksysguard/gui/SensorDisplayLib/DancingBars.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/DancingBarsSettings.cc create mode 100644 ksysguard/gui/SensorDisplayLib/DancingBarsSettings.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/DummyDisplay.cc create mode 100644 ksysguard/gui/SensorDisplayLib/DummyDisplay.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/FancyPlotter.cc create mode 100644 ksysguard/gui/SensorDisplayLib/FancyPlotter.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/FancyPlotterSettings.cc create mode 100644 ksysguard/gui/SensorDisplayLib/FancyPlotterSettings.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/ListView.cc create mode 100644 ksysguard/gui/SensorDisplayLib/ListView.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/ListViewSettings.cc create mode 100644 ksysguard/gui/SensorDisplayLib/ListViewSettings.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/LogFile.cc create mode 100644 ksysguard/gui/SensorDisplayLib/LogFile.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/MultiMeter.cc create mode 100644 ksysguard/gui/SensorDisplayLib/MultiMeter.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/MultiMeterSettings.cc create mode 100644 ksysguard/gui/SensorDisplayLib/MultiMeterSettings.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/ProcessController.cc create mode 100644 ksysguard/gui/SensorDisplayLib/ProcessController.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/ProcessList.cc create mode 100644 ksysguard/gui/SensorDisplayLib/ProcessList.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/ReniceDlg.cc create mode 100644 ksysguard/gui/SensorDisplayLib/ReniceDlg.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/SensorDisplay.cc create mode 100644 ksysguard/gui/SensorDisplayLib/SensorDisplay.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/SensorLogger.cc create mode 100644 ksysguard/gui/SensorDisplayLib/SensorLogger.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/SensorLoggerDlg.cc create mode 100644 ksysguard/gui/SensorDisplayLib/SensorLoggerDlg.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/SensorLoggerSettings.cc create mode 100644 ksysguard/gui/SensorDisplayLib/SensorLoggerSettings.cpp delete mode 100644 ksysguard/gui/SensorDisplayLib/SignalPlotter.cc create mode 100644 ksysguard/gui/SensorDisplayLib/SignalPlotter.cpp (limited to 'ksysguard/gui/SensorDisplayLib') diff --git a/ksysguard/gui/SensorDisplayLib/BarGraph.cc b/ksysguard/gui/SensorDisplayLib/BarGraph.cc deleted file mode 100644 index 8d2b5e302..000000000 --- a/ksysguard/gui/SensorDisplayLib/BarGraph.cc +++ /dev/null @@ -1,177 +0,0 @@ -/* - KSysGuard, the KDE System Guard - - Copyright (c) 1999, 2000 Chris Schlaeger - - This program is free software; you can redistribute it and/or - modify it under the terms of version 2 of the GNU General Public - License as published by the Free Software Foundation - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - KSysGuard is currently maintained by Chris Schlaeger . - Please do not commit any changes without consulting me first. Thanks! - -*/ - -#include -#include - -#include - -#include -#include - -#include - -#include "BarGraph.h" - -BarGraph::BarGraph( TQWidget *parent, const char *name ) - : TQWidget( parent, name ) -{ - // paintEvent covers whole widget so we use no background to avoid flicker - setBackgroundMode( NoBackground ); - - bars = 0; - minValue = 0.0; - maxValue = 100.0; - lowerLimit = upperLimit = 0.0; - lowerLimitActive = upperLimitActive = false; - - normalColor = KSGRD::Style->firstForegroundColor(); - alarmColor = KSGRD::Style->alarmColor(); - backgroundColor = KSGRD::Style->backgroundColor(); - fontSize = KSGRD::Style->fontSize(); - - // Anything smaller than this does not make sense. - setMinimumSize( 16, 16 ); - setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, - TQSizePolicy::Expanding, false ) ); -} - -BarGraph::~BarGraph() -{ -} - -bool BarGraph::addBar( const TQString &footer ) -{ - samples.resize( bars + 1 ); - samples[ bars++ ] = 0.0; - footers.append( footer ); - - return true; -} - -bool BarGraph::removeBar( uint idx ) -{ - if ( idx >= bars ) { - kdDebug(1215) << "BarGraph::removeBar: idx " << idx << " out of range " - << bars << endl; - return false; - } - - samples.resize( --bars ); - footers.remove( footers.at( idx ) ); - update(); - - return true; -} - -void BarGraph::updateSamples( const TQMemArray &newSamples ) -{ - samples = newSamples; - update(); -} - -void BarGraph::changeRange( double min, double max ) -{ - minValue = min; - maxValue = max; -} - -void BarGraph::paintEvent( TQPaintEvent* ) -{ - int w = width(); - int h = height(); - - TQPixmap pm( w, h ); - TQPainter p; - p.begin( &pm, this ); - p.setFont( TQFont( p.font().family(), fontSize ) ); - TQFontMetrics fm( p.font() ); - - pm.fill( backgroundColor ); - - /* Draw white line along the bottom and the right side of the - * widget to create a 3D like look. */ - p.setPen( TQColor( colorGroup().light() ) ); - p.drawLine( 0, h - 1, w - 1, h - 1 ); - p.drawLine( w - 1, 0, w - 1, h - 1 ); - - p.setClipRect( 1, 1, w - 2, h - 2 ); - - if ( bars > 0 ) { - int barWidth = ( w - 2 ) / bars; - uint b; - /* Labels are only printed underneath the bars if the labels - * for all bars are smaller than the bar width. If a single - * label does not fit no label is shown. */ - bool showLabels = true; - for ( b = 0; b < bars; b++ ) - if ( fm.width( footers[ b ] ) > barWidth ) - showLabels = false; - - int barHeight; - if ( showLabels ) - barHeight = h - 2 - ( 2 * fm.lineSpacing() ) - 2; - else - barHeight = h - 2; - - for ( uint b = 0; b < bars; b++ ) { - int topVal = (int) ( (float)barHeight / maxValue * - ( samples[ b ] - minValue ) ); - /* TODO: This widget does not handle negative values properly. */ - if ( topVal < 0 ) - topVal = 0; - - for ( int i = 0; i < barHeight && i < topVal; i += 2 ) { - if ( ( upperLimitActive && samples[ b ] > upperLimit ) || - ( lowerLimitActive && samples[ b ] < lowerLimit ) ) - p.setPen( alarmColor.light( static_cast( 30 + ( 70.0 / - ( barHeight + 1 ) * i ) ) ) ); - else - p.setPen( normalColor.light( static_cast( 30 + ( 70.0 / - ( barHeight + 1 ) * i ) ) ) ); - p.drawLine( b * barWidth + 3, barHeight - i, ( b + 1 ) * barWidth - 3, - barHeight - i ); - } - - if ( ( upperLimitActive && samples[ b ] > upperLimit ) || - ( lowerLimitActive && samples[ b ] < lowerLimit ) ) - p.setPen( alarmColor ); - else - p.setPen( normalColor ); - - if ( showLabels ) { - p.drawText( b * barWidth + 3, h - ( 2 * fm.lineSpacing() ) - 2, - barWidth - 2 * 3, fm.lineSpacing(), Qt::AlignCenter, - footers[ b ] ); - p.drawText( b * barWidth + 3, h - fm.lineSpacing() - 2, - barWidth - 2 * 3, fm.lineSpacing(), Qt::AlignCenter, - TQString( "%1" ).arg( samples[ b ] ) ); - } - } - } - - p.end(); - bitBlt( this, 0, 0, &pm ); -} - -#include "BarGraph.moc" diff --git a/ksysguard/gui/SensorDisplayLib/BarGraph.cpp b/ksysguard/gui/SensorDisplayLib/BarGraph.cpp new file mode 100644 index 000000000..8d2b5e302 --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/BarGraph.cpp @@ -0,0 +1,177 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 1999, 2000 Chris Schlaeger + + This program is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + KSysGuard is currently maintained by Chris Schlaeger . + Please do not commit any changes without consulting me first. Thanks! + +*/ + +#include +#include + +#include + +#include +#include + +#include + +#include "BarGraph.h" + +BarGraph::BarGraph( TQWidget *parent, const char *name ) + : TQWidget( parent, name ) +{ + // paintEvent covers whole widget so we use no background to avoid flicker + setBackgroundMode( NoBackground ); + + bars = 0; + minValue = 0.0; + maxValue = 100.0; + lowerLimit = upperLimit = 0.0; + lowerLimitActive = upperLimitActive = false; + + normalColor = KSGRD::Style->firstForegroundColor(); + alarmColor = KSGRD::Style->alarmColor(); + backgroundColor = KSGRD::Style->backgroundColor(); + fontSize = KSGRD::Style->fontSize(); + + // Anything smaller than this does not make sense. + setMinimumSize( 16, 16 ); + setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, + TQSizePolicy::Expanding, false ) ); +} + +BarGraph::~BarGraph() +{ +} + +bool BarGraph::addBar( const TQString &footer ) +{ + samples.resize( bars + 1 ); + samples[ bars++ ] = 0.0; + footers.append( footer ); + + return true; +} + +bool BarGraph::removeBar( uint idx ) +{ + if ( idx >= bars ) { + kdDebug(1215) << "BarGraph::removeBar: idx " << idx << " out of range " + << bars << endl; + return false; + } + + samples.resize( --bars ); + footers.remove( footers.at( idx ) ); + update(); + + return true; +} + +void BarGraph::updateSamples( const TQMemArray &newSamples ) +{ + samples = newSamples; + update(); +} + +void BarGraph::changeRange( double min, double max ) +{ + minValue = min; + maxValue = max; +} + +void BarGraph::paintEvent( TQPaintEvent* ) +{ + int w = width(); + int h = height(); + + TQPixmap pm( w, h ); + TQPainter p; + p.begin( &pm, this ); + p.setFont( TQFont( p.font().family(), fontSize ) ); + TQFontMetrics fm( p.font() ); + + pm.fill( backgroundColor ); + + /* Draw white line along the bottom and the right side of the + * widget to create a 3D like look. */ + p.setPen( TQColor( colorGroup().light() ) ); + p.drawLine( 0, h - 1, w - 1, h - 1 ); + p.drawLine( w - 1, 0, w - 1, h - 1 ); + + p.setClipRect( 1, 1, w - 2, h - 2 ); + + if ( bars > 0 ) { + int barWidth = ( w - 2 ) / bars; + uint b; + /* Labels are only printed underneath the bars if the labels + * for all bars are smaller than the bar width. If a single + * label does not fit no label is shown. */ + bool showLabels = true; + for ( b = 0; b < bars; b++ ) + if ( fm.width( footers[ b ] ) > barWidth ) + showLabels = false; + + int barHeight; + if ( showLabels ) + barHeight = h - 2 - ( 2 * fm.lineSpacing() ) - 2; + else + barHeight = h - 2; + + for ( uint b = 0; b < bars; b++ ) { + int topVal = (int) ( (float)barHeight / maxValue * + ( samples[ b ] - minValue ) ); + /* TODO: This widget does not handle negative values properly. */ + if ( topVal < 0 ) + topVal = 0; + + for ( int i = 0; i < barHeight && i < topVal; i += 2 ) { + if ( ( upperLimitActive && samples[ b ] > upperLimit ) || + ( lowerLimitActive && samples[ b ] < lowerLimit ) ) + p.setPen( alarmColor.light( static_cast( 30 + ( 70.0 / + ( barHeight + 1 ) * i ) ) ) ); + else + p.setPen( normalColor.light( static_cast( 30 + ( 70.0 / + ( barHeight + 1 ) * i ) ) ) ); + p.drawLine( b * barWidth + 3, barHeight - i, ( b + 1 ) * barWidth - 3, + barHeight - i ); + } + + if ( ( upperLimitActive && samples[ b ] > upperLimit ) || + ( lowerLimitActive && samples[ b ] < lowerLimit ) ) + p.setPen( alarmColor ); + else + p.setPen( normalColor ); + + if ( showLabels ) { + p.drawText( b * barWidth + 3, h - ( 2 * fm.lineSpacing() ) - 2, + barWidth - 2 * 3, fm.lineSpacing(), Qt::AlignCenter, + footers[ b ] ); + p.drawText( b * barWidth + 3, h - fm.lineSpacing() - 2, + barWidth - 2 * 3, fm.lineSpacing(), Qt::AlignCenter, + TQString( "%1" ).arg( samples[ b ] ) ); + } + } + } + + p.end(); + bitBlt( this, 0, 0, &pm ); +} + +#include "BarGraph.moc" diff --git a/ksysguard/gui/SensorDisplayLib/CMakeLists.txt b/ksysguard/gui/SensorDisplayLib/CMakeLists.txt index 0fe416a0b..6fe370076 100644 --- a/ksysguard/gui/SensorDisplayLib/CMakeLists.txt +++ b/ksysguard/gui/SensorDisplayLib/CMakeLists.txt @@ -28,12 +28,12 @@ link_directories( tde_add_library( sensordisplays STATIC_PIC AUTOMOC SOURCES - SensorDisplay.cc BarGraph.cc DancingBars.cc DancingBarsSettings.cc - DummyDisplay.cc FancyPlotter.cc FancyPlotterSettings.cc - ListView.cc LogFile.cc MultiMeter.cc MultiMeterSettings.cc - ProcessController.cc ProcessList.cc ReniceDlg.cc - SensorLogger.cc SensorLoggerDlg.cc SensorLoggerSettings.cc - ListViewSettings.cc SignalPlotter.cc ListViewSettingsWidget.ui + SensorDisplay.cpp BarGraph.cpp DancingBars.cpp DancingBarsSettings.cpp + DummyDisplay.cpp FancyPlotter.cpp FancyPlotterSettings.cpp + ListView.cpp LogFile.cpp MultiMeter.cpp MultiMeterSettings.cpp + ProcessController.cpp ProcessList.cpp ReniceDlg.cpp + SensorLogger.cpp SensorLoggerDlg.cpp SensorLoggerSettings.cpp + ListViewSettings.cpp SignalPlotter.cpp ListViewSettingsWidget.ui LogFileSettings.ui MultiMeterSettingsWidget.ui SensorLoggerDlgWidget.ui SensorLoggerSettingsWidget.ui LINK ksgrd-shared tdeio-shared diff --git a/ksysguard/gui/SensorDisplayLib/DancingBars.cc b/ksysguard/gui/SensorDisplayLib/DancingBars.cc deleted file mode 100644 index 5b09addc0..000000000 --- a/ksysguard/gui/SensorDisplayLib/DancingBars.cc +++ /dev/null @@ -1,353 +0,0 @@ -/* - KSysGuard, the KDE System Guard - - Copyright (c) 1999, 2000, 2001 Chris Schlaeger - - This program is free software; you can redistribute it and/or - modify it under the terms of version 2 of the GNU General Public - License as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - KSysGuard is currently maintained by Chris Schlaeger . - Please do not commit any changes without consulting me first. Thanks! - -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "BarGraph.h" -#include "DancingBarsSettings.h" - -#include "DancingBars.h" - -DancingBars::DancingBars( TQWidget *parent, const char *name, const TQString &title, - int, int, bool noFrame_, bool isApplet ) - : KSGRD::SensorDisplay( parent, name, title, noFrame_, isApplet ) -{ - mBars = 0; - mFlags = TQBitArray(100); - mFlags.fill( false ); - - if ( noFrame() ) - mPlotter = new BarGraph( this ); - else - mPlotter = new BarGraph( frame() ); - - setMinimumSize( sizeHint() ); - - /* All RMB clicks to the mPlotter widget will be handled by - * SensorDisplay::eventFilter. */ - mPlotter->installEventFilter( this ); - - setPlotterWidget( mPlotter ); - - setModified( false ); -} - -DancingBars::~DancingBars() -{ -} - -void DancingBars::configureSettings() -{ - mSettingsDialog = new DancingBarsSettings( this ); - - mSettingsDialog->setTitle( title() ); - mSettingsDialog->setMinValue( mPlotter->getMin() ); - mSettingsDialog->setMaxValue( mPlotter->getMax() ); - - double l, u; - bool la, ua; - mPlotter->getLimits( l, la, u, ua ); - - mSettingsDialog->setUseUpperLimit( ua ); - mSettingsDialog->setUpperLimit( u ); - - mSettingsDialog->setUseLowerLimit( la ); - mSettingsDialog->setLowerLimit( l ); - - mSettingsDialog->setForegroundColor( mPlotter->normalColor ); - mSettingsDialog->setAlarmColor( mPlotter->alarmColor ); - mSettingsDialog->setBackgroundColor( mPlotter->backgroundColor ); - mSettingsDialog->setFontSize( mPlotter->fontSize ); - - TQValueList< TQStringList > list; - for ( uint i = mBars - 1; i < mBars; i-- ) { - TQStringList entry; - entry << sensors().at( i )->hostName(); - entry << KSGRD::SensorMgr->translateSensor( sensors().at( i )->name() ); - entry << mPlotter->footers[ i ]; - entry << KSGRD::SensorMgr->translateUnit( sensors().at( i )->unit() ); - entry << ( sensors().at( i )->isOk() ? i18n( "OK" ) : i18n( "Error" ) ); - - list.append( entry ); - } - mSettingsDialog->setSensors( list ); - - connect( mSettingsDialog, TQT_SIGNAL( applyClicked() ), TQT_SLOT( applySettings() ) ); - - if ( mSettingsDialog->exec() ) - applySettings(); - - delete mSettingsDialog; - mSettingsDialog = 0; -} - -void DancingBars::applySettings() -{ - setTitle( mSettingsDialog->title() ); - mPlotter->changeRange( mSettingsDialog->minValue(), mSettingsDialog->maxValue() ); - mPlotter->setLimits( mSettingsDialog->useLowerLimit() ? - mSettingsDialog->lowerLimit() : 0, - mSettingsDialog->useLowerLimit(), - mSettingsDialog->useUpperLimit() ? - mSettingsDialog->upperLimit() : 0, - mSettingsDialog->useUpperLimit() ); - - mPlotter->normalColor = mSettingsDialog->foregroundColor(); - mPlotter->alarmColor = mSettingsDialog->alarmColor(); - mPlotter->backgroundColor = mSettingsDialog->backgroundColor(); - mPlotter->fontSize = mSettingsDialog->fontSize(); - - TQValueList< TQStringList > list = mSettingsDialog->sensors(); - TQValueList< TQStringList >::Iterator it; - - for ( uint i = 0; i < sensors().count(); i++ ) { - bool found = false; - for ( it = list.begin(); it != list.end(); ++it ) { - if ( (*it)[ 0 ] == sensors().at( i )->hostName() && - (*it)[ 1 ] == KSGRD::SensorMgr->translateSensor( sensors().at( i )->name() ) ) { - mPlotter->footers[ i ] = (*it)[ 2 ]; - found = true; - break; - } - } - - if ( !found ) - removeSensor( i ); - } - - repaint(); - setModified( true ); -} - -void DancingBars::applyStyle() -{ - mPlotter->normalColor = KSGRD::Style->firstForegroundColor(); - mPlotter->alarmColor = KSGRD::Style->alarmColor(); - mPlotter->backgroundColor = KSGRD::Style->backgroundColor(); - mPlotter->fontSize = KSGRD::Style->fontSize(); - - repaint(); - setModified( true ); -} - -bool DancingBars::addSensor( const TQString &hostName, const TQString &name, - const TQString &type, const TQString &title ) -{ - if ( type != "integer" && type != "float" ) - return false; - - if ( mBars >= 32 ) - return false; - - if ( !mPlotter->addBar( title ) ) - return false; - - registerSensor( new KSGRD::SensorProperties( hostName, name, type, title ) ); - - /* To differentiate between answers from value requests and info - * requests we add 100 to the beam index for info requests. */ - sendRequest( hostName, name + "?", mBars + 100 ); - ++mBars; - mSampleBuffer.resize( mBars ); - - TQString tooltip; - for ( uint i = 0; i < mBars; ++i ) { - tooltip += TQString( "%1%2:%3" ).arg( i != 0 ? "\n" : "" ) - .arg( sensors().at( i )->hostName() ) - .arg( sensors().at( i )->name() ); - } - TQToolTip::remove( mPlotter ); - TQToolTip::add( mPlotter, tooltip ); - - return true; -} - -bool DancingBars::removeSensor( uint pos ) -{ - if ( pos >= mBars ) { - kdDebug(1215) << "DancingBars::removeSensor: idx out of range (" - << pos << ")" << endl; - return false; - } - - mPlotter->removeBar( pos ); - mBars--; - KSGRD::SensorDisplay::removeSensor( pos ); - - TQString tooltip; - for ( uint i = 0; i < mBars; ++i ) { - tooltip += TQString( "%1%2:%3" ).arg( i != 0 ? "\n" : "" ) - .arg( sensors().at( i )->hostName() ) - .arg( sensors().at( i )->name() ); - } - TQToolTip::remove( mPlotter ); - TQToolTip::add( mPlotter, tooltip ); - - return true; -} - -void DancingBars::updateSamples( const TQMemArray &samples ) -{ - mPlotter->updateSamples( samples ); -} - -void DancingBars::resizeEvent( TQResizeEvent* ) -{ - if ( noFrame() ) - mPlotter->setGeometry( 0, 0, width(), height() ); - else - frame()->setGeometry( 0, 0, width(), height() ); -} - -TQSize DancingBars::sizeHint() -{ - if ( noFrame() ) - return ( mPlotter->sizeHint() ); - else - return ( frame()->sizeHint() ); -} - -void DancingBars::answerReceived( int id, const TQString &answer ) -{ - /* We received something, so the sensor is probably ok. */ - sensorError( id, false ); - - if ( id < 100 ) { - mSampleBuffer[ id ] = answer.toDouble(); - if ( mFlags.testBit( id ) == true ) { - kdDebug(1215) << "ERROR: DancingBars lost sample (" << mFlags - << ", " << mBars << ")" << endl; - sensorError( id, true ); - } - mFlags.setBit( id, true ); - - bool allBitsAvailable = true; - for ( uint i = 0; i < mBars; ++i ) - allBitsAvailable &= mFlags.testBit( i ); - - if ( allBitsAvailable ) { - mPlotter->updateSamples( mSampleBuffer ); - mFlags.fill( false ); - } - } else if ( id >= 100 ) { - KSGRD::SensorIntegerInfo info( answer ); - if ( id == 100 ) - if ( mPlotter->getMin() == 0.0 && mPlotter->getMax() == 0.0 ) { - /* We only use this information from the sensor when the - * display is still using the default values. If the - * sensor has been restored we don't touch the already set - * values. */ - mPlotter->changeRange( info.min(), info.max() ); - } - - sensors().at( id - 100 )->setUnit( info.unit() ); - } -} - -bool DancingBars::restoreSettings( TQDomElement &element ) -{ - SensorDisplay::restoreSettings( element ); - - mPlotter->changeRange( element.attribute( "min", "0" ).toDouble(), - element.attribute( "max", "0" ).toDouble() ); - - mPlotter->setLimits( element.attribute( "lowlimit", "0" ).toDouble(), - element.attribute( "lowlimitactive", "0" ).toInt(), - element.attribute( "uplimit", "0" ).toDouble(), - element.attribute( "uplimitactive", "0" ).toInt() ); - - mPlotter->normalColor = restoreColor( element, "normalColor", - KSGRD::Style->firstForegroundColor() ); - mPlotter->alarmColor = restoreColor( element, "alarmColor", - KSGRD::Style->alarmColor() ); - mPlotter->backgroundColor = restoreColor( element, "backgroundColor", - KSGRD::Style->backgroundColor() ); - mPlotter->fontSize = element.attribute( "fontSize", TQString( "%1" ).arg( - KSGRD::Style->fontSize() ) ).toInt(); - - TQDomNodeList dnList = element.elementsByTagName( "beam" ); - for ( uint i = 0; i < dnList.count(); ++i ) { - TQDomElement el = dnList.item( i ).toElement(); - addSensor( el.attribute( "hostName" ), el.attribute( "sensorName" ), - ( el.attribute( "sensorType" ).isEmpty() ? "integer" : - el.attribute( "sensorType" ) ), el.attribute( "sensorDescr" ) ); - } - - setModified( false ); - - return true; -} - -bool DancingBars::saveSettings( TQDomDocument &doc, TQDomElement &element, - bool save ) -{ - element.setAttribute( "min", mPlotter->getMin() ); - element.setAttribute( "max", mPlotter->getMax() ); - double l, u; - bool la, ua; - mPlotter->getLimits( l, la, u, ua ); - element.setAttribute( "lowlimit", l ); - element.setAttribute( "lowlimitactive", la ); - element.setAttribute( "uplimit", u ); - element.setAttribute( "uplimitactive", ua ); - - saveColor( element, "normalColor", mPlotter->normalColor ); - saveColor( element, "alarmColor", mPlotter->alarmColor ); - saveColor( element, "backgroundColor", mPlotter->backgroundColor ); - element.setAttribute( "fontSize", mPlotter->fontSize ); - - for ( uint i = 0; i < mBars; ++i ) { - TQDomElement beam = doc.createElement( "beam" ); - element.appendChild( beam ); - beam.setAttribute( "hostName", sensors().at( i )->hostName() ); - beam.setAttribute( "sensorName", sensors().at( i )->name() ); - beam.setAttribute( "sensorType", sensors().at( i )->type() ); - beam.setAttribute( "sensorDescr", mPlotter->footers[ i ] ); - } - - SensorDisplay::saveSettings( doc, element ); - - if ( save ) - setModified( false ); - - return true; -} - -bool DancingBars::hasSettingsDialog() const -{ - return true; -} - -#include "DancingBars.moc" diff --git a/ksysguard/gui/SensorDisplayLib/DancingBars.cpp b/ksysguard/gui/SensorDisplayLib/DancingBars.cpp new file mode 100644 index 000000000..5b09addc0 --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/DancingBars.cpp @@ -0,0 +1,353 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 1999, 2000, 2001 Chris Schlaeger + + This program is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + KSysGuard is currently maintained by Chris Schlaeger . + Please do not commit any changes without consulting me first. Thanks! + +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "BarGraph.h" +#include "DancingBarsSettings.h" + +#include "DancingBars.h" + +DancingBars::DancingBars( TQWidget *parent, const char *name, const TQString &title, + int, int, bool noFrame_, bool isApplet ) + : KSGRD::SensorDisplay( parent, name, title, noFrame_, isApplet ) +{ + mBars = 0; + mFlags = TQBitArray(100); + mFlags.fill( false ); + + if ( noFrame() ) + mPlotter = new BarGraph( this ); + else + mPlotter = new BarGraph( frame() ); + + setMinimumSize( sizeHint() ); + + /* All RMB clicks to the mPlotter widget will be handled by + * SensorDisplay::eventFilter. */ + mPlotter->installEventFilter( this ); + + setPlotterWidget( mPlotter ); + + setModified( false ); +} + +DancingBars::~DancingBars() +{ +} + +void DancingBars::configureSettings() +{ + mSettingsDialog = new DancingBarsSettings( this ); + + mSettingsDialog->setTitle( title() ); + mSettingsDialog->setMinValue( mPlotter->getMin() ); + mSettingsDialog->setMaxValue( mPlotter->getMax() ); + + double l, u; + bool la, ua; + mPlotter->getLimits( l, la, u, ua ); + + mSettingsDialog->setUseUpperLimit( ua ); + mSettingsDialog->setUpperLimit( u ); + + mSettingsDialog->setUseLowerLimit( la ); + mSettingsDialog->setLowerLimit( l ); + + mSettingsDialog->setForegroundColor( mPlotter->normalColor ); + mSettingsDialog->setAlarmColor( mPlotter->alarmColor ); + mSettingsDialog->setBackgroundColor( mPlotter->backgroundColor ); + mSettingsDialog->setFontSize( mPlotter->fontSize ); + + TQValueList< TQStringList > list; + for ( uint i = mBars - 1; i < mBars; i-- ) { + TQStringList entry; + entry << sensors().at( i )->hostName(); + entry << KSGRD::SensorMgr->translateSensor( sensors().at( i )->name() ); + entry << mPlotter->footers[ i ]; + entry << KSGRD::SensorMgr->translateUnit( sensors().at( i )->unit() ); + entry << ( sensors().at( i )->isOk() ? i18n( "OK" ) : i18n( "Error" ) ); + + list.append( entry ); + } + mSettingsDialog->setSensors( list ); + + connect( mSettingsDialog, TQT_SIGNAL( applyClicked() ), TQT_SLOT( applySettings() ) ); + + if ( mSettingsDialog->exec() ) + applySettings(); + + delete mSettingsDialog; + mSettingsDialog = 0; +} + +void DancingBars::applySettings() +{ + setTitle( mSettingsDialog->title() ); + mPlotter->changeRange( mSettingsDialog->minValue(), mSettingsDialog->maxValue() ); + mPlotter->setLimits( mSettingsDialog->useLowerLimit() ? + mSettingsDialog->lowerLimit() : 0, + mSettingsDialog->useLowerLimit(), + mSettingsDialog->useUpperLimit() ? + mSettingsDialog->upperLimit() : 0, + mSettingsDialog->useUpperLimit() ); + + mPlotter->normalColor = mSettingsDialog->foregroundColor(); + mPlotter->alarmColor = mSettingsDialog->alarmColor(); + mPlotter->backgroundColor = mSettingsDialog->backgroundColor(); + mPlotter->fontSize = mSettingsDialog->fontSize(); + + TQValueList< TQStringList > list = mSettingsDialog->sensors(); + TQValueList< TQStringList >::Iterator it; + + for ( uint i = 0; i < sensors().count(); i++ ) { + bool found = false; + for ( it = list.begin(); it != list.end(); ++it ) { + if ( (*it)[ 0 ] == sensors().at( i )->hostName() && + (*it)[ 1 ] == KSGRD::SensorMgr->translateSensor( sensors().at( i )->name() ) ) { + mPlotter->footers[ i ] = (*it)[ 2 ]; + found = true; + break; + } + } + + if ( !found ) + removeSensor( i ); + } + + repaint(); + setModified( true ); +} + +void DancingBars::applyStyle() +{ + mPlotter->normalColor = KSGRD::Style->firstForegroundColor(); + mPlotter->alarmColor = KSGRD::Style->alarmColor(); + mPlotter->backgroundColor = KSGRD::Style->backgroundColor(); + mPlotter->fontSize = KSGRD::Style->fontSize(); + + repaint(); + setModified( true ); +} + +bool DancingBars::addSensor( const TQString &hostName, const TQString &name, + const TQString &type, const TQString &title ) +{ + if ( type != "integer" && type != "float" ) + return false; + + if ( mBars >= 32 ) + return false; + + if ( !mPlotter->addBar( title ) ) + return false; + + registerSensor( new KSGRD::SensorProperties( hostName, name, type, title ) ); + + /* To differentiate between answers from value requests and info + * requests we add 100 to the beam index for info requests. */ + sendRequest( hostName, name + "?", mBars + 100 ); + ++mBars; + mSampleBuffer.resize( mBars ); + + TQString tooltip; + for ( uint i = 0; i < mBars; ++i ) { + tooltip += TQString( "%1%2:%3" ).arg( i != 0 ? "\n" : "" ) + .arg( sensors().at( i )->hostName() ) + .arg( sensors().at( i )->name() ); + } + TQToolTip::remove( mPlotter ); + TQToolTip::add( mPlotter, tooltip ); + + return true; +} + +bool DancingBars::removeSensor( uint pos ) +{ + if ( pos >= mBars ) { + kdDebug(1215) << "DancingBars::removeSensor: idx out of range (" + << pos << ")" << endl; + return false; + } + + mPlotter->removeBar( pos ); + mBars--; + KSGRD::SensorDisplay::removeSensor( pos ); + + TQString tooltip; + for ( uint i = 0; i < mBars; ++i ) { + tooltip += TQString( "%1%2:%3" ).arg( i != 0 ? "\n" : "" ) + .arg( sensors().at( i )->hostName() ) + .arg( sensors().at( i )->name() ); + } + TQToolTip::remove( mPlotter ); + TQToolTip::add( mPlotter, tooltip ); + + return true; +} + +void DancingBars::updateSamples( const TQMemArray &samples ) +{ + mPlotter->updateSamples( samples ); +} + +void DancingBars::resizeEvent( TQResizeEvent* ) +{ + if ( noFrame() ) + mPlotter->setGeometry( 0, 0, width(), height() ); + else + frame()->setGeometry( 0, 0, width(), height() ); +} + +TQSize DancingBars::sizeHint() +{ + if ( noFrame() ) + return ( mPlotter->sizeHint() ); + else + return ( frame()->sizeHint() ); +} + +void DancingBars::answerReceived( int id, const TQString &answer ) +{ + /* We received something, so the sensor is probably ok. */ + sensorError( id, false ); + + if ( id < 100 ) { + mSampleBuffer[ id ] = answer.toDouble(); + if ( mFlags.testBit( id ) == true ) { + kdDebug(1215) << "ERROR: DancingBars lost sample (" << mFlags + << ", " << mBars << ")" << endl; + sensorError( id, true ); + } + mFlags.setBit( id, true ); + + bool allBitsAvailable = true; + for ( uint i = 0; i < mBars; ++i ) + allBitsAvailable &= mFlags.testBit( i ); + + if ( allBitsAvailable ) { + mPlotter->updateSamples( mSampleBuffer ); + mFlags.fill( false ); + } + } else if ( id >= 100 ) { + KSGRD::SensorIntegerInfo info( answer ); + if ( id == 100 ) + if ( mPlotter->getMin() == 0.0 && mPlotter->getMax() == 0.0 ) { + /* We only use this information from the sensor when the + * display is still using the default values. If the + * sensor has been restored we don't touch the already set + * values. */ + mPlotter->changeRange( info.min(), info.max() ); + } + + sensors().at( id - 100 )->setUnit( info.unit() ); + } +} + +bool DancingBars::restoreSettings( TQDomElement &element ) +{ + SensorDisplay::restoreSettings( element ); + + mPlotter->changeRange( element.attribute( "min", "0" ).toDouble(), + element.attribute( "max", "0" ).toDouble() ); + + mPlotter->setLimits( element.attribute( "lowlimit", "0" ).toDouble(), + element.attribute( "lowlimitactive", "0" ).toInt(), + element.attribute( "uplimit", "0" ).toDouble(), + element.attribute( "uplimitactive", "0" ).toInt() ); + + mPlotter->normalColor = restoreColor( element, "normalColor", + KSGRD::Style->firstForegroundColor() ); + mPlotter->alarmColor = restoreColor( element, "alarmColor", + KSGRD::Style->alarmColor() ); + mPlotter->backgroundColor = restoreColor( element, "backgroundColor", + KSGRD::Style->backgroundColor() ); + mPlotter->fontSize = element.attribute( "fontSize", TQString( "%1" ).arg( + KSGRD::Style->fontSize() ) ).toInt(); + + TQDomNodeList dnList = element.elementsByTagName( "beam" ); + for ( uint i = 0; i < dnList.count(); ++i ) { + TQDomElement el = dnList.item( i ).toElement(); + addSensor( el.attribute( "hostName" ), el.attribute( "sensorName" ), + ( el.attribute( "sensorType" ).isEmpty() ? "integer" : + el.attribute( "sensorType" ) ), el.attribute( "sensorDescr" ) ); + } + + setModified( false ); + + return true; +} + +bool DancingBars::saveSettings( TQDomDocument &doc, TQDomElement &element, + bool save ) +{ + element.setAttribute( "min", mPlotter->getMin() ); + element.setAttribute( "max", mPlotter->getMax() ); + double l, u; + bool la, ua; + mPlotter->getLimits( l, la, u, ua ); + element.setAttribute( "lowlimit", l ); + element.setAttribute( "lowlimitactive", la ); + element.setAttribute( "uplimit", u ); + element.setAttribute( "uplimitactive", ua ); + + saveColor( element, "normalColor", mPlotter->normalColor ); + saveColor( element, "alarmColor", mPlotter->alarmColor ); + saveColor( element, "backgroundColor", mPlotter->backgroundColor ); + element.setAttribute( "fontSize", mPlotter->fontSize ); + + for ( uint i = 0; i < mBars; ++i ) { + TQDomElement beam = doc.createElement( "beam" ); + element.appendChild( beam ); + beam.setAttribute( "hostName", sensors().at( i )->hostName() ); + beam.setAttribute( "sensorName", sensors().at( i )->name() ); + beam.setAttribute( "sensorType", sensors().at( i )->type() ); + beam.setAttribute( "sensorDescr", mPlotter->footers[ i ] ); + } + + SensorDisplay::saveSettings( doc, element ); + + if ( save ) + setModified( false ); + + return true; +} + +bool DancingBars::hasSettingsDialog() const +{ + return true; +} + +#include "DancingBars.moc" diff --git a/ksysguard/gui/SensorDisplayLib/DancingBarsSettings.cc b/ksysguard/gui/SensorDisplayLib/DancingBarsSettings.cc deleted file mode 100644 index ee03f9e94..000000000 --- a/ksysguard/gui/SensorDisplayLib/DancingBarsSettings.cc +++ /dev/null @@ -1,398 +0,0 @@ -/* - KSysGuard, the KDE System Guard - - Copyright (c) 2003 Tobias Koenig - - This program is free software; you can redistribute it and/or - modify it under the terms of version 2 of the GNU General Public - License as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - KSysGuard is currently maintained by Chris Schlaeger . - Please do not commit any changes without consulting me first. Thanks! - -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "DancingBarsSettings.h" - -DancingBarsSettings::DancingBarsSettings( TQWidget* parent, const char* name ) - : KDialogBase( Tabbed, i18n( "Edit BarGraph Preferences" ), - Ok | Apply | Cancel, Ok, parent, name, true, true ) -{ - // Range page - TQFrame *page = addPage( i18n( "Range" ) ); - TQGridLayout *pageLayout = new TQGridLayout( page, 3, 1, 0, spacingHint() ); - - TQGroupBox *groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Title" ), page ); - TQGridLayout *boxLayout = new TQGridLayout( groupBox->layout(), 1, 1 ); - - mTitle = new KLineEdit( groupBox ); - TQWhatsThis::add( mTitle, i18n( "Enter the title of the display here." ) ); - boxLayout->addWidget( mTitle, 0, 0 ); - - pageLayout->addWidget( groupBox, 0, 0 ); - - groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Display Range" ), page ); - boxLayout = new TQGridLayout( groupBox->layout(), 1, 5 ); - boxLayout->setColStretch( 2, 1 ); - - TQLabel *label = new TQLabel( i18n( "Minimum value:" ), groupBox ); - boxLayout->addWidget( label, 0, 0 ); - - mMinValue = new KDoubleSpinBox( 0, 100, 0.5, 0, 2, groupBox ); - TQWhatsThis::add( mMinValue, i18n( "Enter the minimum value for the display here. If both values are 0, automatic range detection is enabled." ) ); - boxLayout->addWidget( mMinValue, 0, 1 ); - label->setBuddy( mMinValue ); - - label = new TQLabel( i18n( "Maximum value:" ), groupBox ); - boxLayout->addWidget( label, 0, 3 ); - - mMaxValue = new KDoubleSpinBox( 0, 10000, 0.5, 100, 2, groupBox ); - TQWhatsThis::add( mMaxValue, i18n( "Enter the maximum value for the display here. If both values are 0, automatic range detection is enabled." ) ); - boxLayout->addWidget( mMaxValue, 0, 4 ); - label->setBuddy( mMaxValue ); - - pageLayout->addWidget( groupBox, 1, 0 ); - - pageLayout->setRowStretch( 2, 1 ); - - // Alarm page - page = addPage( i18n( "Alarms" ) ); - pageLayout = new TQGridLayout( page, 3, 1, 0, spacingHint() ); - - groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Alarm for Minimum Value" ), page ); - boxLayout = new TQGridLayout( groupBox->layout(), 1, 4 ); - boxLayout->setColStretch( 1, 1 ); - - mUseLowerLimit = new TQCheckBox( i18n( "Enable alarm" ), groupBox ); - TQWhatsThis::add( mUseLowerLimit, i18n( "Enable the minimum value alarm." ) ); - boxLayout->addWidget( mUseLowerLimit, 0, 0 ); - - label = new TQLabel( i18n( "Lower limit:" ), groupBox ); - boxLayout->addWidget( label, 0, 2 ); - - mLowerLimit = new KDoubleSpinBox( 0, 100, 0.5, 0, 2, groupBox ); - mLowerLimit->setEnabled( false ); - boxLayout->addWidget( mLowerLimit, 0, 3 ); - label->setBuddy( mLowerLimit ); - - pageLayout->addWidget( groupBox, 0, 0 ); - - groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Alarm for Maximum Value" ), page ); - boxLayout = new TQGridLayout( groupBox->layout(), 1, 4 ); - boxLayout->setColStretch( 1, 1 ); - - mUseUpperLimit = new TQCheckBox( i18n( "Enable alarm" ), groupBox ); - TQWhatsThis::add( mUseUpperLimit, i18n( "Enable the maximum value alarm." ) ); - boxLayout->addWidget( mUseUpperLimit, 0, 0 ); - - label = new TQLabel( i18n( "Upper limit:" ), groupBox ); - boxLayout->addWidget( label, 0, 2 ); - - mUpperLimit = new KDoubleSpinBox( 0, 100, 0.5, 0, 2, groupBox ); - mUpperLimit->setEnabled( false ); - boxLayout->addWidget( mUpperLimit, 0, 3 ); - label->setBuddy( mUpperLimit ); - - pageLayout->addWidget( groupBox, 1, 0 ); - - pageLayout->setRowStretch( 2, 1 ); - - // Look page - page = addPage( i18n( "Look" ) ); - pageLayout = new TQGridLayout( page, 5, 2, 0, spacingHint() ); - - label = new TQLabel( i18n( "Normal bar color:" ), page ); - pageLayout->addWidget( label, 0, 0 ); - - mForegroundColor = new KColorButton( page ); - pageLayout->addWidget( mForegroundColor, 0, 1 ); - label->setBuddy( mForegroundColor ); - - label = new TQLabel( i18n( "Out-of-range color:" ), page ); - pageLayout->addWidget( label, 1, 0 ); - - mAlarmColor = new KColorButton( page ); - pageLayout->addWidget( mAlarmColor, 1, 1 ); - label->setBuddy( mAlarmColor ); - - label = new TQLabel( i18n( "Background color:" ), page ); - pageLayout->addWidget( label, 2, 0 ); - - mBackgroundColor = new KColorButton( page ); - pageLayout->addWidget( mBackgroundColor, 2, 1 ); - label->setBuddy( mBackgroundColor ); - - label = new TQLabel( i18n( "Font size:" ), page ); - pageLayout->addWidget( label, 3, 0 ); - - mFontSize = new KIntNumInput( 9, page ); - TQWhatsThis::add( mFontSize, i18n( "This determines the size of the font used to print a label underneath the bars. Bars are automatically suppressed if text becomes too large, so it is advisable to use a small font size here." ) ); - pageLayout->addWidget( mFontSize, 3, 1 ); - label->setBuddy( mFontSize ); - - pageLayout->setRowStretch( 4, 1 ); - - // Sensor page - page = addPage( i18n( "Sensors" ) ); - pageLayout = new TQGridLayout( page, 3, 2, 0, spacingHint() ); - pageLayout->setRowStretch( 2, 1 ); - - mSensorView = new TDEListView( page ); - mSensorView->addColumn( i18n( "Host" ) ); - mSensorView->addColumn( i18n( "Sensor" ) ); - mSensorView->addColumn( i18n( "Label" ) ); - mSensorView->addColumn( i18n( "Unit" ) ); - mSensorView->addColumn( i18n( "Status" ) ); - mSensorView->setAllColumnsShowFocus( true ); - pageLayout->addMultiCellWidget( mSensorView, 0, 2, 0, 0 ); - - mEditButton = new TQPushButton( i18n( "Edit..." ), page ); - mEditButton->setEnabled( false ); - TQWhatsThis::add( mEditButton, i18n( "Push this button to configure the label." ) ); - pageLayout->addWidget( mEditButton, 0, 1 ); - - mRemoveButton = new TQPushButton( i18n( "Delete" ), page ); - mRemoveButton->setEnabled( false ); - TQWhatsThis::add( mRemoveButton, i18n( "Push this button to delete the sensor." ) ); - pageLayout->addWidget( mRemoveButton, 1, 1 ); - - connect( mUseLowerLimit, TQT_SIGNAL( toggled( bool ) ), - mLowerLimit, TQT_SLOT( setEnabled( bool ) ) ); - connect( mUseUpperLimit, TQT_SIGNAL( toggled( bool ) ), - mUpperLimit, TQT_SLOT( setEnabled( bool ) ) ); - - connect( mSensorView, TQT_SIGNAL( selectionChanged( TQListViewItem* ) ), - TQT_SLOT( selectionChanged( TQListViewItem* ) ) ); - connect( mEditButton, TQT_SIGNAL( clicked() ), TQT_SLOT( editSensor() ) ); - connect( mRemoveButton, TQT_SIGNAL( clicked() ), TQT_SLOT( removeSensor() ) ); - - TDEAcceleratorManager::manage( this ); - - mTitle->setFocus(); -} - -DancingBarsSettings::~DancingBarsSettings() -{ -} - -void DancingBarsSettings::setTitle( const TQString& title ) -{ - mTitle->setText( title ); -} - -TQString DancingBarsSettings::title() const -{ - return mTitle->text(); -} - -void DancingBarsSettings::setMinValue( double min ) -{ - mMinValue->setValue( min ); -} - -double DancingBarsSettings::minValue() const -{ - return mMinValue->value(); -} - -void DancingBarsSettings::setMaxValue( double max ) -{ - mMaxValue->setValue( max ); -} - -double DancingBarsSettings::maxValue() const -{ - return mMaxValue->value(); -} - -void DancingBarsSettings::setUseLowerLimit( bool value ) -{ - mUseLowerLimit->setChecked( value ); -} - -bool DancingBarsSettings::useLowerLimit() const -{ - return mUseLowerLimit->isChecked(); -} - -void DancingBarsSettings::setLowerLimit( double limit ) -{ - mLowerLimit->setValue( limit ); -} - -double DancingBarsSettings::lowerLimit() const -{ - return mLowerLimit->value(); -} - -void DancingBarsSettings::setUseUpperLimit( bool value ) -{ - mUseUpperLimit->setChecked( value ); -} - -bool DancingBarsSettings::useUpperLimit() const -{ - return mUseUpperLimit->isChecked(); -} - -void DancingBarsSettings::setUpperLimit( double limit ) -{ - mUpperLimit->setValue( limit ); -} - -double DancingBarsSettings::upperLimit() const -{ - return mUpperLimit->value(); -} - -void DancingBarsSettings::setForegroundColor( const TQColor &color ) -{ - mForegroundColor->setColor( color ); -} - -TQColor DancingBarsSettings::foregroundColor() const -{ - return mForegroundColor->color(); -} - -void DancingBarsSettings::setAlarmColor( const TQColor &color ) -{ - mAlarmColor->setColor( color ); -} - -TQColor DancingBarsSettings::alarmColor() const -{ - return mAlarmColor->color(); -} - -void DancingBarsSettings::setBackgroundColor( const TQColor &color ) -{ - mBackgroundColor->setColor( color ); -} - -TQColor DancingBarsSettings::backgroundColor() const -{ - return mBackgroundColor->color(); -} - -void DancingBarsSettings::setFontSize( int size ) -{ - mFontSize->setValue( size ); -} - -int DancingBarsSettings::fontSize() const -{ - return mFontSize->value(); -} - -void DancingBarsSettings::setSensors( const TQValueList< TQStringList > &list ) -{ - mSensorView->clear(); - - TQValueList< TQStringList >::ConstIterator it; - for ( it = list.begin(); it != list.end(); ++it ) { - new TQListViewItem( mSensorView, - (*it)[ 0 ], // host name - (*it)[ 1 ], // sensor name - (*it)[ 2 ], // footer title - (*it)[ 3 ], // unit - (*it)[ 4 ] ); // status - } -} - -TQValueList< TQStringList > DancingBarsSettings::sensors() const -{ - TQValueList< TQStringList > list; - - TQListViewItemIterator it( mSensorView ); - while ( it.current() && !it.current()->text( 0 ).isEmpty() ) { - TQStringList entry; - entry << it.current()->text( 0 ); - entry << it.current()->text( 1 ); - entry << it.current()->text( 2 ); - entry << it.current()->text( 3 ); - entry << it.current()->text( 4 ); - - list.append( entry ); - ++it; - } - - return list; -} - -void DancingBarsSettings::editSensor() -{ - TQListViewItem *lvi = mSensorView->currentItem(); - - if ( !lvi ) - return; - - bool ok; - TQString str = KInputDialog::getText( i18n( "Label of Bar Graph" ), - i18n( "Enter new label:" ), lvi->text( 2 ), &ok, this ); - if ( ok ) - lvi->setText( 2, str ); -} - -void DancingBarsSettings::removeSensor() -{ - TQListViewItem *lvi = mSensorView->currentItem(); - - if ( lvi ) { - /* Before we delete the currently selected item, we determine a - * new item to be selected. That way we can ensure that multiple - * items can be deleted without forcing the user to select a new - * item between the deletes. If all items are deleted, the buttons - * are disabled again. */ - TQListViewItem* newSelected = 0; - if ( lvi->itemBelow() ) { - lvi->itemBelow()->setSelected( true ); - newSelected = lvi->itemBelow(); - } else if ( lvi->itemAbove() ) { - lvi->itemAbove()->setSelected( true ); - newSelected = lvi->itemAbove(); - } else - selectionChanged( 0 ); - - delete lvi; - - if ( newSelected ) - mSensorView->ensureItemVisible( newSelected ); - } -} - -void DancingBarsSettings::selectionChanged( TQListViewItem* lvi ) -{ - bool state = ( lvi != 0 ); - - mEditButton->setEnabled( state ); - mRemoveButton->setEnabled( state ); -} - - -#include "DancingBarsSettings.moc" diff --git a/ksysguard/gui/SensorDisplayLib/DancingBarsSettings.cpp b/ksysguard/gui/SensorDisplayLib/DancingBarsSettings.cpp new file mode 100644 index 000000000..ee03f9e94 --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/DancingBarsSettings.cpp @@ -0,0 +1,398 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 2003 Tobias Koenig + + This program is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + KSysGuard is currently maintained by Chris Schlaeger . + Please do not commit any changes without consulting me first. Thanks! + +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "DancingBarsSettings.h" + +DancingBarsSettings::DancingBarsSettings( TQWidget* parent, const char* name ) + : KDialogBase( Tabbed, i18n( "Edit BarGraph Preferences" ), + Ok | Apply | Cancel, Ok, parent, name, true, true ) +{ + // Range page + TQFrame *page = addPage( i18n( "Range" ) ); + TQGridLayout *pageLayout = new TQGridLayout( page, 3, 1, 0, spacingHint() ); + + TQGroupBox *groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Title" ), page ); + TQGridLayout *boxLayout = new TQGridLayout( groupBox->layout(), 1, 1 ); + + mTitle = new KLineEdit( groupBox ); + TQWhatsThis::add( mTitle, i18n( "Enter the title of the display here." ) ); + boxLayout->addWidget( mTitle, 0, 0 ); + + pageLayout->addWidget( groupBox, 0, 0 ); + + groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Display Range" ), page ); + boxLayout = new TQGridLayout( groupBox->layout(), 1, 5 ); + boxLayout->setColStretch( 2, 1 ); + + TQLabel *label = new TQLabel( i18n( "Minimum value:" ), groupBox ); + boxLayout->addWidget( label, 0, 0 ); + + mMinValue = new KDoubleSpinBox( 0, 100, 0.5, 0, 2, groupBox ); + TQWhatsThis::add( mMinValue, i18n( "Enter the minimum value for the display here. If both values are 0, automatic range detection is enabled." ) ); + boxLayout->addWidget( mMinValue, 0, 1 ); + label->setBuddy( mMinValue ); + + label = new TQLabel( i18n( "Maximum value:" ), groupBox ); + boxLayout->addWidget( label, 0, 3 ); + + mMaxValue = new KDoubleSpinBox( 0, 10000, 0.5, 100, 2, groupBox ); + TQWhatsThis::add( mMaxValue, i18n( "Enter the maximum value for the display here. If both values are 0, automatic range detection is enabled." ) ); + boxLayout->addWidget( mMaxValue, 0, 4 ); + label->setBuddy( mMaxValue ); + + pageLayout->addWidget( groupBox, 1, 0 ); + + pageLayout->setRowStretch( 2, 1 ); + + // Alarm page + page = addPage( i18n( "Alarms" ) ); + pageLayout = new TQGridLayout( page, 3, 1, 0, spacingHint() ); + + groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Alarm for Minimum Value" ), page ); + boxLayout = new TQGridLayout( groupBox->layout(), 1, 4 ); + boxLayout->setColStretch( 1, 1 ); + + mUseLowerLimit = new TQCheckBox( i18n( "Enable alarm" ), groupBox ); + TQWhatsThis::add( mUseLowerLimit, i18n( "Enable the minimum value alarm." ) ); + boxLayout->addWidget( mUseLowerLimit, 0, 0 ); + + label = new TQLabel( i18n( "Lower limit:" ), groupBox ); + boxLayout->addWidget( label, 0, 2 ); + + mLowerLimit = new KDoubleSpinBox( 0, 100, 0.5, 0, 2, groupBox ); + mLowerLimit->setEnabled( false ); + boxLayout->addWidget( mLowerLimit, 0, 3 ); + label->setBuddy( mLowerLimit ); + + pageLayout->addWidget( groupBox, 0, 0 ); + + groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Alarm for Maximum Value" ), page ); + boxLayout = new TQGridLayout( groupBox->layout(), 1, 4 ); + boxLayout->setColStretch( 1, 1 ); + + mUseUpperLimit = new TQCheckBox( i18n( "Enable alarm" ), groupBox ); + TQWhatsThis::add( mUseUpperLimit, i18n( "Enable the maximum value alarm." ) ); + boxLayout->addWidget( mUseUpperLimit, 0, 0 ); + + label = new TQLabel( i18n( "Upper limit:" ), groupBox ); + boxLayout->addWidget( label, 0, 2 ); + + mUpperLimit = new KDoubleSpinBox( 0, 100, 0.5, 0, 2, groupBox ); + mUpperLimit->setEnabled( false ); + boxLayout->addWidget( mUpperLimit, 0, 3 ); + label->setBuddy( mUpperLimit ); + + pageLayout->addWidget( groupBox, 1, 0 ); + + pageLayout->setRowStretch( 2, 1 ); + + // Look page + page = addPage( i18n( "Look" ) ); + pageLayout = new TQGridLayout( page, 5, 2, 0, spacingHint() ); + + label = new TQLabel( i18n( "Normal bar color:" ), page ); + pageLayout->addWidget( label, 0, 0 ); + + mForegroundColor = new KColorButton( page ); + pageLayout->addWidget( mForegroundColor, 0, 1 ); + label->setBuddy( mForegroundColor ); + + label = new TQLabel( i18n( "Out-of-range color:" ), page ); + pageLayout->addWidget( label, 1, 0 ); + + mAlarmColor = new KColorButton( page ); + pageLayout->addWidget( mAlarmColor, 1, 1 ); + label->setBuddy( mAlarmColor ); + + label = new TQLabel( i18n( "Background color:" ), page ); + pageLayout->addWidget( label, 2, 0 ); + + mBackgroundColor = new KColorButton( page ); + pageLayout->addWidget( mBackgroundColor, 2, 1 ); + label->setBuddy( mBackgroundColor ); + + label = new TQLabel( i18n( "Font size:" ), page ); + pageLayout->addWidget( label, 3, 0 ); + + mFontSize = new KIntNumInput( 9, page ); + TQWhatsThis::add( mFontSize, i18n( "This determines the size of the font used to print a label underneath the bars. Bars are automatically suppressed if text becomes too large, so it is advisable to use a small font size here." ) ); + pageLayout->addWidget( mFontSize, 3, 1 ); + label->setBuddy( mFontSize ); + + pageLayout->setRowStretch( 4, 1 ); + + // Sensor page + page = addPage( i18n( "Sensors" ) ); + pageLayout = new TQGridLayout( page, 3, 2, 0, spacingHint() ); + pageLayout->setRowStretch( 2, 1 ); + + mSensorView = new TDEListView( page ); + mSensorView->addColumn( i18n( "Host" ) ); + mSensorView->addColumn( i18n( "Sensor" ) ); + mSensorView->addColumn( i18n( "Label" ) ); + mSensorView->addColumn( i18n( "Unit" ) ); + mSensorView->addColumn( i18n( "Status" ) ); + mSensorView->setAllColumnsShowFocus( true ); + pageLayout->addMultiCellWidget( mSensorView, 0, 2, 0, 0 ); + + mEditButton = new TQPushButton( i18n( "Edit..." ), page ); + mEditButton->setEnabled( false ); + TQWhatsThis::add( mEditButton, i18n( "Push this button to configure the label." ) ); + pageLayout->addWidget( mEditButton, 0, 1 ); + + mRemoveButton = new TQPushButton( i18n( "Delete" ), page ); + mRemoveButton->setEnabled( false ); + TQWhatsThis::add( mRemoveButton, i18n( "Push this button to delete the sensor." ) ); + pageLayout->addWidget( mRemoveButton, 1, 1 ); + + connect( mUseLowerLimit, TQT_SIGNAL( toggled( bool ) ), + mLowerLimit, TQT_SLOT( setEnabled( bool ) ) ); + connect( mUseUpperLimit, TQT_SIGNAL( toggled( bool ) ), + mUpperLimit, TQT_SLOT( setEnabled( bool ) ) ); + + connect( mSensorView, TQT_SIGNAL( selectionChanged( TQListViewItem* ) ), + TQT_SLOT( selectionChanged( TQListViewItem* ) ) ); + connect( mEditButton, TQT_SIGNAL( clicked() ), TQT_SLOT( editSensor() ) ); + connect( mRemoveButton, TQT_SIGNAL( clicked() ), TQT_SLOT( removeSensor() ) ); + + TDEAcceleratorManager::manage( this ); + + mTitle->setFocus(); +} + +DancingBarsSettings::~DancingBarsSettings() +{ +} + +void DancingBarsSettings::setTitle( const TQString& title ) +{ + mTitle->setText( title ); +} + +TQString DancingBarsSettings::title() const +{ + return mTitle->text(); +} + +void DancingBarsSettings::setMinValue( double min ) +{ + mMinValue->setValue( min ); +} + +double DancingBarsSettings::minValue() const +{ + return mMinValue->value(); +} + +void DancingBarsSettings::setMaxValue( double max ) +{ + mMaxValue->setValue( max ); +} + +double DancingBarsSettings::maxValue() const +{ + return mMaxValue->value(); +} + +void DancingBarsSettings::setUseLowerLimit( bool value ) +{ + mUseLowerLimit->setChecked( value ); +} + +bool DancingBarsSettings::useLowerLimit() const +{ + return mUseLowerLimit->isChecked(); +} + +void DancingBarsSettings::setLowerLimit( double limit ) +{ + mLowerLimit->setValue( limit ); +} + +double DancingBarsSettings::lowerLimit() const +{ + return mLowerLimit->value(); +} + +void DancingBarsSettings::setUseUpperLimit( bool value ) +{ + mUseUpperLimit->setChecked( value ); +} + +bool DancingBarsSettings::useUpperLimit() const +{ + return mUseUpperLimit->isChecked(); +} + +void DancingBarsSettings::setUpperLimit( double limit ) +{ + mUpperLimit->setValue( limit ); +} + +double DancingBarsSettings::upperLimit() const +{ + return mUpperLimit->value(); +} + +void DancingBarsSettings::setForegroundColor( const TQColor &color ) +{ + mForegroundColor->setColor( color ); +} + +TQColor DancingBarsSettings::foregroundColor() const +{ + return mForegroundColor->color(); +} + +void DancingBarsSettings::setAlarmColor( const TQColor &color ) +{ + mAlarmColor->setColor( color ); +} + +TQColor DancingBarsSettings::alarmColor() const +{ + return mAlarmColor->color(); +} + +void DancingBarsSettings::setBackgroundColor( const TQColor &color ) +{ + mBackgroundColor->setColor( color ); +} + +TQColor DancingBarsSettings::backgroundColor() const +{ + return mBackgroundColor->color(); +} + +void DancingBarsSettings::setFontSize( int size ) +{ + mFontSize->setValue( size ); +} + +int DancingBarsSettings::fontSize() const +{ + return mFontSize->value(); +} + +void DancingBarsSettings::setSensors( const TQValueList< TQStringList > &list ) +{ + mSensorView->clear(); + + TQValueList< TQStringList >::ConstIterator it; + for ( it = list.begin(); it != list.end(); ++it ) { + new TQListViewItem( mSensorView, + (*it)[ 0 ], // host name + (*it)[ 1 ], // sensor name + (*it)[ 2 ], // footer title + (*it)[ 3 ], // unit + (*it)[ 4 ] ); // status + } +} + +TQValueList< TQStringList > DancingBarsSettings::sensors() const +{ + TQValueList< TQStringList > list; + + TQListViewItemIterator it( mSensorView ); + while ( it.current() && !it.current()->text( 0 ).isEmpty() ) { + TQStringList entry; + entry << it.current()->text( 0 ); + entry << it.current()->text( 1 ); + entry << it.current()->text( 2 ); + entry << it.current()->text( 3 ); + entry << it.current()->text( 4 ); + + list.append( entry ); + ++it; + } + + return list; +} + +void DancingBarsSettings::editSensor() +{ + TQListViewItem *lvi = mSensorView->currentItem(); + + if ( !lvi ) + return; + + bool ok; + TQString str = KInputDialog::getText( i18n( "Label of Bar Graph" ), + i18n( "Enter new label:" ), lvi->text( 2 ), &ok, this ); + if ( ok ) + lvi->setText( 2, str ); +} + +void DancingBarsSettings::removeSensor() +{ + TQListViewItem *lvi = mSensorView->currentItem(); + + if ( lvi ) { + /* Before we delete the currently selected item, we determine a + * new item to be selected. That way we can ensure that multiple + * items can be deleted without forcing the user to select a new + * item between the deletes. If all items are deleted, the buttons + * are disabled again. */ + TQListViewItem* newSelected = 0; + if ( lvi->itemBelow() ) { + lvi->itemBelow()->setSelected( true ); + newSelected = lvi->itemBelow(); + } else if ( lvi->itemAbove() ) { + lvi->itemAbove()->setSelected( true ); + newSelected = lvi->itemAbove(); + } else + selectionChanged( 0 ); + + delete lvi; + + if ( newSelected ) + mSensorView->ensureItemVisible( newSelected ); + } +} + +void DancingBarsSettings::selectionChanged( TQListViewItem* lvi ) +{ + bool state = ( lvi != 0 ); + + mEditButton->setEnabled( state ); + mRemoveButton->setEnabled( state ); +} + + +#include "DancingBarsSettings.moc" diff --git a/ksysguard/gui/SensorDisplayLib/DummyDisplay.cc b/ksysguard/gui/SensorDisplayLib/DummyDisplay.cc deleted file mode 100644 index 13696c502..000000000 --- a/ksysguard/gui/SensorDisplayLib/DummyDisplay.cc +++ /dev/null @@ -1,58 +0,0 @@ -/* - KSysGuard, the KDE System Guard - - Copyright (c) 1999, 2000, 2001 Chris Schlaeger - - This program is free software; you can redistribute it and/or - modify it under the terms of version 2 of the GNU General Public - License as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - KSysGuard is currently maintained by Chris Schlaeger . - Please do not commit any changes without consulting me first. Thanks! - -*/ - -#include -#include - -#include - -#include "DummyDisplay.h" - -DummyDisplay::DummyDisplay( TQWidget* parent, const char* name, - const TQString&, double, double ) - : KSGRD::SensorDisplay( parent, name, i18n( "Drop Sensor Here" ) ) -{ - setMinimumSize( 16, 16 ); - - TQWhatsThis::add( this, i18n( - "This is an empty space in a worksheet. Drag a sensor from " - "the Sensor Browser and drop it here. A sensor display will " - "appear that allows you to monitor the values of the sensor " - "over time." ) ); -} - -void DummyDisplay::resizeEvent( TQResizeEvent* ) -{ - frame()->setGeometry( 0, 0, width(), height() ); -} - -bool DummyDisplay::eventFilter( TQObject* object, TQEvent* event ) -{ - if ( event->type() == TQEvent::MouseButtonRelease && - ( (TQMouseEvent*)event)->button() == Qt::LeftButton ) - setFocus(); - - return TQWidget::eventFilter( object, event ); -} - -#include "DummyDisplay.moc" diff --git a/ksysguard/gui/SensorDisplayLib/DummyDisplay.cpp b/ksysguard/gui/SensorDisplayLib/DummyDisplay.cpp new file mode 100644 index 000000000..13696c502 --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/DummyDisplay.cpp @@ -0,0 +1,58 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 1999, 2000, 2001 Chris Schlaeger + + This program is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + KSysGuard is currently maintained by Chris Schlaeger . + Please do not commit any changes without consulting me first. Thanks! + +*/ + +#include +#include + +#include + +#include "DummyDisplay.h" + +DummyDisplay::DummyDisplay( TQWidget* parent, const char* name, + const TQString&, double, double ) + : KSGRD::SensorDisplay( parent, name, i18n( "Drop Sensor Here" ) ) +{ + setMinimumSize( 16, 16 ); + + TQWhatsThis::add( this, i18n( + "This is an empty space in a worksheet. Drag a sensor from " + "the Sensor Browser and drop it here. A sensor display will " + "appear that allows you to monitor the values of the sensor " + "over time." ) ); +} + +void DummyDisplay::resizeEvent( TQResizeEvent* ) +{ + frame()->setGeometry( 0, 0, width(), height() ); +} + +bool DummyDisplay::eventFilter( TQObject* object, TQEvent* event ) +{ + if ( event->type() == TQEvent::MouseButtonRelease && + ( (TQMouseEvent*)event)->button() == Qt::LeftButton ) + setFocus(); + + return TQWidget::eventFilter( object, event ); +} + +#include "DummyDisplay.moc" diff --git a/ksysguard/gui/SensorDisplayLib/FancyPlotter.cc b/ksysguard/gui/SensorDisplayLib/FancyPlotter.cc deleted file mode 100644 index 22894afea..000000000 --- a/ksysguard/gui/SensorDisplayLib/FancyPlotter.cc +++ /dev/null @@ -1,457 +0,0 @@ -/* - KSysGuard, the KDE System Guard - - Copyright (c) 1999 - 2002 Chris Schlaeger - - This program is free software; you can redistribute it and/or - modify it under the terms of version 2 of the GNU General Public - License as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - KSysGuard is currently maintained by Chris Schlaeger . - Please do not commit any changes without consulting me first. Thanks! - -*/ - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include "SensorDisplay.h" -#include "FancyPlotterSettings.h" - -#include "FancyPlotter.h" - -FancyPlotter::FancyPlotter( TQWidget* parent, const char* name, - const TQString &title, double, double, - bool nf, bool isApplet) - : KSGRD::SensorDisplay( parent, name, title, nf, isApplet ) -{ - mBeams = 0; - mSettingsDialog = 0; - - if ( noFrame() ) { - mPlotter = new SignalPlotter( this ); - mPlotter->setShowTopBar( true ); - } else - mPlotter = new SignalPlotter( frame() ); - mPlotter->setTitle( title ); - mPlotter->setThinFrame(!isApplet); //if we aren't an applet, draw a thin white frame on the left and bottom, for a 3d effect - - setMinimumSize( sizeHint() ); - - /* All RMB clicks to the mPlotter widget will be handled by - * SensorDisplay::eventFilter. */ - mPlotter->installEventFilter( this ); - - setPlotterWidget( TQT_TQWIDGET(mPlotter) ); - - setModified( false ); -} - -FancyPlotter::~FancyPlotter() -{ -} - -void FancyPlotter::configureSettings() -{ - if(mSettingsDialog) { - return; - } - mSettingsDialog = new FancyPlotterSettings( this ); - - mSettingsDialog->setTitle( title() ); - mSettingsDialog->setUseAutoRange( mPlotter->useAutoRange() ); - mSettingsDialog->setMinValue( mPlotter->minValue() ); - mSettingsDialog->setMaxValue( mPlotter->maxValue() ); - - mSettingsDialog->setUsePolygonStyle( mPlotter->graphStyle() == GRAPH_POLYGON ); - mSettingsDialog->setHorizontalScale( mPlotter->horizontalScale() ); - - mSettingsDialog->setShowVerticalLines( mPlotter->showVerticalLines() ); - mSettingsDialog->setVerticalLinesColor( mPlotter->verticalLinesColor() ); - mSettingsDialog->setVerticalLinesDistance( mPlotter->verticalLinesDistance() ); - mSettingsDialog->setVerticalLinesScroll( mPlotter->verticalLinesScroll() ); - - mSettingsDialog->setShowHorizontalLines( mPlotter->showHorizontalLines() ); - mSettingsDialog->setHorizontalLinesColor( mPlotter->horizontalLinesColor() ); - mSettingsDialog->setHorizontalLinesCount( mPlotter->horizontalLinesCount() ); - - mSettingsDialog->setShowLabels( mPlotter->showLabels() ); - mSettingsDialog->setShowTopBar( mPlotter->showTopBar() ); - mSettingsDialog->setFontSize( mPlotter->fontSize() ); - - mSettingsDialog->setBackgroundColor( mPlotter->backgroundColor() ); - - TQValueList< TQStringList > list; - for ( uint i = 0; i < mBeams; ++i ) { - TQStringList entry; - entry << TQString::number(i); - entry << sensors().at( i )->hostName(); - entry << KSGRD::SensorMgr->translateSensor( sensors().at( i )->name() ); - entry << KSGRD::SensorMgr->translateUnit( sensors().at( i )->unit() ); - entry << ( sensors().at( i )->isOk() ? i18n( "OK" ) : i18n( "Error" ) ); - entry << ( mPlotter->beamColors()[ i ].name() ); - - list.append( entry ); - } - mSettingsDialog->setSensors( list ); - - connect( mSettingsDialog, TQT_SIGNAL( applyClicked() ), TQT_SLOT( applySettings() ) ); - connect( mSettingsDialog, TQT_SIGNAL( okClicked() ), TQT_SLOT( applySettings() ) ); - connect( mSettingsDialog, TQT_SIGNAL( finished() ), TQT_SLOT( killDialog() ) ); - - mSettingsDialog->show(); -} - -void FancyPlotter::killDialog() { - mSettingsDialog->delayedDestruct(); - mSettingsDialog = 0; -} - -void FancyPlotter::applySettings() -{ - setTitle( mSettingsDialog->title() ); - mPlotter->setTitle( title() ); - - if ( mSettingsDialog->useAutoRange() ) - mPlotter->setUseAutoRange( true ); - else { - mPlotter->setUseAutoRange( false ); - mPlotter->changeRange( 0, mSettingsDialog->minValue(), - mSettingsDialog->maxValue() ); - } - - if ( mSettingsDialog->usePolygonStyle() ) - mPlotter->setGraphStyle( GRAPH_POLYGON ); - else - mPlotter->setGraphStyle( GRAPH_ORIGINAL ); - - if ( mPlotter->horizontalScale() != mSettingsDialog->horizontalScale() ) { - mPlotter->setHorizontalScale( mSettingsDialog->horizontalScale() ); - // Can someone think of a useful TQResizeEvent to pass? - // It doesn't really matter anyway because it's not used. - emit resizeEvent( 0 ); - } - - mPlotter->setShowVerticalLines( mSettingsDialog->showVerticalLines() ); - mPlotter->setVerticalLinesColor( mSettingsDialog->verticalLinesColor() ); - mPlotter->setVerticalLinesDistance( mSettingsDialog->verticalLinesDistance() ); - mPlotter->setVerticalLinesScroll( mSettingsDialog->verticalLinesScroll() ); - - mPlotter->setShowHorizontalLines( mSettingsDialog->showHorizontalLines() ); - mPlotter->setHorizontalLinesColor( mSettingsDialog->horizontalLinesColor() ); - mPlotter->setHorizontalLinesCount( mSettingsDialog->horizontalLinesCount() ); - - mPlotter->setShowLabels( mSettingsDialog->showLabels() ); - mPlotter->setShowTopBar( mSettingsDialog->showTopBar() ); - mPlotter->setFontSize( mSettingsDialog->fontSize() ); - - mPlotter->setBackgroundColor( mSettingsDialog->backgroundColor() ); - - - TQValueList orderOfSensors = mSettingsDialog->order(); - TQValueList deletedSensors = mSettingsDialog->deleted(); - mSettingsDialog->clearDeleted(); - mSettingsDialog->resetOrder(); - TQValueList< int >::Iterator itDelete; - for ( itDelete = deletedSensors.begin(); itDelete != deletedSensors.end(); ++itDelete ) - removeSensor(*itDelete); - - TQValueList< int >::Iterator itOrder; - mPlotter->reorderBeams(orderOfSensors); - reorderSensors(orderOfSensors); - - TQValueList< TQStringList > list = mSettingsDialog->sensors(); - TQValueList< TQStringList >::Iterator it; - - for ( uint i = 0; i < sensors().count(); ++i ) - mPlotter->beamColors()[ i ] = TQColor( list[i][ 5 ] ); - - mPlotter->repaint(); - setModified( true ); -} - -void FancyPlotter::applyStyle() -{ - mPlotter->setVerticalLinesColor( KSGRD::Style->firstForegroundColor() ); - mPlotter->setHorizontalLinesColor( KSGRD::Style->secondForegroundColor() ); - mPlotter->setBackgroundColor( KSGRD::Style->backgroundColor() ); - mPlotter->setFontSize( KSGRD::Style->fontSize() ); - for ( uint i = 0; i < mPlotter->beamColors().count() && - i < KSGRD::Style->numSensorColors(); ++i ) - mPlotter->beamColors()[ i ] = KSGRD::Style->sensorColor( i ); - - mPlotter->update(); - setModified( true ); -} - -bool FancyPlotter::addSensor( const TQString &hostName, const TQString &name, - const TQString &type, const TQString &title ) -{ - return addSensor( hostName, name, type, title, - KSGRD::Style->sensorColor( mBeams ) ); -} - -bool FancyPlotter::addSensor( const TQString &hostName, const TQString &name, - const TQString &type, const TQString &title, - const TQColor &color ) -{ - if ( type != "integer" && type != "float" ) - return false; - - if ( mBeams > 0 && hostName != sensors().at( 0 )->hostName() ) { - KMessageBox::sorry( this, TQString( "All sensors of this display need " - "to be from the host %1!" ) - .arg( sensors().at( 0 )->hostName() ) ); - - /* We have to enforce this since the answers to value requests - * need to be received in order. */ - return false; - } - - if ( !mPlotter->addBeam( color ) ) - return false; - - registerSensor( new FPSensorProperties( hostName, name, type, title, color ) ); - - /* To differentiate between answers from value requests and info - * requests we add 100 to the beam index for info requests. */ - sendRequest( hostName, name + "?", mBeams + 100 ); - - ++mBeams; - - TQString tooltip; - for ( uint i = 0; i < mBeams; ++i ) { - tooltip += TQString( "%1%2:%3" ).arg( i != 0 ? "\n" : "" ) - .arg( sensors().at( mBeams - i - 1 )->hostName() ) - .arg( sensors().at( mBeams - i - 1 )->name() ); - } - - TQToolTip::remove( TQT_TQWIDGET(mPlotter) ); - TQToolTip::add( TQT_TQWIDGET(mPlotter), tooltip ); - - return true; -} - -bool FancyPlotter::removeSensor( uint pos ) -{ - if ( pos >= mBeams ) { - kdDebug(1215) << "FancyPlotter::removeSensor: idx out of range (" - << pos << ")" << endl; - return false; - } - - mPlotter->removeBeam( pos ); - mBeams--; - KSGRD::SensorDisplay::removeSensor( pos ); - - TQString tooltip; - for ( uint i = 0; i < mBeams; ++i ) { - tooltip += TQString( "%1%2:%3" ).arg( i != 0 ? "\n" : "" ) - .arg( sensors().at( mBeams - i - 1 )->hostName() ) - .arg( sensors().at( mBeams - i - 1 )->name() ); - } - - TQToolTip::remove( TQT_TQWIDGET(mPlotter) ); - TQToolTip::add( TQT_TQWIDGET(mPlotter), tooltip ); - - return true; -} - -void FancyPlotter::resizeEvent( TQResizeEvent* ) -{ - if ( noFrame() ) - mPlotter->setGeometry( 0, 0, width(), height() ); - else - frame()->setGeometry( 0, 0, width(), height() ); -} - -TQSize FancyPlotter::sizeHint() -{ - if ( noFrame() ) - return mPlotter->sizeHint(); - else - return frame()->sizeHint(); -} - -void FancyPlotter::answerReceived( int id, const TQString &answer ) -{ - if ( (uint)id < mBeams ) { - if ( id != (int)mSampleBuf.count() ) { - if ( id == 0 ) - sensorError( mBeams - 1, true ); - else - sensorError( id - 1, true ); - } - mSampleBuf.append( answer.toDouble() ); - - /* We received something, so the sensor is probably ok. */ - sensorError( id, false ); - - if ( id == (int)mBeams - 1 ) { - mPlotter->addSample( mSampleBuf ); - mSampleBuf.clear(); - } - } else if ( id >= 100 ) { - KSGRD::SensorFloatInfo info( answer ); - if ( !mPlotter->useAutoRange() && mPlotter->minValue() == 0.0 && - mPlotter->maxValue() == 0.0 ) { - /* We only use this information from the sensor when the - * display is still using the default values. If the - * sensor has been restored we don't touch the already set - * values. */ - mPlotter->changeRange( id - 100, info.min(), info.max() ); - if ( info.min() == 0.0 && info.max() == 0.0 ) - mPlotter->setUseAutoRange( true ); - } - sensors().at( id - 100 )->setUnit( info.unit() ); - } -} - -bool FancyPlotter::restoreSettings( TQDomElement &element ) -{ - /* autoRage was added after KDE 2.x and was brokenly emulated by - * min == 0.0 and max == 0.0. Since we have to be able to read old - * files as well we have to emulate the old behaviour as well. */ - double min = element.attribute( "min", "0.0" ).toDouble(); - double max = element.attribute( "max", "0.0" ).toDouble(); - if ( element.attribute( "autoRange", min == 0.0 && max == 0.0 ? "1" : "0" ).toInt() ) - mPlotter->setUseAutoRange( true ); - else { - mPlotter->setUseAutoRange( false ); - mPlotter->changeRange( 0, element.attribute( "min" ).toDouble(), - element.attribute( "max" ).toDouble() ); - } - - mPlotter->setShowVerticalLines( element.attribute( "vLines", "1" ).toUInt() ); - mPlotter->setVerticalLinesColor( restoreColor( element, "vColor", - KSGRD::Style->firstForegroundColor() ) ); - mPlotter->setVerticalLinesDistance( element.attribute( "vDistance", "30" ).toUInt() ); - mPlotter->setVerticalLinesScroll( element.attribute( "vScroll", "1" ).toUInt() ); - mPlotter->setGraphStyle( element.attribute( "graphStyle", "0" ).toUInt() ); - mPlotter->setHorizontalScale( element.attribute( "hScale", "1" ).toUInt() ); - - mPlotter->setShowHorizontalLines( element.attribute( "hLines", "1" ).toUInt() ); - mPlotter->setHorizontalLinesColor( restoreColor( element, "hColor", - KSGRD::Style->secondForegroundColor() ) ); - mPlotter->setHorizontalLinesCount( element.attribute( "hCount", "5" ).toUInt() ); - - mPlotter->setShowLabels( element.attribute( "labels", "1" ).toUInt() ); - mPlotter->setShowTopBar( element.attribute( "topBar", "0" ).toUInt() ); - mPlotter->setFontSize( element.attribute( "fontSize", - TQString( "%1" ).arg( KSGRD::Style->fontSize() ) ).toUInt() ); - - mPlotter->setBackgroundColor( restoreColor( element, "bColor", - KSGRD::Style->backgroundColor() ) ); - - TQDomNodeList dnList = element.elementsByTagName( "beam" ); - for ( uint i = 0; i < dnList.count(); ++i ) { - TQDomElement el = dnList.item( i ).toElement(); - addSensor( el.attribute( "hostName" ), el.attribute( "sensorName" ), - ( el.attribute( "sensorType" ).isEmpty() ? "integer" : - el.attribute( "sensorType" ) ), "", restoreColor( el, "color", - KSGRD::Style->sensorColor( i ) ) ); - } - - SensorDisplay::restoreSettings( element ); - - if ( !title().isEmpty() ) - mPlotter->setTitle( title() ); - - setModified( false ); - - return true; -} - -bool FancyPlotter::saveSettings( TQDomDocument &doc, TQDomElement &element, - bool save ) -{ - element.setAttribute( "min", mPlotter->minValue() ); - element.setAttribute( "max", mPlotter->maxValue() ); - element.setAttribute( "autoRange", mPlotter->useAutoRange() ); - element.setAttribute( "vLines", mPlotter->showVerticalLines() ); - saveColor( element, "vColor", mPlotter->verticalLinesColor() ); - element.setAttribute( "vDistance", mPlotter->verticalLinesDistance() ); - element.setAttribute( "vScroll", mPlotter->verticalLinesScroll() ); - - element.setAttribute( "graphStyle", mPlotter->graphStyle() ); - element.setAttribute( "hScale", mPlotter->horizontalScale() ); - - element.setAttribute( "hLines", mPlotter->showHorizontalLines() ); - saveColor( element, "hColor", mPlotter->horizontalLinesColor() ); - element.setAttribute( "hCount", mPlotter->horizontalLinesCount() ); - - element.setAttribute( "labels", mPlotter->showLabels() ); - element.setAttribute( "topBar", mPlotter->showTopBar() ); - element.setAttribute( "fontSize", mPlotter->fontSize() ); - - saveColor( element, "bColor", mPlotter->backgroundColor() ); - - for ( uint i = 0; i < mBeams; ++i ) { - TQDomElement beam = doc.createElement( "beam" ); - element.appendChild( beam ); - beam.setAttribute( "hostName", sensors().at( i )->hostName() ); - beam.setAttribute( "sensorName", sensors().at( i )->name() ); - beam.setAttribute( "sensorType", sensors().at( i )->type() ); - saveColor( beam, "color", mPlotter->beamColors()[ i ] ); - } - - SensorDisplay::saveSettings( doc, element ); - - if ( save ) - setModified( false ); - - return true; -} - -bool FancyPlotter::hasSettingsDialog() const -{ - return true; -} - - - -FPSensorProperties::FPSensorProperties() -{ -} - -FPSensorProperties::FPSensorProperties( const TQString &hostName, - const TQString &name, - const TQString &type, - const TQString &description, - const TQColor &color ) - : KSGRD::SensorProperties( hostName, name, type, description ), - mColor( color ) -{ -} - -FPSensorProperties::~FPSensorProperties() -{ -} - -void FPSensorProperties::setColor( const TQColor &color ) -{ - mColor = color; -} - -TQColor FPSensorProperties::color() const -{ - return mColor; -} - -#include "FancyPlotter.moc" diff --git a/ksysguard/gui/SensorDisplayLib/FancyPlotter.cpp b/ksysguard/gui/SensorDisplayLib/FancyPlotter.cpp new file mode 100644 index 000000000..22894afea --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/FancyPlotter.cpp @@ -0,0 +1,457 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 1999 - 2002 Chris Schlaeger + + This program is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + KSysGuard is currently maintained by Chris Schlaeger . + Please do not commit any changes without consulting me first. Thanks! + +*/ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include "SensorDisplay.h" +#include "FancyPlotterSettings.h" + +#include "FancyPlotter.h" + +FancyPlotter::FancyPlotter( TQWidget* parent, const char* name, + const TQString &title, double, double, + bool nf, bool isApplet) + : KSGRD::SensorDisplay( parent, name, title, nf, isApplet ) +{ + mBeams = 0; + mSettingsDialog = 0; + + if ( noFrame() ) { + mPlotter = new SignalPlotter( this ); + mPlotter->setShowTopBar( true ); + } else + mPlotter = new SignalPlotter( frame() ); + mPlotter->setTitle( title ); + mPlotter->setThinFrame(!isApplet); //if we aren't an applet, draw a thin white frame on the left and bottom, for a 3d effect + + setMinimumSize( sizeHint() ); + + /* All RMB clicks to the mPlotter widget will be handled by + * SensorDisplay::eventFilter. */ + mPlotter->installEventFilter( this ); + + setPlotterWidget( TQT_TQWIDGET(mPlotter) ); + + setModified( false ); +} + +FancyPlotter::~FancyPlotter() +{ +} + +void FancyPlotter::configureSettings() +{ + if(mSettingsDialog) { + return; + } + mSettingsDialog = new FancyPlotterSettings( this ); + + mSettingsDialog->setTitle( title() ); + mSettingsDialog->setUseAutoRange( mPlotter->useAutoRange() ); + mSettingsDialog->setMinValue( mPlotter->minValue() ); + mSettingsDialog->setMaxValue( mPlotter->maxValue() ); + + mSettingsDialog->setUsePolygonStyle( mPlotter->graphStyle() == GRAPH_POLYGON ); + mSettingsDialog->setHorizontalScale( mPlotter->horizontalScale() ); + + mSettingsDialog->setShowVerticalLines( mPlotter->showVerticalLines() ); + mSettingsDialog->setVerticalLinesColor( mPlotter->verticalLinesColor() ); + mSettingsDialog->setVerticalLinesDistance( mPlotter->verticalLinesDistance() ); + mSettingsDialog->setVerticalLinesScroll( mPlotter->verticalLinesScroll() ); + + mSettingsDialog->setShowHorizontalLines( mPlotter->showHorizontalLines() ); + mSettingsDialog->setHorizontalLinesColor( mPlotter->horizontalLinesColor() ); + mSettingsDialog->setHorizontalLinesCount( mPlotter->horizontalLinesCount() ); + + mSettingsDialog->setShowLabels( mPlotter->showLabels() ); + mSettingsDialog->setShowTopBar( mPlotter->showTopBar() ); + mSettingsDialog->setFontSize( mPlotter->fontSize() ); + + mSettingsDialog->setBackgroundColor( mPlotter->backgroundColor() ); + + TQValueList< TQStringList > list; + for ( uint i = 0; i < mBeams; ++i ) { + TQStringList entry; + entry << TQString::number(i); + entry << sensors().at( i )->hostName(); + entry << KSGRD::SensorMgr->translateSensor( sensors().at( i )->name() ); + entry << KSGRD::SensorMgr->translateUnit( sensors().at( i )->unit() ); + entry << ( sensors().at( i )->isOk() ? i18n( "OK" ) : i18n( "Error" ) ); + entry << ( mPlotter->beamColors()[ i ].name() ); + + list.append( entry ); + } + mSettingsDialog->setSensors( list ); + + connect( mSettingsDialog, TQT_SIGNAL( applyClicked() ), TQT_SLOT( applySettings() ) ); + connect( mSettingsDialog, TQT_SIGNAL( okClicked() ), TQT_SLOT( applySettings() ) ); + connect( mSettingsDialog, TQT_SIGNAL( finished() ), TQT_SLOT( killDialog() ) ); + + mSettingsDialog->show(); +} + +void FancyPlotter::killDialog() { + mSettingsDialog->delayedDestruct(); + mSettingsDialog = 0; +} + +void FancyPlotter::applySettings() +{ + setTitle( mSettingsDialog->title() ); + mPlotter->setTitle( title() ); + + if ( mSettingsDialog->useAutoRange() ) + mPlotter->setUseAutoRange( true ); + else { + mPlotter->setUseAutoRange( false ); + mPlotter->changeRange( 0, mSettingsDialog->minValue(), + mSettingsDialog->maxValue() ); + } + + if ( mSettingsDialog->usePolygonStyle() ) + mPlotter->setGraphStyle( GRAPH_POLYGON ); + else + mPlotter->setGraphStyle( GRAPH_ORIGINAL ); + + if ( mPlotter->horizontalScale() != mSettingsDialog->horizontalScale() ) { + mPlotter->setHorizontalScale( mSettingsDialog->horizontalScale() ); + // Can someone think of a useful TQResizeEvent to pass? + // It doesn't really matter anyway because it's not used. + emit resizeEvent( 0 ); + } + + mPlotter->setShowVerticalLines( mSettingsDialog->showVerticalLines() ); + mPlotter->setVerticalLinesColor( mSettingsDialog->verticalLinesColor() ); + mPlotter->setVerticalLinesDistance( mSettingsDialog->verticalLinesDistance() ); + mPlotter->setVerticalLinesScroll( mSettingsDialog->verticalLinesScroll() ); + + mPlotter->setShowHorizontalLines( mSettingsDialog->showHorizontalLines() ); + mPlotter->setHorizontalLinesColor( mSettingsDialog->horizontalLinesColor() ); + mPlotter->setHorizontalLinesCount( mSettingsDialog->horizontalLinesCount() ); + + mPlotter->setShowLabels( mSettingsDialog->showLabels() ); + mPlotter->setShowTopBar( mSettingsDialog->showTopBar() ); + mPlotter->setFontSize( mSettingsDialog->fontSize() ); + + mPlotter->setBackgroundColor( mSettingsDialog->backgroundColor() ); + + + TQValueList orderOfSensors = mSettingsDialog->order(); + TQValueList deletedSensors = mSettingsDialog->deleted(); + mSettingsDialog->clearDeleted(); + mSettingsDialog->resetOrder(); + TQValueList< int >::Iterator itDelete; + for ( itDelete = deletedSensors.begin(); itDelete != deletedSensors.end(); ++itDelete ) + removeSensor(*itDelete); + + TQValueList< int >::Iterator itOrder; + mPlotter->reorderBeams(orderOfSensors); + reorderSensors(orderOfSensors); + + TQValueList< TQStringList > list = mSettingsDialog->sensors(); + TQValueList< TQStringList >::Iterator it; + + for ( uint i = 0; i < sensors().count(); ++i ) + mPlotter->beamColors()[ i ] = TQColor( list[i][ 5 ] ); + + mPlotter->repaint(); + setModified( true ); +} + +void FancyPlotter::applyStyle() +{ + mPlotter->setVerticalLinesColor( KSGRD::Style->firstForegroundColor() ); + mPlotter->setHorizontalLinesColor( KSGRD::Style->secondForegroundColor() ); + mPlotter->setBackgroundColor( KSGRD::Style->backgroundColor() ); + mPlotter->setFontSize( KSGRD::Style->fontSize() ); + for ( uint i = 0; i < mPlotter->beamColors().count() && + i < KSGRD::Style->numSensorColors(); ++i ) + mPlotter->beamColors()[ i ] = KSGRD::Style->sensorColor( i ); + + mPlotter->update(); + setModified( true ); +} + +bool FancyPlotter::addSensor( const TQString &hostName, const TQString &name, + const TQString &type, const TQString &title ) +{ + return addSensor( hostName, name, type, title, + KSGRD::Style->sensorColor( mBeams ) ); +} + +bool FancyPlotter::addSensor( const TQString &hostName, const TQString &name, + const TQString &type, const TQString &title, + const TQColor &color ) +{ + if ( type != "integer" && type != "float" ) + return false; + + if ( mBeams > 0 && hostName != sensors().at( 0 )->hostName() ) { + KMessageBox::sorry( this, TQString( "All sensors of this display need " + "to be from the host %1!" ) + .arg( sensors().at( 0 )->hostName() ) ); + + /* We have to enforce this since the answers to value requests + * need to be received in order. */ + return false; + } + + if ( !mPlotter->addBeam( color ) ) + return false; + + registerSensor( new FPSensorProperties( hostName, name, type, title, color ) ); + + /* To differentiate between answers from value requests and info + * requests we add 100 to the beam index for info requests. */ + sendRequest( hostName, name + "?", mBeams + 100 ); + + ++mBeams; + + TQString tooltip; + for ( uint i = 0; i < mBeams; ++i ) { + tooltip += TQString( "%1%2:%3" ).arg( i != 0 ? "\n" : "" ) + .arg( sensors().at( mBeams - i - 1 )->hostName() ) + .arg( sensors().at( mBeams - i - 1 )->name() ); + } + + TQToolTip::remove( TQT_TQWIDGET(mPlotter) ); + TQToolTip::add( TQT_TQWIDGET(mPlotter), tooltip ); + + return true; +} + +bool FancyPlotter::removeSensor( uint pos ) +{ + if ( pos >= mBeams ) { + kdDebug(1215) << "FancyPlotter::removeSensor: idx out of range (" + << pos << ")" << endl; + return false; + } + + mPlotter->removeBeam( pos ); + mBeams--; + KSGRD::SensorDisplay::removeSensor( pos ); + + TQString tooltip; + for ( uint i = 0; i < mBeams; ++i ) { + tooltip += TQString( "%1%2:%3" ).arg( i != 0 ? "\n" : "" ) + .arg( sensors().at( mBeams - i - 1 )->hostName() ) + .arg( sensors().at( mBeams - i - 1 )->name() ); + } + + TQToolTip::remove( TQT_TQWIDGET(mPlotter) ); + TQToolTip::add( TQT_TQWIDGET(mPlotter), tooltip ); + + return true; +} + +void FancyPlotter::resizeEvent( TQResizeEvent* ) +{ + if ( noFrame() ) + mPlotter->setGeometry( 0, 0, width(), height() ); + else + frame()->setGeometry( 0, 0, width(), height() ); +} + +TQSize FancyPlotter::sizeHint() +{ + if ( noFrame() ) + return mPlotter->sizeHint(); + else + return frame()->sizeHint(); +} + +void FancyPlotter::answerReceived( int id, const TQString &answer ) +{ + if ( (uint)id < mBeams ) { + if ( id != (int)mSampleBuf.count() ) { + if ( id == 0 ) + sensorError( mBeams - 1, true ); + else + sensorError( id - 1, true ); + } + mSampleBuf.append( answer.toDouble() ); + + /* We received something, so the sensor is probably ok. */ + sensorError( id, false ); + + if ( id == (int)mBeams - 1 ) { + mPlotter->addSample( mSampleBuf ); + mSampleBuf.clear(); + } + } else if ( id >= 100 ) { + KSGRD::SensorFloatInfo info( answer ); + if ( !mPlotter->useAutoRange() && mPlotter->minValue() == 0.0 && + mPlotter->maxValue() == 0.0 ) { + /* We only use this information from the sensor when the + * display is still using the default values. If the + * sensor has been restored we don't touch the already set + * values. */ + mPlotter->changeRange( id - 100, info.min(), info.max() ); + if ( info.min() == 0.0 && info.max() == 0.0 ) + mPlotter->setUseAutoRange( true ); + } + sensors().at( id - 100 )->setUnit( info.unit() ); + } +} + +bool FancyPlotter::restoreSettings( TQDomElement &element ) +{ + /* autoRage was added after KDE 2.x and was brokenly emulated by + * min == 0.0 and max == 0.0. Since we have to be able to read old + * files as well we have to emulate the old behaviour as well. */ + double min = element.attribute( "min", "0.0" ).toDouble(); + double max = element.attribute( "max", "0.0" ).toDouble(); + if ( element.attribute( "autoRange", min == 0.0 && max == 0.0 ? "1" : "0" ).toInt() ) + mPlotter->setUseAutoRange( true ); + else { + mPlotter->setUseAutoRange( false ); + mPlotter->changeRange( 0, element.attribute( "min" ).toDouble(), + element.attribute( "max" ).toDouble() ); + } + + mPlotter->setShowVerticalLines( element.attribute( "vLines", "1" ).toUInt() ); + mPlotter->setVerticalLinesColor( restoreColor( element, "vColor", + KSGRD::Style->firstForegroundColor() ) ); + mPlotter->setVerticalLinesDistance( element.attribute( "vDistance", "30" ).toUInt() ); + mPlotter->setVerticalLinesScroll( element.attribute( "vScroll", "1" ).toUInt() ); + mPlotter->setGraphStyle( element.attribute( "graphStyle", "0" ).toUInt() ); + mPlotter->setHorizontalScale( element.attribute( "hScale", "1" ).toUInt() ); + + mPlotter->setShowHorizontalLines( element.attribute( "hLines", "1" ).toUInt() ); + mPlotter->setHorizontalLinesColor( restoreColor( element, "hColor", + KSGRD::Style->secondForegroundColor() ) ); + mPlotter->setHorizontalLinesCount( element.attribute( "hCount", "5" ).toUInt() ); + + mPlotter->setShowLabels( element.attribute( "labels", "1" ).toUInt() ); + mPlotter->setShowTopBar( element.attribute( "topBar", "0" ).toUInt() ); + mPlotter->setFontSize( element.attribute( "fontSize", + TQString( "%1" ).arg( KSGRD::Style->fontSize() ) ).toUInt() ); + + mPlotter->setBackgroundColor( restoreColor( element, "bColor", + KSGRD::Style->backgroundColor() ) ); + + TQDomNodeList dnList = element.elementsByTagName( "beam" ); + for ( uint i = 0; i < dnList.count(); ++i ) { + TQDomElement el = dnList.item( i ).toElement(); + addSensor( el.attribute( "hostName" ), el.attribute( "sensorName" ), + ( el.attribute( "sensorType" ).isEmpty() ? "integer" : + el.attribute( "sensorType" ) ), "", restoreColor( el, "color", + KSGRD::Style->sensorColor( i ) ) ); + } + + SensorDisplay::restoreSettings( element ); + + if ( !title().isEmpty() ) + mPlotter->setTitle( title() ); + + setModified( false ); + + return true; +} + +bool FancyPlotter::saveSettings( TQDomDocument &doc, TQDomElement &element, + bool save ) +{ + element.setAttribute( "min", mPlotter->minValue() ); + element.setAttribute( "max", mPlotter->maxValue() ); + element.setAttribute( "autoRange", mPlotter->useAutoRange() ); + element.setAttribute( "vLines", mPlotter->showVerticalLines() ); + saveColor( element, "vColor", mPlotter->verticalLinesColor() ); + element.setAttribute( "vDistance", mPlotter->verticalLinesDistance() ); + element.setAttribute( "vScroll", mPlotter->verticalLinesScroll() ); + + element.setAttribute( "graphStyle", mPlotter->graphStyle() ); + element.setAttribute( "hScale", mPlotter->horizontalScale() ); + + element.setAttribute( "hLines", mPlotter->showHorizontalLines() ); + saveColor( element, "hColor", mPlotter->horizontalLinesColor() ); + element.setAttribute( "hCount", mPlotter->horizontalLinesCount() ); + + element.setAttribute( "labels", mPlotter->showLabels() ); + element.setAttribute( "topBar", mPlotter->showTopBar() ); + element.setAttribute( "fontSize", mPlotter->fontSize() ); + + saveColor( element, "bColor", mPlotter->backgroundColor() ); + + for ( uint i = 0; i < mBeams; ++i ) { + TQDomElement beam = doc.createElement( "beam" ); + element.appendChild( beam ); + beam.setAttribute( "hostName", sensors().at( i )->hostName() ); + beam.setAttribute( "sensorName", sensors().at( i )->name() ); + beam.setAttribute( "sensorType", sensors().at( i )->type() ); + saveColor( beam, "color", mPlotter->beamColors()[ i ] ); + } + + SensorDisplay::saveSettings( doc, element ); + + if ( save ) + setModified( false ); + + return true; +} + +bool FancyPlotter::hasSettingsDialog() const +{ + return true; +} + + + +FPSensorProperties::FPSensorProperties() +{ +} + +FPSensorProperties::FPSensorProperties( const TQString &hostName, + const TQString &name, + const TQString &type, + const TQString &description, + const TQColor &color ) + : KSGRD::SensorProperties( hostName, name, type, description ), + mColor( color ) +{ +} + +FPSensorProperties::~FPSensorProperties() +{ +} + +void FPSensorProperties::setColor( const TQColor &color ) +{ + mColor = color; +} + +TQColor FPSensorProperties::color() const +{ + return mColor; +} + +#include "FancyPlotter.moc" diff --git a/ksysguard/gui/SensorDisplayLib/FancyPlotterSettings.cc b/ksysguard/gui/SensorDisplayLib/FancyPlotterSettings.cc deleted file mode 100644 index ef53bab75..000000000 --- a/ksysguard/gui/SensorDisplayLib/FancyPlotterSettings.cc +++ /dev/null @@ -1,637 +0,0 @@ -/* - KSysGuard, the KDE System Guard - - Copyright (c) 2003 Tobias Koenig - - This program is free software; you can redistribute it and/or - modify it under the terms of version 2 of the GNU General Public - License as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - KSysGuard is currently maintained by Chris Schlaeger . - Please do not commit any changes without consulting me first. Thanks! - -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "FancyPlotterSettings.h" - -FancyPlotterSettings::FancyPlotterSettings( TQWidget* parent, const char* name ) - : KDialogBase( Tabbed, i18n( "Signal Plotter Settings" ), Ok | Apply | Cancel, - Ok, parent, name, false, true ) -{ - TQFrame *page = 0; - TQGridLayout *pageLayout = 0; - TQGridLayout *boxLayout = 0; - TQGroupBox *groupBox = 0; - TQLabel *label = 0; - - // Style page - page = addPage( i18n( "Style" ) ); - pageLayout = new TQGridLayout( page, 3, 2, 0, spacingHint() ); - - label = new TQLabel( i18n( "Title:" ), page ); - pageLayout->addWidget( label, 0, 0 ); - - mTitle = new KLineEdit( page ); - TQWhatsThis::add( mTitle, i18n( "Enter the title of the display here." ) ); - pageLayout->addWidget( mTitle, 0, 1 ); - label->setBuddy( mTitle ); - - TQButtonGroup *buttonBox = new TQButtonGroup( 2, Qt::Vertical, - i18n( "Graph Drawing Style" ), page ); - - mUsePolygonStyle = new TQRadioButton( i18n( "Basic polygons" ), buttonBox ); - mUsePolygonStyle->setChecked( true ); - mUseOriginalStyle = new TQRadioButton( i18n( "Original - single line per data point" ), buttonBox ); - - pageLayout->addMultiCellWidget( buttonBox, 1, 1, 0, 1 ); - - // Scales page - page = addPage( i18n( "Scales" ) ); - pageLayout = new TQGridLayout( page, 2, 1, 0, spacingHint() ); - - groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Vertical Scale" ), page ); - boxLayout = new TQGridLayout( groupBox->layout(), 2, 5, spacingHint() ); - boxLayout->setColStretch( 2, 1 ); - - mUseAutoRange = new TQCheckBox( i18n( "Automatic range detection" ), groupBox ); - TQWhatsThis::add( mUseAutoRange, i18n( "Check this box if you want the display range to adapt dynamically to the currently displayed values; if you do not check this, you have to specify the range you want in the fields below." ) ); - boxLayout->addMultiCellWidget( mUseAutoRange, 0, 0, 0, 4 ); - - label = new TQLabel( i18n( "Minimum value:" ), groupBox ); - boxLayout->addWidget( label, 1, 0 ); - - mMinValue = new KLineEdit( groupBox ); - mMinValue->setAlignment( AlignRight ); - mMinValue->setEnabled( false ); - TQWhatsThis::add( mMinValue, i18n( "Enter the minimum value for the display here. If both values are 0, automatic range detection is enabled." ) ); - boxLayout->addWidget( mMinValue, 1, 1 ); - label->setBuddy( mMinValue ); - - label = new TQLabel( i18n( "Maximum value:" ), groupBox ); - boxLayout->addWidget( label, 1, 3 ); - - mMaxValue = new KLineEdit( groupBox ); - mMaxValue->setAlignment( AlignRight ); - mMaxValue->setEnabled( false ); - TQWhatsThis::add( mMaxValue, i18n( "Enter the maximum value for the display here. If both values are 0, automatic range detection is enabled." ) ); - boxLayout->addWidget( mMaxValue, 1, 4 ); - label->setBuddy( mMaxValue ); - - pageLayout->addWidget( groupBox, 0, 0 ); - - groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Horizontal Scale" ), page ); - boxLayout = new TQGridLayout( groupBox->layout(), 2, 2, spacingHint() ); - boxLayout->setRowStretch( 1, 1 ); - - mHorizontalScale = new KIntNumInput( 1, groupBox ); - mHorizontalScale->setMinValue( 1 ); - mHorizontalScale->setMaxValue( 50 ); - boxLayout->addWidget( mHorizontalScale, 0, 0 ); - - label = new TQLabel( i18n( "pixel(s) per time period" ), groupBox ); - boxLayout->addWidget( label, 0, 1 ); - - pageLayout->addWidget( groupBox, 1, 0 ); - - // Grid page - page = addPage( i18n( "Grid" ) ); - pageLayout = new TQGridLayout( page, 3, 2, 0, spacingHint() ); - - groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Lines" ), page ); - boxLayout = new TQGridLayout( groupBox->layout(), 2, 5, spacingHint() ); - boxLayout->setColStretch( 1, 1 ); - - mShowVerticalLines = new TQCheckBox( i18n( "Vertical lines" ), groupBox ); - TQWhatsThis::add( mShowVerticalLines, i18n( "Check this to activate the vertical lines if display is large enough." ) ); - boxLayout->addWidget( mShowVerticalLines, 0, 0 ); - - label = new TQLabel( i18n( "Distance:" ), groupBox ); - boxLayout->addWidget( label, 0, 2 ); - - mVerticalLinesDistance = new KIntNumInput( 0, groupBox ); - mVerticalLinesDistance->setMinValue( 10 ); - mVerticalLinesDistance->setMaxValue( 120 ); - TQWhatsThis::add( mVerticalLinesDistance, i18n( "Enter the distance between two vertical lines here." ) ); - boxLayout->addWidget( mVerticalLinesDistance , 0, 3 ); - label->setBuddy( mVerticalLinesDistance ); - - mVerticalLinesScroll = new TQCheckBox( i18n( "Vertical lines scroll" ), groupBox ); - boxLayout->addWidget( mVerticalLinesScroll, 0, 4 ); - - mShowHorizontalLines = new TQCheckBox( i18n( "Horizontal lines" ), groupBox ); - TQWhatsThis::add( mShowHorizontalLines, i18n( "Check this to enable horizontal lines if display is large enough." ) ); - boxLayout->addWidget( mShowHorizontalLines, 1, 0 ); - - label = new TQLabel( i18n( "Count:" ), groupBox ); - boxLayout->addWidget( label, 1, 2 ); - - mHorizontalLinesCount = new KIntNumInput( 0, groupBox ); - mHorizontalLinesCount->setMinValue( 1 ); - mHorizontalLinesCount->setMaxValue( 100 ); - TQWhatsThis::add( mHorizontalLinesCount, i18n( "Enter the number of horizontal lines here." ) ); - boxLayout->addWidget( mHorizontalLinesCount , 1, 3 ); - label->setBuddy( mHorizontalLinesCount ); - - boxLayout->setRowStretch( 2, 1 ); - - pageLayout->addMultiCellWidget( groupBox, 0, 0, 0, 1 ); - - groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Text" ), page ); - boxLayout = new TQGridLayout( groupBox->layout(), 3, 4, spacingHint() ); - boxLayout->setColStretch( 1, 1 ); - - mShowLabels = new TQCheckBox( i18n( "Labels" ), groupBox ); - TQWhatsThis::add( mShowLabels, i18n( "Check this box if horizontal lines should be decorated with the values they mark." ) ); - boxLayout->addWidget( mShowLabels, 0, 0 ); - - label = new TQLabel( i18n( "Font size:" ), groupBox ); - boxLayout->addWidget( label, 0, 2 ); - - mFontSize = new KIntNumInput( 9, groupBox ); - mFontSize->setMinValue( 5 ); - mFontSize->setMaxValue( 24 ); - boxLayout->addWidget( mFontSize, 0, 3 ); - label->setBuddy( mFontSize ); - - mShowTopBar = new TQCheckBox( i18n( "Top bar" ), groupBox ); - TQWhatsThis::add( mShowTopBar, i18n( "Check this to active the display title bar. This is probably only useful for applet displays. The bar is only visible if the display is large enough." ) ); - boxLayout->addWidget( mShowTopBar, 1, 0 ); - - boxLayout->setRowStretch( 2, 1 ); - - pageLayout->addWidget( groupBox, 1, 0 ); - - groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Colors" ), page ); - boxLayout = new TQGridLayout( groupBox->layout(), 4, 2, spacingHint() ); - - label = new TQLabel( i18n( "Vertical lines:" ), groupBox ); - boxLayout->addWidget( label, 0, 0 ); - - mVerticalLinesColor = new KColorButton( groupBox ); - boxLayout->addWidget( mVerticalLinesColor, 0, 1 ); - label->setBuddy( mVerticalLinesColor ); - - label = new TQLabel( i18n( "Horizontal lines:" ), groupBox ); - boxLayout->addWidget( label, 1, 0 ); - - mHorizontalLinesColor = new KColorButton( groupBox ); - boxLayout->addWidget( mHorizontalLinesColor, 1, 1 ); - label->setBuddy( mHorizontalLinesColor ); - - label = new TQLabel( i18n( "Background:" ), groupBox ); - boxLayout->addWidget( label, 2, 0 ); - - mBackgroundColor = new KColorButton( groupBox ); - boxLayout->addWidget( mBackgroundColor, 2, 1 ); - label->setBuddy( mBackgroundColor ); - - boxLayout->setRowStretch( 3, 1 ); - - pageLayout->addWidget( groupBox, 1, 1 ); - - pageLayout->setRowStretch( 2, 1 ); - - // Sensors page - page = addPage( i18n( "Sensors" ) ); - pageLayout = new TQGridLayout( page, 6, 2, 0, spacingHint() ); - pageLayout->setRowStretch( 2, 1 ); - pageLayout->setRowStretch( 5, 1 ); - - mSensorView = new TDEListView( page ); - mSensorView->addColumn("" , 0); - mSensorView->addColumn( i18n( "Host" ) ); - mSensorView->addColumn( i18n( "Sensor" ) ); - mSensorView->addColumn( i18n( "Unit" ) ); - mSensorView->addColumn( i18n( "Status" ) ); - mSensorView->setResizeMode(TQListView::LastColumn); - mSensorView->header()->setResizeEnabled(false, 0); - mSensorView->hideColumn(0); - mSensorView->header()->resizeSection(0, 0); - mSensorView->setAllColumnsShowFocus( true ); - pageLayout->addMultiCellWidget( mSensorView, 0, 5, 0, 0 ); - mSensorView->setSortColumn ( -1 ); - mEditButton = new TQPushButton( i18n( "Set Color..." ), page ); - mEditButton->setEnabled( false ); - TQWhatsThis::add( mEditButton, i18n( "Push this button to configure the color of the sensor in the diagram." ) ); - pageLayout->addWidget( mEditButton, 0, 1 ); - - mRemoveButton = new TQPushButton( i18n( "Delete" ), page ); - mRemoveButton->setEnabled( false ); - TQWhatsThis::add( mRemoveButton, i18n( "Push this button to delete the sensor." ) ); - pageLayout->addWidget( mRemoveButton, 1, 1 ); - - mMoveUpButton = new TQPushButton( i18n( "Move Up" ), page ); - mMoveUpButton->setEnabled( false ); - pageLayout->addWidget( mMoveUpButton, 3, 1 ); - - mMoveDownButton = new TQPushButton( i18n( "Move Down" ), page ); - mMoveDownButton->setEnabled( false ); - pageLayout->addWidget( mMoveDownButton, 4, 1 ); - - connect( mUseAutoRange, TQT_SIGNAL( toggled( bool ) ), mMinValue, - TQT_SLOT( setDisabled( bool ) ) ); - connect( mUseAutoRange, TQT_SIGNAL( toggled( bool ) ), mMaxValue, - TQT_SLOT( setDisabled( bool ) ) ); - connect( mShowVerticalLines, TQT_SIGNAL( toggled( bool ) ), mVerticalLinesDistance, - TQT_SLOT( setEnabled( bool ) ) ); - connect( mShowVerticalLines, TQT_SIGNAL( toggled( bool ) ), mVerticalLinesScroll, - TQT_SLOT( setEnabled( bool ) ) ); - connect( mShowVerticalLines, TQT_SIGNAL( toggled( bool ) ), mVerticalLinesColor, - TQT_SLOT( setEnabled( bool ) ) ); - connect( mShowHorizontalLines, TQT_SIGNAL( toggled( bool ) ), mHorizontalLinesCount, - TQT_SLOT( setEnabled( bool ) ) ); - connect( mShowHorizontalLines, TQT_SIGNAL( toggled( bool ) ), mHorizontalLinesColor, - TQT_SLOT( setEnabled( bool ) ) ); - connect( mShowHorizontalLines, TQT_SIGNAL( toggled( bool ) ), mShowLabels, - TQT_SLOT( setEnabled( bool ) ) ); - connect( mSensorView, TQT_SIGNAL( selectionChanged( TQListViewItem* ) ), - TQT_SLOT( selectionChanged( TQListViewItem* ) ) ); - - connect( mEditButton, TQT_SIGNAL( clicked() ), TQT_SLOT( editSensor() ) ); - connect( mRemoveButton, TQT_SIGNAL( clicked() ), TQT_SLOT( removeSensor() ) ); - connect( mMoveUpButton, TQT_SIGNAL( clicked() ), TQT_SLOT( moveUpSensor() ) ); - connect( mMoveDownButton, TQT_SIGNAL( clicked() ), TQT_SLOT( moveDownSensor() ) ); - connect ( mSensorView, TQT_SIGNAL( doubleClicked( TQListViewItem *, const TQPoint &, int )), TQT_SLOT(editSensor())); - - TDEAcceleratorManager::manage( this ); -} - -FancyPlotterSettings::~FancyPlotterSettings() -{ -} - -void FancyPlotterSettings::setTitle( const TQString &title ) -{ - mTitle->setText( title ); -} - -TQString FancyPlotterSettings::title() const -{ - return mTitle->text(); -} - -void FancyPlotterSettings::setUseAutoRange( bool value ) -{ - mUseAutoRange->setChecked( value ); - mMinValue->setEnabled( !value ); - mMaxValue->setEnabled( !value ); -} - -bool FancyPlotterSettings::useAutoRange() const -{ - return mUseAutoRange->isChecked(); -} - -void FancyPlotterSettings::setMinValue( double min ) -{ - mMinValue->setText( TQString::number( min ) ); -} - -double FancyPlotterSettings::minValue() const -{ - return mMinValue->text().toDouble(); -} - -void FancyPlotterSettings::setMaxValue( double max ) -{ - mMaxValue->setText( TQString::number( max ) ); -} - -double FancyPlotterSettings::maxValue() const -{ - return mMaxValue->text().toDouble(); -} - -void FancyPlotterSettings::setUsePolygonStyle( bool value ) -{ - if ( value ) - mUsePolygonStyle->setChecked( true ); - else - mUseOriginalStyle->setChecked( true ); -} - -bool FancyPlotterSettings::usePolygonStyle() const -{ - return mUsePolygonStyle->isChecked(); -} - -void FancyPlotterSettings::setHorizontalScale( int scale ) -{ - mHorizontalScale->setValue( scale ); -} - -int FancyPlotterSettings::horizontalScale() const -{ - return mHorizontalScale->value(); -} - -void FancyPlotterSettings::setShowVerticalLines( bool value ) -{ - mShowVerticalLines->setChecked( value ); - mVerticalLinesDistance->setEnabled( value ); - mVerticalLinesScroll->setEnabled( value ); - mVerticalLinesColor->setEnabled( value ); -} - -bool FancyPlotterSettings::showVerticalLines() const -{ - return mShowVerticalLines->isChecked(); -} - -void FancyPlotterSettings::setVerticalLinesColor( const TQColor &color ) -{ - mVerticalLinesColor->setColor( color ); -} - -TQColor FancyPlotterSettings::verticalLinesColor() const -{ - return mVerticalLinesColor->color(); -} - -void FancyPlotterSettings::setVerticalLinesDistance( int distance ) -{ - mVerticalLinesDistance->setValue( distance ); -} - -int FancyPlotterSettings::verticalLinesDistance() const -{ - return mVerticalLinesDistance->value(); -} - -void FancyPlotterSettings::setVerticalLinesScroll( bool value ) -{ - mVerticalLinesScroll->setChecked( value ); -} - -bool FancyPlotterSettings::verticalLinesScroll() const -{ - return mVerticalLinesScroll->isChecked(); -} - -void FancyPlotterSettings::setShowHorizontalLines( bool value ) -{ - mShowHorizontalLines->setChecked( value ); - mHorizontalLinesCount->setEnabled( value ); - mHorizontalLinesColor->setEnabled( value ); - mShowLabels->setEnabled( value ); - -} - -bool FancyPlotterSettings::showHorizontalLines() const -{ - return mShowHorizontalLines->isChecked(); -} - -void FancyPlotterSettings::setHorizontalLinesColor( const TQColor &color ) -{ - mHorizontalLinesColor->setColor( color ); -} - -TQColor FancyPlotterSettings::horizontalLinesColor() const -{ - return mHorizontalLinesColor->color(); -} - -void FancyPlotterSettings::setHorizontalLinesCount( int count ) -{ - mHorizontalLinesCount->setValue( count ); -} - -int FancyPlotterSettings::horizontalLinesCount() const -{ - return mHorizontalLinesCount->value(); -} - -void FancyPlotterSettings::setShowLabels( bool value ) -{ - mShowLabels->setChecked( value ); -} - -bool FancyPlotterSettings::showLabels() const -{ - return mShowLabels->isChecked(); -} - -void FancyPlotterSettings::setShowTopBar( bool value ) -{ - mShowTopBar->setChecked( value ); -} - -bool FancyPlotterSettings::showTopBar() const -{ - return mShowTopBar->isChecked(); -} - -void FancyPlotterSettings::setFontSize( int size ) -{ - mFontSize->setValue( size ); -} - -int FancyPlotterSettings::fontSize() const -{ - return mFontSize->value(); -} - -void FancyPlotterSettings::setBackgroundColor( const TQColor &color ) -{ - mBackgroundColor->setColor( color ); -} - -TQColor FancyPlotterSettings::backgroundColor() const -{ - return mBackgroundColor->color(); -} -void FancyPlotterSettings::clearDeleted() -{ - mDeleted.clear(); -} -TQValueList FancyPlotterSettings::deleted() const -{ - return mDeleted; -} - -TQValueList FancyPlotterSettings::order() const -{ - TQValueList newOrder; - - TQListViewItemIterator it( mSensorView ); - for ( ; it.current(); ++it ) { - newOrder.prepend(it.current()->text(0).toInt()); - } - return newOrder; -} - -void FancyPlotterSettings::resetOrder() -{ - int i = mSensorView->childCount()-1; - TQListViewItemIterator it( mSensorView ); - for ( ; it.current(); ++it, --i) { - it.current()->setText(0, TQString::number(i)); - } -} - -void FancyPlotterSettings::setSensors( const TQValueList< TQStringList > &list ) -{ - mSensorView->clear(); - - TQValueList< TQStringList >::ConstIterator it; - for ( it = list.begin(); it != list.end(); ++it ) { - TQListViewItem* lvi = new TQListViewItem( mSensorView, - (*it)[ 0 ], // id - (*it)[ 1 ], // host name - (*it)[ 2 ], // sensor name - (*it)[ 3 ], // unit - (*it)[ 4 ] ); // status - TQPixmap pm( 12, 12 ); - pm.fill( TQColor( (*it)[ 5 ] ) ); - lvi->setPixmap( 2, pm ); - mSensorView->insertItem( lvi ); - } -} - -TQValueList< TQStringList > FancyPlotterSettings::sensors() const -{ - TQValueList< TQStringList > list; - - TQListViewItemIterator it( mSensorView ); - - for ( ; it.current(); ++it ) { - TQStringList entry; - entry << it.current()->text( 0 ); - entry << it.current()->text( 1 ); - entry << it.current()->text( 2 ); - entry << it.current()->text( 3 ); - entry << it.current()->text( 4 ); - QRgb rgb = it.current()->pixmap( 2 )->convertToImage().pixel( 1, 1 ); - TQColor color( tqRed( rgb ), tqGreen( rgb ), tqBlue( rgb ) ); - entry << ( color.name() ); - - list.prepend( entry ); - } - - return list; -} - -void FancyPlotterSettings::editSensor() -{ - TQListViewItem* lvi = mSensorView->currentItem(); - - if ( !lvi ) - return; - - TQColor color = lvi->pixmap( 2 )->convertToImage().pixel( 1, 1 ); - int result = KColorDialog::getColor( color, parentWidget() ); - if ( result == KColorDialog::Accepted ) { - TQPixmap newPm( 12, 12 ); - newPm.fill( color ); - lvi->setPixmap( 2, newPm ); - } -} - -void FancyPlotterSettings::removeSensor() -{ - TQListViewItem* lvi = mSensorView->currentItem(); - - if ( lvi ) { - //Note down the id of the one we are deleting - int id = lvi->text(0).toInt(); - mDeleted.append(id); - - /* Before we delete the currently selected item, we determine a - * new item to be selected. That way we can ensure that multiple - * items can be deleted without forcing the user to select a new - * item between the deletes. If all items are deleted, the buttons - * are disabled again. */ - TQListViewItem* newSelected = 0; - if ( lvi->itemBelow() ) { - lvi->itemBelow()->setSelected( true ); - newSelected = lvi->itemBelow(); - } else if ( lvi->itemAbove() ) { - lvi->itemAbove()->setSelected( true ); - newSelected = lvi->itemAbove(); - } else - selectionChanged( 0 ); - - delete lvi; - - TQListViewItemIterator it( mSensorView ); - for ( ; it.current(); ++it ) { - if(it.current()->text(0).toInt() > id) - it.current()->setText(0, TQString::number(it.current()->text(0).toInt() -1)); - } - - - if ( newSelected ) - mSensorView->ensureItemVisible( newSelected ); - } -} - -void FancyPlotterSettings::moveUpSensor() -{ - if ( mSensorView->currentItem() != 0 ) { - TQListViewItem* item = mSensorView->currentItem()->itemAbove(); - if ( item ) { - if ( item->itemAbove() ) - { - mSensorView->currentItem()->moveItem( item->itemAbove() ); - } - else - { - item->moveItem( mSensorView->currentItem() ); - } - } - - selectionChanged( mSensorView->currentItem() ); - } -} - -void FancyPlotterSettings::moveDownSensor() -{ - if ( mSensorView->currentItem() != 0 ) { - if ( mSensorView->currentItem()->itemBelow() ) - mSensorView->currentItem()->moveItem( mSensorView->currentItem()->itemBelow() ); - - selectionChanged( mSensorView->currentItem() ); - } -} - -void FancyPlotterSettings::selectionChanged( TQListViewItem *item ) -{ - bool state = ( item != 0 ); - - mEditButton->setEnabled( state ); - mRemoveButton->setEnabled( state ); - mMoveUpButton->setEnabled( state && item->itemAbove() ); - mMoveDownButton->setEnabled( state && item->itemBelow() ); -} - -#include "FancyPlotterSettings.moc" diff --git a/ksysguard/gui/SensorDisplayLib/FancyPlotterSettings.cpp b/ksysguard/gui/SensorDisplayLib/FancyPlotterSettings.cpp new file mode 100644 index 000000000..ef53bab75 --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/FancyPlotterSettings.cpp @@ -0,0 +1,637 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 2003 Tobias Koenig + + This program is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + KSysGuard is currently maintained by Chris Schlaeger . + Please do not commit any changes without consulting me first. Thanks! + +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "FancyPlotterSettings.h" + +FancyPlotterSettings::FancyPlotterSettings( TQWidget* parent, const char* name ) + : KDialogBase( Tabbed, i18n( "Signal Plotter Settings" ), Ok | Apply | Cancel, + Ok, parent, name, false, true ) +{ + TQFrame *page = 0; + TQGridLayout *pageLayout = 0; + TQGridLayout *boxLayout = 0; + TQGroupBox *groupBox = 0; + TQLabel *label = 0; + + // Style page + page = addPage( i18n( "Style" ) ); + pageLayout = new TQGridLayout( page, 3, 2, 0, spacingHint() ); + + label = new TQLabel( i18n( "Title:" ), page ); + pageLayout->addWidget( label, 0, 0 ); + + mTitle = new KLineEdit( page ); + TQWhatsThis::add( mTitle, i18n( "Enter the title of the display here." ) ); + pageLayout->addWidget( mTitle, 0, 1 ); + label->setBuddy( mTitle ); + + TQButtonGroup *buttonBox = new TQButtonGroup( 2, Qt::Vertical, + i18n( "Graph Drawing Style" ), page ); + + mUsePolygonStyle = new TQRadioButton( i18n( "Basic polygons" ), buttonBox ); + mUsePolygonStyle->setChecked( true ); + mUseOriginalStyle = new TQRadioButton( i18n( "Original - single line per data point" ), buttonBox ); + + pageLayout->addMultiCellWidget( buttonBox, 1, 1, 0, 1 ); + + // Scales page + page = addPage( i18n( "Scales" ) ); + pageLayout = new TQGridLayout( page, 2, 1, 0, spacingHint() ); + + groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Vertical Scale" ), page ); + boxLayout = new TQGridLayout( groupBox->layout(), 2, 5, spacingHint() ); + boxLayout->setColStretch( 2, 1 ); + + mUseAutoRange = new TQCheckBox( i18n( "Automatic range detection" ), groupBox ); + TQWhatsThis::add( mUseAutoRange, i18n( "Check this box if you want the display range to adapt dynamically to the currently displayed values; if you do not check this, you have to specify the range you want in the fields below." ) ); + boxLayout->addMultiCellWidget( mUseAutoRange, 0, 0, 0, 4 ); + + label = new TQLabel( i18n( "Minimum value:" ), groupBox ); + boxLayout->addWidget( label, 1, 0 ); + + mMinValue = new KLineEdit( groupBox ); + mMinValue->setAlignment( AlignRight ); + mMinValue->setEnabled( false ); + TQWhatsThis::add( mMinValue, i18n( "Enter the minimum value for the display here. If both values are 0, automatic range detection is enabled." ) ); + boxLayout->addWidget( mMinValue, 1, 1 ); + label->setBuddy( mMinValue ); + + label = new TQLabel( i18n( "Maximum value:" ), groupBox ); + boxLayout->addWidget( label, 1, 3 ); + + mMaxValue = new KLineEdit( groupBox ); + mMaxValue->setAlignment( AlignRight ); + mMaxValue->setEnabled( false ); + TQWhatsThis::add( mMaxValue, i18n( "Enter the maximum value for the display here. If both values are 0, automatic range detection is enabled." ) ); + boxLayout->addWidget( mMaxValue, 1, 4 ); + label->setBuddy( mMaxValue ); + + pageLayout->addWidget( groupBox, 0, 0 ); + + groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Horizontal Scale" ), page ); + boxLayout = new TQGridLayout( groupBox->layout(), 2, 2, spacingHint() ); + boxLayout->setRowStretch( 1, 1 ); + + mHorizontalScale = new KIntNumInput( 1, groupBox ); + mHorizontalScale->setMinValue( 1 ); + mHorizontalScale->setMaxValue( 50 ); + boxLayout->addWidget( mHorizontalScale, 0, 0 ); + + label = new TQLabel( i18n( "pixel(s) per time period" ), groupBox ); + boxLayout->addWidget( label, 0, 1 ); + + pageLayout->addWidget( groupBox, 1, 0 ); + + // Grid page + page = addPage( i18n( "Grid" ) ); + pageLayout = new TQGridLayout( page, 3, 2, 0, spacingHint() ); + + groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Lines" ), page ); + boxLayout = new TQGridLayout( groupBox->layout(), 2, 5, spacingHint() ); + boxLayout->setColStretch( 1, 1 ); + + mShowVerticalLines = new TQCheckBox( i18n( "Vertical lines" ), groupBox ); + TQWhatsThis::add( mShowVerticalLines, i18n( "Check this to activate the vertical lines if display is large enough." ) ); + boxLayout->addWidget( mShowVerticalLines, 0, 0 ); + + label = new TQLabel( i18n( "Distance:" ), groupBox ); + boxLayout->addWidget( label, 0, 2 ); + + mVerticalLinesDistance = new KIntNumInput( 0, groupBox ); + mVerticalLinesDistance->setMinValue( 10 ); + mVerticalLinesDistance->setMaxValue( 120 ); + TQWhatsThis::add( mVerticalLinesDistance, i18n( "Enter the distance between two vertical lines here." ) ); + boxLayout->addWidget( mVerticalLinesDistance , 0, 3 ); + label->setBuddy( mVerticalLinesDistance ); + + mVerticalLinesScroll = new TQCheckBox( i18n( "Vertical lines scroll" ), groupBox ); + boxLayout->addWidget( mVerticalLinesScroll, 0, 4 ); + + mShowHorizontalLines = new TQCheckBox( i18n( "Horizontal lines" ), groupBox ); + TQWhatsThis::add( mShowHorizontalLines, i18n( "Check this to enable horizontal lines if display is large enough." ) ); + boxLayout->addWidget( mShowHorizontalLines, 1, 0 ); + + label = new TQLabel( i18n( "Count:" ), groupBox ); + boxLayout->addWidget( label, 1, 2 ); + + mHorizontalLinesCount = new KIntNumInput( 0, groupBox ); + mHorizontalLinesCount->setMinValue( 1 ); + mHorizontalLinesCount->setMaxValue( 100 ); + TQWhatsThis::add( mHorizontalLinesCount, i18n( "Enter the number of horizontal lines here." ) ); + boxLayout->addWidget( mHorizontalLinesCount , 1, 3 ); + label->setBuddy( mHorizontalLinesCount ); + + boxLayout->setRowStretch( 2, 1 ); + + pageLayout->addMultiCellWidget( groupBox, 0, 0, 0, 1 ); + + groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Text" ), page ); + boxLayout = new TQGridLayout( groupBox->layout(), 3, 4, spacingHint() ); + boxLayout->setColStretch( 1, 1 ); + + mShowLabels = new TQCheckBox( i18n( "Labels" ), groupBox ); + TQWhatsThis::add( mShowLabels, i18n( "Check this box if horizontal lines should be decorated with the values they mark." ) ); + boxLayout->addWidget( mShowLabels, 0, 0 ); + + label = new TQLabel( i18n( "Font size:" ), groupBox ); + boxLayout->addWidget( label, 0, 2 ); + + mFontSize = new KIntNumInput( 9, groupBox ); + mFontSize->setMinValue( 5 ); + mFontSize->setMaxValue( 24 ); + boxLayout->addWidget( mFontSize, 0, 3 ); + label->setBuddy( mFontSize ); + + mShowTopBar = new TQCheckBox( i18n( "Top bar" ), groupBox ); + TQWhatsThis::add( mShowTopBar, i18n( "Check this to active the display title bar. This is probably only useful for applet displays. The bar is only visible if the display is large enough." ) ); + boxLayout->addWidget( mShowTopBar, 1, 0 ); + + boxLayout->setRowStretch( 2, 1 ); + + pageLayout->addWidget( groupBox, 1, 0 ); + + groupBox = new TQGroupBox( 0, Qt::Vertical, i18n( "Colors" ), page ); + boxLayout = new TQGridLayout( groupBox->layout(), 4, 2, spacingHint() ); + + label = new TQLabel( i18n( "Vertical lines:" ), groupBox ); + boxLayout->addWidget( label, 0, 0 ); + + mVerticalLinesColor = new KColorButton( groupBox ); + boxLayout->addWidget( mVerticalLinesColor, 0, 1 ); + label->setBuddy( mVerticalLinesColor ); + + label = new TQLabel( i18n( "Horizontal lines:" ), groupBox ); + boxLayout->addWidget( label, 1, 0 ); + + mHorizontalLinesColor = new KColorButton( groupBox ); + boxLayout->addWidget( mHorizontalLinesColor, 1, 1 ); + label->setBuddy( mHorizontalLinesColor ); + + label = new TQLabel( i18n( "Background:" ), groupBox ); + boxLayout->addWidget( label, 2, 0 ); + + mBackgroundColor = new KColorButton( groupBox ); + boxLayout->addWidget( mBackgroundColor, 2, 1 ); + label->setBuddy( mBackgroundColor ); + + boxLayout->setRowStretch( 3, 1 ); + + pageLayout->addWidget( groupBox, 1, 1 ); + + pageLayout->setRowStretch( 2, 1 ); + + // Sensors page + page = addPage( i18n( "Sensors" ) ); + pageLayout = new TQGridLayout( page, 6, 2, 0, spacingHint() ); + pageLayout->setRowStretch( 2, 1 ); + pageLayout->setRowStretch( 5, 1 ); + + mSensorView = new TDEListView( page ); + mSensorView->addColumn("" , 0); + mSensorView->addColumn( i18n( "Host" ) ); + mSensorView->addColumn( i18n( "Sensor" ) ); + mSensorView->addColumn( i18n( "Unit" ) ); + mSensorView->addColumn( i18n( "Status" ) ); + mSensorView->setResizeMode(TQListView::LastColumn); + mSensorView->header()->setResizeEnabled(false, 0); + mSensorView->hideColumn(0); + mSensorView->header()->resizeSection(0, 0); + mSensorView->setAllColumnsShowFocus( true ); + pageLayout->addMultiCellWidget( mSensorView, 0, 5, 0, 0 ); + mSensorView->setSortColumn ( -1 ); + mEditButton = new TQPushButton( i18n( "Set Color..." ), page ); + mEditButton->setEnabled( false ); + TQWhatsThis::add( mEditButton, i18n( "Push this button to configure the color of the sensor in the diagram." ) ); + pageLayout->addWidget( mEditButton, 0, 1 ); + + mRemoveButton = new TQPushButton( i18n( "Delete" ), page ); + mRemoveButton->setEnabled( false ); + TQWhatsThis::add( mRemoveButton, i18n( "Push this button to delete the sensor." ) ); + pageLayout->addWidget( mRemoveButton, 1, 1 ); + + mMoveUpButton = new TQPushButton( i18n( "Move Up" ), page ); + mMoveUpButton->setEnabled( false ); + pageLayout->addWidget( mMoveUpButton, 3, 1 ); + + mMoveDownButton = new TQPushButton( i18n( "Move Down" ), page ); + mMoveDownButton->setEnabled( false ); + pageLayout->addWidget( mMoveDownButton, 4, 1 ); + + connect( mUseAutoRange, TQT_SIGNAL( toggled( bool ) ), mMinValue, + TQT_SLOT( setDisabled( bool ) ) ); + connect( mUseAutoRange, TQT_SIGNAL( toggled( bool ) ), mMaxValue, + TQT_SLOT( setDisabled( bool ) ) ); + connect( mShowVerticalLines, TQT_SIGNAL( toggled( bool ) ), mVerticalLinesDistance, + TQT_SLOT( setEnabled( bool ) ) ); + connect( mShowVerticalLines, TQT_SIGNAL( toggled( bool ) ), mVerticalLinesScroll, + TQT_SLOT( setEnabled( bool ) ) ); + connect( mShowVerticalLines, TQT_SIGNAL( toggled( bool ) ), mVerticalLinesColor, + TQT_SLOT( setEnabled( bool ) ) ); + connect( mShowHorizontalLines, TQT_SIGNAL( toggled( bool ) ), mHorizontalLinesCount, + TQT_SLOT( setEnabled( bool ) ) ); + connect( mShowHorizontalLines, TQT_SIGNAL( toggled( bool ) ), mHorizontalLinesColor, + TQT_SLOT( setEnabled( bool ) ) ); + connect( mShowHorizontalLines, TQT_SIGNAL( toggled( bool ) ), mShowLabels, + TQT_SLOT( setEnabled( bool ) ) ); + connect( mSensorView, TQT_SIGNAL( selectionChanged( TQListViewItem* ) ), + TQT_SLOT( selectionChanged( TQListViewItem* ) ) ); + + connect( mEditButton, TQT_SIGNAL( clicked() ), TQT_SLOT( editSensor() ) ); + connect( mRemoveButton, TQT_SIGNAL( clicked() ), TQT_SLOT( removeSensor() ) ); + connect( mMoveUpButton, TQT_SIGNAL( clicked() ), TQT_SLOT( moveUpSensor() ) ); + connect( mMoveDownButton, TQT_SIGNAL( clicked() ), TQT_SLOT( moveDownSensor() ) ); + connect ( mSensorView, TQT_SIGNAL( doubleClicked( TQListViewItem *, const TQPoint &, int )), TQT_SLOT(editSensor())); + + TDEAcceleratorManager::manage( this ); +} + +FancyPlotterSettings::~FancyPlotterSettings() +{ +} + +void FancyPlotterSettings::setTitle( const TQString &title ) +{ + mTitle->setText( title ); +} + +TQString FancyPlotterSettings::title() const +{ + return mTitle->text(); +} + +void FancyPlotterSettings::setUseAutoRange( bool value ) +{ + mUseAutoRange->setChecked( value ); + mMinValue->setEnabled( !value ); + mMaxValue->setEnabled( !value ); +} + +bool FancyPlotterSettings::useAutoRange() const +{ + return mUseAutoRange->isChecked(); +} + +void FancyPlotterSettings::setMinValue( double min ) +{ + mMinValue->setText( TQString::number( min ) ); +} + +double FancyPlotterSettings::minValue() const +{ + return mMinValue->text().toDouble(); +} + +void FancyPlotterSettings::setMaxValue( double max ) +{ + mMaxValue->setText( TQString::number( max ) ); +} + +double FancyPlotterSettings::maxValue() const +{ + return mMaxValue->text().toDouble(); +} + +void FancyPlotterSettings::setUsePolygonStyle( bool value ) +{ + if ( value ) + mUsePolygonStyle->setChecked( true ); + else + mUseOriginalStyle->setChecked( true ); +} + +bool FancyPlotterSettings::usePolygonStyle() const +{ + return mUsePolygonStyle->isChecked(); +} + +void FancyPlotterSettings::setHorizontalScale( int scale ) +{ + mHorizontalScale->setValue( scale ); +} + +int FancyPlotterSettings::horizontalScale() const +{ + return mHorizontalScale->value(); +} + +void FancyPlotterSettings::setShowVerticalLines( bool value ) +{ + mShowVerticalLines->setChecked( value ); + mVerticalLinesDistance->setEnabled( value ); + mVerticalLinesScroll->setEnabled( value ); + mVerticalLinesColor->setEnabled( value ); +} + +bool FancyPlotterSettings::showVerticalLines() const +{ + return mShowVerticalLines->isChecked(); +} + +void FancyPlotterSettings::setVerticalLinesColor( const TQColor &color ) +{ + mVerticalLinesColor->setColor( color ); +} + +TQColor FancyPlotterSettings::verticalLinesColor() const +{ + return mVerticalLinesColor->color(); +} + +void FancyPlotterSettings::setVerticalLinesDistance( int distance ) +{ + mVerticalLinesDistance->setValue( distance ); +} + +int FancyPlotterSettings::verticalLinesDistance() const +{ + return mVerticalLinesDistance->value(); +} + +void FancyPlotterSettings::setVerticalLinesScroll( bool value ) +{ + mVerticalLinesScroll->setChecked( value ); +} + +bool FancyPlotterSettings::verticalLinesScroll() const +{ + return mVerticalLinesScroll->isChecked(); +} + +void FancyPlotterSettings::setShowHorizontalLines( bool value ) +{ + mShowHorizontalLines->setChecked( value ); + mHorizontalLinesCount->setEnabled( value ); + mHorizontalLinesColor->setEnabled( value ); + mShowLabels->setEnabled( value ); + +} + +bool FancyPlotterSettings::showHorizontalLines() const +{ + return mShowHorizontalLines->isChecked(); +} + +void FancyPlotterSettings::setHorizontalLinesColor( const TQColor &color ) +{ + mHorizontalLinesColor->setColor( color ); +} + +TQColor FancyPlotterSettings::horizontalLinesColor() const +{ + return mHorizontalLinesColor->color(); +} + +void FancyPlotterSettings::setHorizontalLinesCount( int count ) +{ + mHorizontalLinesCount->setValue( count ); +} + +int FancyPlotterSettings::horizontalLinesCount() const +{ + return mHorizontalLinesCount->value(); +} + +void FancyPlotterSettings::setShowLabels( bool value ) +{ + mShowLabels->setChecked( value ); +} + +bool FancyPlotterSettings::showLabels() const +{ + return mShowLabels->isChecked(); +} + +void FancyPlotterSettings::setShowTopBar( bool value ) +{ + mShowTopBar->setChecked( value ); +} + +bool FancyPlotterSettings::showTopBar() const +{ + return mShowTopBar->isChecked(); +} + +void FancyPlotterSettings::setFontSize( int size ) +{ + mFontSize->setValue( size ); +} + +int FancyPlotterSettings::fontSize() const +{ + return mFontSize->value(); +} + +void FancyPlotterSettings::setBackgroundColor( const TQColor &color ) +{ + mBackgroundColor->setColor( color ); +} + +TQColor FancyPlotterSettings::backgroundColor() const +{ + return mBackgroundColor->color(); +} +void FancyPlotterSettings::clearDeleted() +{ + mDeleted.clear(); +} +TQValueList FancyPlotterSettings::deleted() const +{ + return mDeleted; +} + +TQValueList FancyPlotterSettings::order() const +{ + TQValueList newOrder; + + TQListViewItemIterator it( mSensorView ); + for ( ; it.current(); ++it ) { + newOrder.prepend(it.current()->text(0).toInt()); + } + return newOrder; +} + +void FancyPlotterSettings::resetOrder() +{ + int i = mSensorView->childCount()-1; + TQListViewItemIterator it( mSensorView ); + for ( ; it.current(); ++it, --i) { + it.current()->setText(0, TQString::number(i)); + } +} + +void FancyPlotterSettings::setSensors( const TQValueList< TQStringList > &list ) +{ + mSensorView->clear(); + + TQValueList< TQStringList >::ConstIterator it; + for ( it = list.begin(); it != list.end(); ++it ) { + TQListViewItem* lvi = new TQListViewItem( mSensorView, + (*it)[ 0 ], // id + (*it)[ 1 ], // host name + (*it)[ 2 ], // sensor name + (*it)[ 3 ], // unit + (*it)[ 4 ] ); // status + TQPixmap pm( 12, 12 ); + pm.fill( TQColor( (*it)[ 5 ] ) ); + lvi->setPixmap( 2, pm ); + mSensorView->insertItem( lvi ); + } +} + +TQValueList< TQStringList > FancyPlotterSettings::sensors() const +{ + TQValueList< TQStringList > list; + + TQListViewItemIterator it( mSensorView ); + + for ( ; it.current(); ++it ) { + TQStringList entry; + entry << it.current()->text( 0 ); + entry << it.current()->text( 1 ); + entry << it.current()->text( 2 ); + entry << it.current()->text( 3 ); + entry << it.current()->text( 4 ); + QRgb rgb = it.current()->pixmap( 2 )->convertToImage().pixel( 1, 1 ); + TQColor color( tqRed( rgb ), tqGreen( rgb ), tqBlue( rgb ) ); + entry << ( color.name() ); + + list.prepend( entry ); + } + + return list; +} + +void FancyPlotterSettings::editSensor() +{ + TQListViewItem* lvi = mSensorView->currentItem(); + + if ( !lvi ) + return; + + TQColor color = lvi->pixmap( 2 )->convertToImage().pixel( 1, 1 ); + int result = KColorDialog::getColor( color, parentWidget() ); + if ( result == KColorDialog::Accepted ) { + TQPixmap newPm( 12, 12 ); + newPm.fill( color ); + lvi->setPixmap( 2, newPm ); + } +} + +void FancyPlotterSettings::removeSensor() +{ + TQListViewItem* lvi = mSensorView->currentItem(); + + if ( lvi ) { + //Note down the id of the one we are deleting + int id = lvi->text(0).toInt(); + mDeleted.append(id); + + /* Before we delete the currently selected item, we determine a + * new item to be selected. That way we can ensure that multiple + * items can be deleted without forcing the user to select a new + * item between the deletes. If all items are deleted, the buttons + * are disabled again. */ + TQListViewItem* newSelected = 0; + if ( lvi->itemBelow() ) { + lvi->itemBelow()->setSelected( true ); + newSelected = lvi->itemBelow(); + } else if ( lvi->itemAbove() ) { + lvi->itemAbove()->setSelected( true ); + newSelected = lvi->itemAbove(); + } else + selectionChanged( 0 ); + + delete lvi; + + TQListViewItemIterator it( mSensorView ); + for ( ; it.current(); ++it ) { + if(it.current()->text(0).toInt() > id) + it.current()->setText(0, TQString::number(it.current()->text(0).toInt() -1)); + } + + + if ( newSelected ) + mSensorView->ensureItemVisible( newSelected ); + } +} + +void FancyPlotterSettings::moveUpSensor() +{ + if ( mSensorView->currentItem() != 0 ) { + TQListViewItem* item = mSensorView->currentItem()->itemAbove(); + if ( item ) { + if ( item->itemAbove() ) + { + mSensorView->currentItem()->moveItem( item->itemAbove() ); + } + else + { + item->moveItem( mSensorView->currentItem() ); + } + } + + selectionChanged( mSensorView->currentItem() ); + } +} + +void FancyPlotterSettings::moveDownSensor() +{ + if ( mSensorView->currentItem() != 0 ) { + if ( mSensorView->currentItem()->itemBelow() ) + mSensorView->currentItem()->moveItem( mSensorView->currentItem()->itemBelow() ); + + selectionChanged( mSensorView->currentItem() ); + } +} + +void FancyPlotterSettings::selectionChanged( TQListViewItem *item ) +{ + bool state = ( item != 0 ); + + mEditButton->setEnabled( state ); + mRemoveButton->setEnabled( state ); + mMoveUpButton->setEnabled( state && item->itemAbove() ); + mMoveDownButton->setEnabled( state && item->itemBelow() ); +} + +#include "FancyPlotterSettings.moc" diff --git a/ksysguard/gui/SensorDisplayLib/ListView.cc b/ksysguard/gui/SensorDisplayLib/ListView.cc deleted file mode 100644 index 5b748e9c0..000000000 --- a/ksysguard/gui/SensorDisplayLib/ListView.cc +++ /dev/null @@ -1,371 +0,0 @@ -/* - KSysGuard, the KDE System Guard - - Copyright (c) 2001 Tobias Koenig - - This program is free software; you can redistribute it and/or - modify it under the terms of version 2 of the GNU General Public - License as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - KSysGuard is currently maintained by Chris Schlaeger . - Please do not commit any changes without consulting me first. Thanks! - -*/ - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "ListView.h" -#include "ListView.moc" -#include "ListViewSettings.h" - -PrivateListViewItem::PrivateListViewItem(PrivateListView *parent) - : TQListViewItem(parent) -{ - _parent = parent; -} - -int PrivateListViewItem::compare( TQListViewItem *item, int col, bool ascending ) const -{ - int type = ((PrivateListView*)listView())->columnType( col ); - - if ( type == PrivateListView::Int ) { - int prev = (int)TDEGlobal::locale()->readNumber( key( col, ascending ) ); - int next = (int)TDEGlobal::locale()->readNumber( item->key( col, ascending ) ); - if ( prev < next ) - return -1; - else if ( prev == next ) - return 0; - else - return 1; - } else if ( type == PrivateListView::Float ) { - double prev = TDEGlobal::locale()->readNumber( key( col, ascending ) ); - double next = TDEGlobal::locale()->readNumber( item->key( col, ascending ) ); - if ( prev < next ) - return -1; - else - return 1; - } else if ( type == PrivateListView::Time ) { - int hourPrev, hourNext, minutesPrev, minutesNext; - sscanf( key( col, ascending ).latin1(), "%d:%d", &hourPrev, &minutesPrev ); - sscanf( item->key( col, ascending ).latin1(), "%d:%d", &hourNext, &minutesNext ); - int prev = hourPrev * 60 + minutesPrev; - int next = hourNext * 60 + minutesNext; - if ( prev < next ) - return -1; - else if ( prev == next ) - return 0; - else - return 1; - } else if ( type == PrivateListView::DiskStat ) { - TQString prev = key( col, ascending ); - TQString next = item->key( col, ascending ); - TQString prevKey, nextKey; - - uint counter = prev.length(); - for ( uint i = 0; i < counter; ++i ) - if ( prev[ i ].isDigit() ) { - prevKey.sprintf( "%s%016d", prev.left( i ).latin1(), prev.mid( i ).toInt() ); - break; - } - - counter = next.length(); - for ( uint i = 0; i < counter; ++i ) - if ( next[ i ].isDigit() ) { - nextKey.sprintf( "%s%016d", next.left( i ).latin1(), next.mid( i ).toInt() ); - break; - } - - return prevKey.compare( nextKey ); - } else - return key( col, ascending ).localeAwareCompare( item->key( col, ascending ) ); -} - -PrivateListView::PrivateListView(TQWidget *parent, const char *name) - : TQListView(parent, name) -{ - TQColorGroup cg = colorGroup(); - - cg.setColor(TQColorGroup::Link, KSGRD::Style->firstForegroundColor()); - cg.setColor(TQColorGroup::Text, KSGRD::Style->secondForegroundColor()); - cg.setColor(TQColorGroup::Base, KSGRD::Style->backgroundColor()); - - setPalette(TQPalette(cg, cg, cg)); -} - -void PrivateListView::update(const TQString& answer) -{ - setUpdatesEnabled(false); - viewport()->setUpdatesEnabled(false); - - int vpos = verticalScrollBar()->value(); - int hpos = horizontalScrollBar()->value(); - - clear(); - - KSGRD::SensorTokenizer lines(answer, '\n'); - for (uint i = 0; i < lines.count(); i++) { - PrivateListViewItem *item = new PrivateListViewItem(this); - KSGRD::SensorTokenizer records(lines[i], '\t'); - for (uint j = 0; j < records.count(); j++) { - if ( mColumnTypes[ j ] == "f" ) - item->setText(j, TDEGlobal::locale()->formatNumber( records[j].toFloat() ) ); - else if ( mColumnTypes[ j ] == "D" ) - item->setText(j, TDEGlobal::locale()->formatNumber( records[j].toDouble(), 0 ) ); - else - item->setText(j, records[j]); - } - - insertItem(item); - } - - verticalScrollBar()->setValue(vpos); - horizontalScrollBar()->setValue(hpos); - - viewport()->setUpdatesEnabled(true); - setUpdatesEnabled(true); - - triggerUpdate(); -} - -int PrivateListView::columnType( uint pos ) const -{ - if ( pos >= mColumnTypes.count() ) - return 0; - - if ( mColumnTypes[ pos ] == "d" || mColumnTypes[ pos ] == "D" ) - return Int; - else if ( mColumnTypes[ pos ] == "f" || mColumnTypes[ pos ] == "F" ) - return Float; - else if ( mColumnTypes[ pos ] == "t" ) - return Time; - else if ( mColumnTypes[ pos ] == "M" ) - return DiskStat; - else - return Text; -} - -void PrivateListView::removeColumns(void) -{ - for (int i = columns() - 1; i >= 0; --i) - removeColumn(i); -} - -void PrivateListView::addColumn(const TQString& label, const TQString& type) -{ - TQListView::addColumn( label ); - int col = columns() - 1; - - if (type == "s" || type == "S") - setColumnAlignment(col, AlignLeft); - else if (type == "d" || type == "D") - setColumnAlignment(col, AlignRight); - else if (type == "t") - setColumnAlignment(col, AlignRight); - else if (type == "f") - setColumnAlignment(col, AlignRight); - else if (type == "M") - setColumnAlignment(col, AlignLeft); - else - { - kdDebug(1215) << "Unknown type " << type << " of column " << label - << " in ListView!" << endl; - return; - } - - mColumnTypes.append( type ); - - /* Just use some sensible default values as initial setting. */ - TQFontMetrics fm = fontMetrics(); - setColumnWidth(col, fm.width(label) + 10); -} - -ListView::ListView(TQWidget* parent, const char* name, const TQString& title, int, int) - : KSGRD::SensorDisplay(parent, name, title) -{ - setBackgroundColor(KSGRD::Style->backgroundColor()); - - monitor = new PrivateListView( frame() ); - TQ_CHECK_PTR(monitor); - monitor->setSelectionMode(TQListView::NoSelection); - monitor->setItemMargin(2); - - setMinimumSize(50, 25); - - setPlotterWidget(monitor); - - setModified(false); -} - -bool -ListView::addSensor(const TQString& hostName, const TQString& sensorName, const TQString& sensorType, const TQString& title) -{ - if (sensorType != "listview") - return (false); - - registerSensor(new KSGRD::SensorProperties(hostName, sensorName, sensorType, title)); - - setTitle(title); - - /* To differentiate between answers from value requests and info - * requests we use 100 for info requests. */ - sendRequest(hostName, sensorName + "?", 100); - sendRequest(hostName, sensorName, 19); - setModified(true); - return (true); -} - -void -ListView::updateList() -{ - sendRequest(sensors().at(0)->hostName(), sensors().at(0)->name(), 19); -} - -void -ListView::answerReceived(int id, const TQString& answer) -{ - /* We received something, so the sensor is probably ok. */ - sensorError(id, false); - - switch (id) - { - case 100: { - /* We have received the answer to a '?' command that contains - * the information about the table headers. */ - KSGRD::SensorTokenizer lines(answer, '\n'); - if (lines.count() != 2) - { - kdDebug(1215) << "wrong number of lines" << endl; - return; - } - KSGRD::SensorTokenizer headers(lines[0], '\t'); - KSGRD::SensorTokenizer colTypes(lines[1], '\t'); - - /* remove all columns from list */ - monitor->removeColumns(); - - /* add the new columns */ - for (unsigned int i = 0; i < headers.count(); i++) - /* TODO: Implement translation support for header texts */ - monitor->addColumn(headers[i], colTypes[i]); - break; - } - case 19: { - monitor->update(answer); - break; - } - } -} - -void -ListView::resizeEvent(TQResizeEvent*) -{ - frame()->setGeometry(0, 0, width(), height()); - monitor->setGeometry(10, 20, width() - 20, height() - 30); -} - -bool -ListView::restoreSettings(TQDomElement& element) -{ - addSensor(element.attribute("hostName"), element.attribute("sensorName"), (element.attribute("sensorType").isEmpty() ? "listview" : element.attribute("sensorType")), element.attribute("title")); - - TQColorGroup colorGroup = monitor->colorGroup(); - colorGroup.setColor(TQColorGroup::Link, restoreColor(element, "gridColor", KSGRD::Style->firstForegroundColor())); - colorGroup.setColor(TQColorGroup::Text, restoreColor(element, "textColor", KSGRD::Style->secondForegroundColor())); - colorGroup.setColor(TQColorGroup::Base, restoreColor(element, "backgroundColor", KSGRD::Style->backgroundColor())); - - monitor->setPalette(TQPalette(colorGroup, colorGroup, colorGroup)); - - SensorDisplay::restoreSettings(element); - - setModified(false); - - return (true); -} - -bool -ListView::saveSettings(TQDomDocument& doc, TQDomElement& element, bool save) -{ - element.setAttribute("hostName", sensors().at(0)->hostName()); - element.setAttribute("sensorName", sensors().at(0)->name()); - element.setAttribute("sensorType", sensors().at(0)->type()); - - TQColorGroup colorGroup = monitor->colorGroup(); - saveColor(element, "gridColor", colorGroup.color(TQColorGroup::Link)); - saveColor(element, "textColor", colorGroup.color(TQColorGroup::Text)); - saveColor(element, "backgroundColor", colorGroup.color(TQColorGroup::Base)); - - SensorDisplay::saveSettings(doc, element); - - if (save) - setModified(false); - - return (true); -} - -void -ListView::configureSettings() -{ - lvs = new ListViewSettings(this, "ListViewSettings"); - TQ_CHECK_PTR(lvs); - connect(lvs, TQT_SIGNAL(applyClicked()), TQT_SLOT(applySettings())); - - TQColorGroup colorGroup = monitor->colorGroup(); - lvs->setGridColor(colorGroup.color(TQColorGroup::Link)); - lvs->setTextColor(colorGroup.color(TQColorGroup::Text)); - lvs->setBackgroundColor(colorGroup.color(TQColorGroup::Base)); - lvs->setTitle(title()); - - if (lvs->exec()) - applySettings(); - - delete lvs; - lvs = 0; -} - -void -ListView::applySettings() -{ - TQColorGroup colorGroup = monitor->colorGroup(); - colorGroup.setColor(TQColorGroup::Link, lvs->gridColor()); - colorGroup.setColor(TQColorGroup::Text, lvs->textColor()); - colorGroup.setColor(TQColorGroup::Base, lvs->backgroundColor()); - monitor->setPalette(TQPalette(colorGroup, colorGroup, colorGroup)); - - setTitle(lvs->title()); - - setModified(true); -} - -void -ListView::applyStyle() -{ - TQColorGroup colorGroup = monitor->colorGroup(); - colorGroup.setColor(TQColorGroup::Link, KSGRD::Style->firstForegroundColor()); - colorGroup.setColor(TQColorGroup::Text, KSGRD::Style->secondForegroundColor()); - colorGroup.setColor(TQColorGroup::Base, KSGRD::Style->backgroundColor()); - monitor->setPalette(TQPalette(colorGroup, colorGroup, colorGroup)); - - setModified(true); -} diff --git a/ksysguard/gui/SensorDisplayLib/ListView.cpp b/ksysguard/gui/SensorDisplayLib/ListView.cpp new file mode 100644 index 000000000..5b748e9c0 --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/ListView.cpp @@ -0,0 +1,371 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 2001 Tobias Koenig + + This program is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + KSysGuard is currently maintained by Chris Schlaeger . + Please do not commit any changes without consulting me first. Thanks! + +*/ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ListView.h" +#include "ListView.moc" +#include "ListViewSettings.h" + +PrivateListViewItem::PrivateListViewItem(PrivateListView *parent) + : TQListViewItem(parent) +{ + _parent = parent; +} + +int PrivateListViewItem::compare( TQListViewItem *item, int col, bool ascending ) const +{ + int type = ((PrivateListView*)listView())->columnType( col ); + + if ( type == PrivateListView::Int ) { + int prev = (int)TDEGlobal::locale()->readNumber( key( col, ascending ) ); + int next = (int)TDEGlobal::locale()->readNumber( item->key( col, ascending ) ); + if ( prev < next ) + return -1; + else if ( prev == next ) + return 0; + else + return 1; + } else if ( type == PrivateListView::Float ) { + double prev = TDEGlobal::locale()->readNumber( key( col, ascending ) ); + double next = TDEGlobal::locale()->readNumber( item->key( col, ascending ) ); + if ( prev < next ) + return -1; + else + return 1; + } else if ( type == PrivateListView::Time ) { + int hourPrev, hourNext, minutesPrev, minutesNext; + sscanf( key( col, ascending ).latin1(), "%d:%d", &hourPrev, &minutesPrev ); + sscanf( item->key( col, ascending ).latin1(), "%d:%d", &hourNext, &minutesNext ); + int prev = hourPrev * 60 + minutesPrev; + int next = hourNext * 60 + minutesNext; + if ( prev < next ) + return -1; + else if ( prev == next ) + return 0; + else + return 1; + } else if ( type == PrivateListView::DiskStat ) { + TQString prev = key( col, ascending ); + TQString next = item->key( col, ascending ); + TQString prevKey, nextKey; + + uint counter = prev.length(); + for ( uint i = 0; i < counter; ++i ) + if ( prev[ i ].isDigit() ) { + prevKey.sprintf( "%s%016d", prev.left( i ).latin1(), prev.mid( i ).toInt() ); + break; + } + + counter = next.length(); + for ( uint i = 0; i < counter; ++i ) + if ( next[ i ].isDigit() ) { + nextKey.sprintf( "%s%016d", next.left( i ).latin1(), next.mid( i ).toInt() ); + break; + } + + return prevKey.compare( nextKey ); + } else + return key( col, ascending ).localeAwareCompare( item->key( col, ascending ) ); +} + +PrivateListView::PrivateListView(TQWidget *parent, const char *name) + : TQListView(parent, name) +{ + TQColorGroup cg = colorGroup(); + + cg.setColor(TQColorGroup::Link, KSGRD::Style->firstForegroundColor()); + cg.setColor(TQColorGroup::Text, KSGRD::Style->secondForegroundColor()); + cg.setColor(TQColorGroup::Base, KSGRD::Style->backgroundColor()); + + setPalette(TQPalette(cg, cg, cg)); +} + +void PrivateListView::update(const TQString& answer) +{ + setUpdatesEnabled(false); + viewport()->setUpdatesEnabled(false); + + int vpos = verticalScrollBar()->value(); + int hpos = horizontalScrollBar()->value(); + + clear(); + + KSGRD::SensorTokenizer lines(answer, '\n'); + for (uint i = 0; i < lines.count(); i++) { + PrivateListViewItem *item = new PrivateListViewItem(this); + KSGRD::SensorTokenizer records(lines[i], '\t'); + for (uint j = 0; j < records.count(); j++) { + if ( mColumnTypes[ j ] == "f" ) + item->setText(j, TDEGlobal::locale()->formatNumber( records[j].toFloat() ) ); + else if ( mColumnTypes[ j ] == "D" ) + item->setText(j, TDEGlobal::locale()->formatNumber( records[j].toDouble(), 0 ) ); + else + item->setText(j, records[j]); + } + + insertItem(item); + } + + verticalScrollBar()->setValue(vpos); + horizontalScrollBar()->setValue(hpos); + + viewport()->setUpdatesEnabled(true); + setUpdatesEnabled(true); + + triggerUpdate(); +} + +int PrivateListView::columnType( uint pos ) const +{ + if ( pos >= mColumnTypes.count() ) + return 0; + + if ( mColumnTypes[ pos ] == "d" || mColumnTypes[ pos ] == "D" ) + return Int; + else if ( mColumnTypes[ pos ] == "f" || mColumnTypes[ pos ] == "F" ) + return Float; + else if ( mColumnTypes[ pos ] == "t" ) + return Time; + else if ( mColumnTypes[ pos ] == "M" ) + return DiskStat; + else + return Text; +} + +void PrivateListView::removeColumns(void) +{ + for (int i = columns() - 1; i >= 0; --i) + removeColumn(i); +} + +void PrivateListView::addColumn(const TQString& label, const TQString& type) +{ + TQListView::addColumn( label ); + int col = columns() - 1; + + if (type == "s" || type == "S") + setColumnAlignment(col, AlignLeft); + else if (type == "d" || type == "D") + setColumnAlignment(col, AlignRight); + else if (type == "t") + setColumnAlignment(col, AlignRight); + else if (type == "f") + setColumnAlignment(col, AlignRight); + else if (type == "M") + setColumnAlignment(col, AlignLeft); + else + { + kdDebug(1215) << "Unknown type " << type << " of column " << label + << " in ListView!" << endl; + return; + } + + mColumnTypes.append( type ); + + /* Just use some sensible default values as initial setting. */ + TQFontMetrics fm = fontMetrics(); + setColumnWidth(col, fm.width(label) + 10); +} + +ListView::ListView(TQWidget* parent, const char* name, const TQString& title, int, int) + : KSGRD::SensorDisplay(parent, name, title) +{ + setBackgroundColor(KSGRD::Style->backgroundColor()); + + monitor = new PrivateListView( frame() ); + TQ_CHECK_PTR(monitor); + monitor->setSelectionMode(TQListView::NoSelection); + monitor->setItemMargin(2); + + setMinimumSize(50, 25); + + setPlotterWidget(monitor); + + setModified(false); +} + +bool +ListView::addSensor(const TQString& hostName, const TQString& sensorName, const TQString& sensorType, const TQString& title) +{ + if (sensorType != "listview") + return (false); + + registerSensor(new KSGRD::SensorProperties(hostName, sensorName, sensorType, title)); + + setTitle(title); + + /* To differentiate between answers from value requests and info + * requests we use 100 for info requests. */ + sendRequest(hostName, sensorName + "?", 100); + sendRequest(hostName, sensorName, 19); + setModified(true); + return (true); +} + +void +ListView::updateList() +{ + sendRequest(sensors().at(0)->hostName(), sensors().at(0)->name(), 19); +} + +void +ListView::answerReceived(int id, const TQString& answer) +{ + /* We received something, so the sensor is probably ok. */ + sensorError(id, false); + + switch (id) + { + case 100: { + /* We have received the answer to a '?' command that contains + * the information about the table headers. */ + KSGRD::SensorTokenizer lines(answer, '\n'); + if (lines.count() != 2) + { + kdDebug(1215) << "wrong number of lines" << endl; + return; + } + KSGRD::SensorTokenizer headers(lines[0], '\t'); + KSGRD::SensorTokenizer colTypes(lines[1], '\t'); + + /* remove all columns from list */ + monitor->removeColumns(); + + /* add the new columns */ + for (unsigned int i = 0; i < headers.count(); i++) + /* TODO: Implement translation support for header texts */ + monitor->addColumn(headers[i], colTypes[i]); + break; + } + case 19: { + monitor->update(answer); + break; + } + } +} + +void +ListView::resizeEvent(TQResizeEvent*) +{ + frame()->setGeometry(0, 0, width(), height()); + monitor->setGeometry(10, 20, width() - 20, height() - 30); +} + +bool +ListView::restoreSettings(TQDomElement& element) +{ + addSensor(element.attribute("hostName"), element.attribute("sensorName"), (element.attribute("sensorType").isEmpty() ? "listview" : element.attribute("sensorType")), element.attribute("title")); + + TQColorGroup colorGroup = monitor->colorGroup(); + colorGroup.setColor(TQColorGroup::Link, restoreColor(element, "gridColor", KSGRD::Style->firstForegroundColor())); + colorGroup.setColor(TQColorGroup::Text, restoreColor(element, "textColor", KSGRD::Style->secondForegroundColor())); + colorGroup.setColor(TQColorGroup::Base, restoreColor(element, "backgroundColor", KSGRD::Style->backgroundColor())); + + monitor->setPalette(TQPalette(colorGroup, colorGroup, colorGroup)); + + SensorDisplay::restoreSettings(element); + + setModified(false); + + return (true); +} + +bool +ListView::saveSettings(TQDomDocument& doc, TQDomElement& element, bool save) +{ + element.setAttribute("hostName", sensors().at(0)->hostName()); + element.setAttribute("sensorName", sensors().at(0)->name()); + element.setAttribute("sensorType", sensors().at(0)->type()); + + TQColorGroup colorGroup = monitor->colorGroup(); + saveColor(element, "gridColor", colorGroup.color(TQColorGroup::Link)); + saveColor(element, "textColor", colorGroup.color(TQColorGroup::Text)); + saveColor(element, "backgroundColor", colorGroup.color(TQColorGroup::Base)); + + SensorDisplay::saveSettings(doc, element); + + if (save) + setModified(false); + + return (true); +} + +void +ListView::configureSettings() +{ + lvs = new ListViewSettings(this, "ListViewSettings"); + TQ_CHECK_PTR(lvs); + connect(lvs, TQT_SIGNAL(applyClicked()), TQT_SLOT(applySettings())); + + TQColorGroup colorGroup = monitor->colorGroup(); + lvs->setGridColor(colorGroup.color(TQColorGroup::Link)); + lvs->setTextColor(colorGroup.color(TQColorGroup::Text)); + lvs->setBackgroundColor(colorGroup.color(TQColorGroup::Base)); + lvs->setTitle(title()); + + if (lvs->exec()) + applySettings(); + + delete lvs; + lvs = 0; +} + +void +ListView::applySettings() +{ + TQColorGroup colorGroup = monitor->colorGroup(); + colorGroup.setColor(TQColorGroup::Link, lvs->gridColor()); + colorGroup.setColor(TQColorGroup::Text, lvs->textColor()); + colorGroup.setColor(TQColorGroup::Base, lvs->backgroundColor()); + monitor->setPalette(TQPalette(colorGroup, colorGroup, colorGroup)); + + setTitle(lvs->title()); + + setModified(true); +} + +void +ListView::applyStyle() +{ + TQColorGroup colorGroup = monitor->colorGroup(); + colorGroup.setColor(TQColorGroup::Link, KSGRD::Style->firstForegroundColor()); + colorGroup.setColor(TQColorGroup::Text, KSGRD::Style->secondForegroundColor()); + colorGroup.setColor(TQColorGroup::Base, KSGRD::Style->backgroundColor()); + monitor->setPalette(TQPalette(colorGroup, colorGroup, colorGroup)); + + setModified(true); +} diff --git a/ksysguard/gui/SensorDisplayLib/ListViewSettings.cc b/ksysguard/gui/SensorDisplayLib/ListViewSettings.cc deleted file mode 100644 index a3b1eb3ad..000000000 --- a/ksysguard/gui/SensorDisplayLib/ListViewSettings.cc +++ /dev/null @@ -1,73 +0,0 @@ -/* This file is part of the KDE project - Copyright ( C ) 2003 Nadeem Hasan - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "ListViewSettings.h" -#include "ListViewSettingsWidget.h" - -#include - -ListViewSettings::ListViewSettings( TQWidget *parent, const char *name ) - : KDialogBase( parent, name, true, i18n( "List View Settings" ), - Ok|Apply|Cancel, Ok, true ) -{ - m_settingsWidget = new ListViewSettingsWidget( this, "m_settingsWidget" ); - setMainWidget( m_settingsWidget ); -} - -TQString ListViewSettings::title() const -{ - return m_settingsWidget->title(); -} - -TQColor ListViewSettings::textColor() const -{ - return m_settingsWidget->textColor(); -} - -TQColor ListViewSettings::backgroundColor() const -{ - return m_settingsWidget->backgroundColor(); -} - -TQColor ListViewSettings::gridColor() const -{ - return m_settingsWidget->gridColor(); -} - -void ListViewSettings::setTitle( const TQString &title ) -{ - m_settingsWidget->setTitle( title ); -} - -void ListViewSettings::setBackgroundColor( const TQColor &c ) -{ - m_settingsWidget->setBackgroundColor( c ); -} - -void ListViewSettings::setTextColor( const TQColor &c ) -{ - m_settingsWidget->setTextColor( c ); -} - -void ListViewSettings::setGridColor( const TQColor &c ) -{ - m_settingsWidget->setGridColor( c ); -} - -#include "ListViewSettings.moc" diff --git a/ksysguard/gui/SensorDisplayLib/ListViewSettings.cpp b/ksysguard/gui/SensorDisplayLib/ListViewSettings.cpp new file mode 100644 index 000000000..a3b1eb3ad --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/ListViewSettings.cpp @@ -0,0 +1,73 @@ +/* This file is part of the KDE project + Copyright ( C ) 2003 Nadeem Hasan + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ListViewSettings.h" +#include "ListViewSettingsWidget.h" + +#include + +ListViewSettings::ListViewSettings( TQWidget *parent, const char *name ) + : KDialogBase( parent, name, true, i18n( "List View Settings" ), + Ok|Apply|Cancel, Ok, true ) +{ + m_settingsWidget = new ListViewSettingsWidget( this, "m_settingsWidget" ); + setMainWidget( m_settingsWidget ); +} + +TQString ListViewSettings::title() const +{ + return m_settingsWidget->title(); +} + +TQColor ListViewSettings::textColor() const +{ + return m_settingsWidget->textColor(); +} + +TQColor ListViewSettings::backgroundColor() const +{ + return m_settingsWidget->backgroundColor(); +} + +TQColor ListViewSettings::gridColor() const +{ + return m_settingsWidget->gridColor(); +} + +void ListViewSettings::setTitle( const TQString &title ) +{ + m_settingsWidget->setTitle( title ); +} + +void ListViewSettings::setBackgroundColor( const TQColor &c ) +{ + m_settingsWidget->setBackgroundColor( c ); +} + +void ListViewSettings::setTextColor( const TQColor &c ) +{ + m_settingsWidget->setTextColor( c ); +} + +void ListViewSettings::setGridColor( const TQColor &c ) +{ + m_settingsWidget->setGridColor( c ); +} + +#include "ListViewSettings.moc" diff --git a/ksysguard/gui/SensorDisplayLib/LogFile.cc b/ksysguard/gui/SensorDisplayLib/LogFile.cc deleted file mode 100644 index a8b22569d..000000000 --- a/ksysguard/gui/SensorDisplayLib/LogFile.cc +++ /dev/null @@ -1,285 +0,0 @@ -/* - KSysGuard, the KDE System Guard - - Copyright (c) 2001 Tobias Koenig - - This program is free software; you can redistribute it and/or - modify it under the terms of version 2 of the GNU General Public - License as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -*/ - -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include "LogFile.moc" - -LogFile::LogFile(TQWidget *parent, const char *name, const TQString& title) - : KSGRD::SensorDisplay(parent, name, title) -{ - monitor = new TQListBox(this); - TQ_CHECK_PTR(monitor); - - setMinimumSize(50, 25); - - setPlotterWidget(monitor); - - setModified(false); -} - -LogFile::~LogFile(void) -{ - sendRequest(sensors().at(0)->hostName(), TQString("logfile_unregister %1" ).arg(logFileID), 43); -} - -bool -LogFile::addSensor(const TQString& hostName, const TQString& sensorName, const TQString& sensorType, const TQString& title) -{ - if (sensorType != "logfile") - return (false); - - registerSensor(new KSGRD::SensorProperties(hostName, sensorName, sensorType, title)); - - TQString sensorID = sensorName.right(sensorName.length() - (sensorName.findRev("/") + 1)); - - sendRequest(sensors().at(0)->hostName(), TQString("logfile_register %1" ).arg(sensorID), 42); - - if (title.isEmpty()) - setTitle(sensors().at(0)->hostName() + ":" + sensorID); - else - setTitle(title); - - setModified(true); - - return (true); -} - - -void LogFile::configureSettings(void) -{ - TQColorGroup cgroup = monitor->colorGroup(); - - lfs = new LogFileSettings(this); - TQ_CHECK_PTR(lfs); - - lfs->fgColor->setColor(cgroup.text()); - lfs->fgColor->setText(i18n("Foreground color:")); - lfs->bgColor->setColor(cgroup.base()); - lfs->bgColor->setText(i18n("Background color:")); - lfs->fontButton->setFont(monitor->font()); - lfs->ruleList->insertStringList(filterRules); - lfs->title->setText(title()); - - connect(lfs->okButton, TQT_SIGNAL(clicked()), lfs, TQT_SLOT(accept())); - connect(lfs->applyButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(applySettings())); - connect(lfs->cancelButton, TQT_SIGNAL(clicked()), lfs, TQT_SLOT(reject())); - - connect(lfs->fontButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(settingsFontSelection())); - connect(lfs->addButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(settingsAddRule())); - connect(lfs->deleteButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(settingsDeleteRule())); - connect(lfs->changeButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(settingsChangeRule())); - connect(lfs->ruleList, TQT_SIGNAL(selected(int)), this, TQT_SLOT(settingsRuleListSelected(int))); - connect(lfs->ruleText, TQT_SIGNAL(returnPressed()), this, TQT_SLOT(settingsAddRule())); - - if (lfs->exec()) { - applySettings(); - } - - delete lfs; - lfs = 0; -} - -void LogFile::settingsFontSelection() -{ - TQFont tmpFont = lfs->fontButton->font(); - - if (TDEFontDialog::getFont(tmpFont) == TDEFontDialog::Accepted) { - lfs->fontButton->setFont(tmpFont); - } -} - -void LogFile::settingsAddRule() -{ - if (!lfs->ruleText->text().isEmpty()) { - lfs->ruleList->insertItem(lfs->ruleText->text(), -1); - lfs->ruleText->setText(""); - } -} - -void LogFile::settingsDeleteRule() -{ - lfs->ruleList->removeItem(lfs->ruleList->currentItem()); - lfs->ruleText->setText(""); -} - -void LogFile::settingsChangeRule() -{ - lfs->ruleList->changeItem(lfs->ruleText->text(), lfs->ruleList->currentItem()); - lfs->ruleText->setText(""); -} - -void LogFile::settingsRuleListSelected(int index) -{ - lfs->ruleText->setText(lfs->ruleList->text(index)); -} - -void LogFile::applySettings(void) -{ - TQColorGroup cgroup = monitor->colorGroup(); - - cgroup.setColor(TQColorGroup::Text, lfs->fgColor->color()); - cgroup.setColor(TQColorGroup::Base, lfs->bgColor->color()); - monitor->setPalette(TQPalette(cgroup, cgroup, cgroup)); - monitor->setFont(lfs->fontButton->font()); - - filterRules.clear(); - for (uint i = 0; i < lfs->ruleList->count(); i++) - filterRules.append(lfs->ruleList->text(i)); - - setTitle(lfs->title->text()); - - setModified(true); -} - -void -LogFile::applyStyle() -{ - TQColorGroup cgroup = monitor->colorGroup(); - - cgroup.setColor(TQColorGroup::Text, KSGRD::Style->firstForegroundColor()); - cgroup.setColor(TQColorGroup::Base, KSGRD::Style->backgroundColor()); - monitor->setPalette(TQPalette(cgroup, cgroup, cgroup)); - - setModified(true); -} - -bool -LogFile::restoreSettings(TQDomElement& element) -{ - TQFont font; - TQColorGroup cgroup = monitor->colorGroup(); - - cgroup.setColor(TQColorGroup::Text, restoreColor(element, "textColor", Qt::green)); - cgroup.setColor(TQColorGroup::Base, restoreColor(element, "backgroundColor", Qt::black)); - monitor->setPalette(TQPalette(cgroup, cgroup, cgroup)); - - addSensor(element.attribute("hostName"), element.attribute("sensorName"), (element.attribute("sensorType").isEmpty() ? "logfile" : element.attribute("sensorType")), element.attribute("title")); - - font.fromString( element.attribute( "font" ) ); - monitor->setFont(font); - - TQDomNodeList dnList = element.elementsByTagName("filter"); - for (uint i = 0; i < dnList.count(); i++) { - TQDomElement element = dnList.item(i).toElement(); - filterRules.append(element.attribute("rule")); - } - - SensorDisplay::restoreSettings(element); - - setModified(false); - - return true; -} - -bool -LogFile::saveSettings(TQDomDocument& doc, TQDomElement& element, bool save) -{ - element.setAttribute("hostName", sensors().at(0)->hostName()); - element.setAttribute("sensorName", sensors().at(0)->name()); - element.setAttribute("sensorType", sensors().at(0)->type()); - - element.setAttribute("font", monitor->font().toString()); - - saveColor(element, "textColor", monitor->colorGroup().text()); - saveColor(element, "backgroundColor", monitor->colorGroup().base()); - - for (TQStringList::Iterator it = filterRules.begin(); - it != filterRules.end(); it++) - { - TQDomElement filter = doc.createElement("filter"); - filter.setAttribute("rule", (*it)); - element.appendChild(filter); - } - - SensorDisplay::saveSettings(doc, element); - - if (save) - setModified(false); - - return true; -} - -void -LogFile::updateMonitor() -{ - sendRequest(sensors().at(0)->hostName(), - TQString("%1 %2" ).arg(sensors().at(0)->name()).arg(logFileID), 19); -} - -void -LogFile::answerReceived(int id, const TQString& answer) -{ - /* We received something, so the sensor is probably ok. */ - sensorError(id, false); - - switch (id) - { - case 19: { - KSGRD::SensorTokenizer lines(answer, '\n'); - - for (uint i = 0; i < lines.count(); i++) { - if (monitor->count() == MAXLINES) - monitor->removeItem(0); - - monitor->insertItem(lines[i], -1); - - for (TQStringList::Iterator it = filterRules.begin(); it != filterRules.end(); it++) { - TQRegExp *expr = new TQRegExp((*it).latin1()); - if (expr->search(lines[i].latin1()) != -1) { - KNotifyClient::event(winId(), "pattern_match", TQString("rule '%1' matched").arg((*it).latin1())); - } - delete expr; - } - } - - monitor->setCurrentItem( monitor->count() - 1 ); - monitor->ensureCurrentVisible(); - - break; - } - - case 42: { - logFileID = answer.toULong(); - break; - } - } -} - -void -LogFile::resizeEvent(TQResizeEvent*) -{ - frame()->setGeometry(0, 0, this->width(), this->height()); - monitor->setGeometry(10, 20, this->width() - 20, this->height() - 30); -} diff --git a/ksysguard/gui/SensorDisplayLib/LogFile.cpp b/ksysguard/gui/SensorDisplayLib/LogFile.cpp new file mode 100644 index 000000000..a8b22569d --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/LogFile.cpp @@ -0,0 +1,285 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 2001 Tobias Koenig + + This program is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include "LogFile.moc" + +LogFile::LogFile(TQWidget *parent, const char *name, const TQString& title) + : KSGRD::SensorDisplay(parent, name, title) +{ + monitor = new TQListBox(this); + TQ_CHECK_PTR(monitor); + + setMinimumSize(50, 25); + + setPlotterWidget(monitor); + + setModified(false); +} + +LogFile::~LogFile(void) +{ + sendRequest(sensors().at(0)->hostName(), TQString("logfile_unregister %1" ).arg(logFileID), 43); +} + +bool +LogFile::addSensor(const TQString& hostName, const TQString& sensorName, const TQString& sensorType, const TQString& title) +{ + if (sensorType != "logfile") + return (false); + + registerSensor(new KSGRD::SensorProperties(hostName, sensorName, sensorType, title)); + + TQString sensorID = sensorName.right(sensorName.length() - (sensorName.findRev("/") + 1)); + + sendRequest(sensors().at(0)->hostName(), TQString("logfile_register %1" ).arg(sensorID), 42); + + if (title.isEmpty()) + setTitle(sensors().at(0)->hostName() + ":" + sensorID); + else + setTitle(title); + + setModified(true); + + return (true); +} + + +void LogFile::configureSettings(void) +{ + TQColorGroup cgroup = monitor->colorGroup(); + + lfs = new LogFileSettings(this); + TQ_CHECK_PTR(lfs); + + lfs->fgColor->setColor(cgroup.text()); + lfs->fgColor->setText(i18n("Foreground color:")); + lfs->bgColor->setColor(cgroup.base()); + lfs->bgColor->setText(i18n("Background color:")); + lfs->fontButton->setFont(monitor->font()); + lfs->ruleList->insertStringList(filterRules); + lfs->title->setText(title()); + + connect(lfs->okButton, TQT_SIGNAL(clicked()), lfs, TQT_SLOT(accept())); + connect(lfs->applyButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(applySettings())); + connect(lfs->cancelButton, TQT_SIGNAL(clicked()), lfs, TQT_SLOT(reject())); + + connect(lfs->fontButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(settingsFontSelection())); + connect(lfs->addButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(settingsAddRule())); + connect(lfs->deleteButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(settingsDeleteRule())); + connect(lfs->changeButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(settingsChangeRule())); + connect(lfs->ruleList, TQT_SIGNAL(selected(int)), this, TQT_SLOT(settingsRuleListSelected(int))); + connect(lfs->ruleText, TQT_SIGNAL(returnPressed()), this, TQT_SLOT(settingsAddRule())); + + if (lfs->exec()) { + applySettings(); + } + + delete lfs; + lfs = 0; +} + +void LogFile::settingsFontSelection() +{ + TQFont tmpFont = lfs->fontButton->font(); + + if (TDEFontDialog::getFont(tmpFont) == TDEFontDialog::Accepted) { + lfs->fontButton->setFont(tmpFont); + } +} + +void LogFile::settingsAddRule() +{ + if (!lfs->ruleText->text().isEmpty()) { + lfs->ruleList->insertItem(lfs->ruleText->text(), -1); + lfs->ruleText->setText(""); + } +} + +void LogFile::settingsDeleteRule() +{ + lfs->ruleList->removeItem(lfs->ruleList->currentItem()); + lfs->ruleText->setText(""); +} + +void LogFile::settingsChangeRule() +{ + lfs->ruleList->changeItem(lfs->ruleText->text(), lfs->ruleList->currentItem()); + lfs->ruleText->setText(""); +} + +void LogFile::settingsRuleListSelected(int index) +{ + lfs->ruleText->setText(lfs->ruleList->text(index)); +} + +void LogFile::applySettings(void) +{ + TQColorGroup cgroup = monitor->colorGroup(); + + cgroup.setColor(TQColorGroup::Text, lfs->fgColor->color()); + cgroup.setColor(TQColorGroup::Base, lfs->bgColor->color()); + monitor->setPalette(TQPalette(cgroup, cgroup, cgroup)); + monitor->setFont(lfs->fontButton->font()); + + filterRules.clear(); + for (uint i = 0; i < lfs->ruleList->count(); i++) + filterRules.append(lfs->ruleList->text(i)); + + setTitle(lfs->title->text()); + + setModified(true); +} + +void +LogFile::applyStyle() +{ + TQColorGroup cgroup = monitor->colorGroup(); + + cgroup.setColor(TQColorGroup::Text, KSGRD::Style->firstForegroundColor()); + cgroup.setColor(TQColorGroup::Base, KSGRD::Style->backgroundColor()); + monitor->setPalette(TQPalette(cgroup, cgroup, cgroup)); + + setModified(true); +} + +bool +LogFile::restoreSettings(TQDomElement& element) +{ + TQFont font; + TQColorGroup cgroup = monitor->colorGroup(); + + cgroup.setColor(TQColorGroup::Text, restoreColor(element, "textColor", Qt::green)); + cgroup.setColor(TQColorGroup::Base, restoreColor(element, "backgroundColor", Qt::black)); + monitor->setPalette(TQPalette(cgroup, cgroup, cgroup)); + + addSensor(element.attribute("hostName"), element.attribute("sensorName"), (element.attribute("sensorType").isEmpty() ? "logfile" : element.attribute("sensorType")), element.attribute("title")); + + font.fromString( element.attribute( "font" ) ); + monitor->setFont(font); + + TQDomNodeList dnList = element.elementsByTagName("filter"); + for (uint i = 0; i < dnList.count(); i++) { + TQDomElement element = dnList.item(i).toElement(); + filterRules.append(element.attribute("rule")); + } + + SensorDisplay::restoreSettings(element); + + setModified(false); + + return true; +} + +bool +LogFile::saveSettings(TQDomDocument& doc, TQDomElement& element, bool save) +{ + element.setAttribute("hostName", sensors().at(0)->hostName()); + element.setAttribute("sensorName", sensors().at(0)->name()); + element.setAttribute("sensorType", sensors().at(0)->type()); + + element.setAttribute("font", monitor->font().toString()); + + saveColor(element, "textColor", monitor->colorGroup().text()); + saveColor(element, "backgroundColor", monitor->colorGroup().base()); + + for (TQStringList::Iterator it = filterRules.begin(); + it != filterRules.end(); it++) + { + TQDomElement filter = doc.createElement("filter"); + filter.setAttribute("rule", (*it)); + element.appendChild(filter); + } + + SensorDisplay::saveSettings(doc, element); + + if (save) + setModified(false); + + return true; +} + +void +LogFile::updateMonitor() +{ + sendRequest(sensors().at(0)->hostName(), + TQString("%1 %2" ).arg(sensors().at(0)->name()).arg(logFileID), 19); +} + +void +LogFile::answerReceived(int id, const TQString& answer) +{ + /* We received something, so the sensor is probably ok. */ + sensorError(id, false); + + switch (id) + { + case 19: { + KSGRD::SensorTokenizer lines(answer, '\n'); + + for (uint i = 0; i < lines.count(); i++) { + if (monitor->count() == MAXLINES) + monitor->removeItem(0); + + monitor->insertItem(lines[i], -1); + + for (TQStringList::Iterator it = filterRules.begin(); it != filterRules.end(); it++) { + TQRegExp *expr = new TQRegExp((*it).latin1()); + if (expr->search(lines[i].latin1()) != -1) { + KNotifyClient::event(winId(), "pattern_match", TQString("rule '%1' matched").arg((*it).latin1())); + } + delete expr; + } + } + + monitor->setCurrentItem( monitor->count() - 1 ); + monitor->ensureCurrentVisible(); + + break; + } + + case 42: { + logFileID = answer.toULong(); + break; + } + } +} + +void +LogFile::resizeEvent(TQResizeEvent*) +{ + frame()->setGeometry(0, 0, this->width(), this->height()); + monitor->setGeometry(10, 20, this->width() - 20, this->height() - 30); +} diff --git a/ksysguard/gui/SensorDisplayLib/Makefile.am b/ksysguard/gui/SensorDisplayLib/Makefile.am index d3f82a3a7..8ebc4c5ee 100644 --- a/ksysguard/gui/SensorDisplayLib/Makefile.am +++ b/ksysguard/gui/SensorDisplayLib/Makefile.am @@ -9,25 +9,25 @@ libsensordisplays_la_LIBADD = ../ksgrd/libksgrd.la $(LIB_TDEIO) # Which sources should be compiled for the sensor display lib. libsensordisplays_la_SOURCES = \ - SensorDisplay.cc \ - BarGraph.cc \ - DancingBars.cc \ - DancingBarsSettings.cc \ - DummyDisplay.cc \ - FancyPlotter.cc \ - FancyPlotterSettings.cc \ - ListView.cc \ - LogFile.cc \ - MultiMeter.cc \ - MultiMeterSettings.cc \ - ProcessController.cc \ - ProcessList.cc \ - ReniceDlg.cc \ - SensorLogger.cc \ - SensorLoggerDlg.cc \ - SensorLoggerSettings.cc \ - ListViewSettings.cc \ - SignalPlotter.cc \ + SensorDisplay.cpp \ + BarGraph.cpp \ + DancingBars.cpp \ + DancingBarsSettings.cpp \ + DummyDisplay.cpp \ + FancyPlotter.cpp \ + FancyPlotterSettings.cpp \ + ListView.cpp \ + LogFile.cpp \ + MultiMeter.cpp \ + MultiMeterSettings.cpp \ + ProcessController.cpp \ + ProcessList.cpp \ + ReniceDlg.cpp \ + SensorLogger.cpp \ + SensorLoggerDlg.cpp \ + SensorLoggerSettings.cpp \ + ListViewSettings.cpp \ + SignalPlotter.cpp \ ListViewSettingsWidget.ui \ LogFileSettings.ui \ MultiMeterSettingsWidget.ui \ diff --git a/ksysguard/gui/SensorDisplayLib/MultiMeter.cc b/ksysguard/gui/SensorDisplayLib/MultiMeter.cc deleted file mode 100644 index 111c4787b..000000000 --- a/ksysguard/gui/SensorDisplayLib/MultiMeter.cc +++ /dev/null @@ -1,258 +0,0 @@ -/* - KSysGuard, the KDE System Guard - - Copyright (c) 1999, 2000, 2001 Chris Schlaeger - - This program is free software; you can redistribute it and/or - modify it under the terms of version 2 of the GNU General Public - License as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - KSysGuard is currently maintained by Chris Schlaeger . - Please do not commit any changes without consulting me first. Thanks! - -*/ - -#include -#include - -#include -#include -#include - -#include - -#include -#include - -#include "MultiMeter.moc" -#include "MultiMeterSettings.h" - -MultiMeter::MultiMeter(TQWidget* parent, const char* name, - const TQString& title, double, double, bool nf, bool isApplet) - : KSGRD::SensorDisplay(parent, name, title, nf, isApplet) -{ - setShowUnit( true ); - lowerLimit = upperLimit = 0; - lowerLimitActive = upperLimitActive = false; - - normalDigitColor = KSGRD::Style->firstForegroundColor(); - alarmDigitColor = KSGRD::Style->alarmColor(); - if (noFrame()) - lcd = new TQLCDNumber(this, "meterLCD"); - else - lcd = new TQLCDNumber(frame(), "meterLCD"); - TQ_CHECK_PTR(lcd); - lcd->setSegmentStyle(TQLCDNumber::Filled); - setDigitColor(KSGRD::Style->backgroundColor()); - lcd->setSizePolicy(TQSizePolicy(TQSizePolicy::Expanding, - TQSizePolicy::Expanding, false)); - - setBackgroundColor(KSGRD::Style->backgroundColor()); - /* All RMB clicks to the lcd widget will be handled by - * SensorDisplay::eventFilter. */ - lcd->installEventFilter(this); - - setPlotterWidget(lcd); - - setMinimumSize(5, 5); - setModified(false); -} - -bool -MultiMeter::addSensor(const TQString& hostName, const TQString& sensorName, - const TQString& sensorType, const TQString& title) -{ - if (sensorType != "integer" && sensorType != "float") - return (false); - - registerSensor(new KSGRD::SensorProperties(hostName, sensorName, sensorType, title)); - - /* To differentiate between answers from value requests and info - * requests we use 100 for info requests. */ - sendRequest(hostName, sensorName + "?", 100); - - TQToolTip::remove(lcd); - TQToolTip::add(lcd, TQString("%1:%2").arg(hostName).arg(sensorName)); - - setModified(true); - return (true); -} - -void -MultiMeter::answerReceived(int id, const TQString& answer) -{ - /* We received something, so the sensor is probably ok. */ - sensorError(id, false); - - if (id == 100) - { - KSGRD::SensorIntegerInfo info(answer); - setUnit(KSGRD::SensorMgr->translateUnit(info.unit())); - } - else - { - double val = answer.toDouble(); - int digits = (int) log10(val) + 1; - - if (noFrame()) - if (digits > 4) - lcd->setNumDigits(4); - else - lcd->setNumDigits(digits); - else - { - if (digits > 5) - lcd->setNumDigits(digits); - else - lcd->setNumDigits(5); - } - - lcd->display(val); - if (lowerLimitActive && val < lowerLimit) - { - setDigitColor(alarmDigitColor); - } - else if (upperLimitActive && val > upperLimit) - { - setDigitColor(alarmDigitColor); - } - else - setDigitColor(normalDigitColor); - } -} - -void -MultiMeter::resizeEvent(TQResizeEvent*) -{ - if (noFrame()) - lcd->setGeometry(0, 0, width(), height()); - else - frame()->setGeometry(0, 0, width(), height()); -} - -bool -MultiMeter::restoreSettings(TQDomElement& element) -{ - lowerLimitActive = element.attribute("lowerLimitActive").toInt(); - lowerLimit = element.attribute("lowerLimit").toLong(); - upperLimitActive = element.attribute("upperLimitActive").toInt(); - upperLimit = element.attribute("upperLimit").toLong(); - - normalDigitColor = restoreColor(element, "normalDigitColor", - KSGRD::Style->firstForegroundColor()); - alarmDigitColor = restoreColor(element, "alarmDigitColor", - KSGRD::Style->alarmColor()); - setBackgroundColor(restoreColor(element, "backgroundColor", - KSGRD::Style->backgroundColor())); - - addSensor(element.attribute("hostName"), element.attribute("sensorName"), (element.attribute("sensorType").isEmpty() ? "integer" : element.attribute("sensorType")), ""); - - SensorDisplay::restoreSettings(element); - - setModified(false); - - return (true); -} - -bool -MultiMeter::saveSettings(TQDomDocument& doc, TQDomElement& element, bool save) -{ - element.setAttribute("hostName", sensors().at(0)->hostName()); - element.setAttribute("sensorName", sensors().at(0)->name()); - element.setAttribute("sensorType", sensors().at(0)->type()); - element.setAttribute("showUnit", showUnit()); - element.setAttribute("lowerLimitActive", (int) lowerLimitActive); - element.setAttribute("lowerLimit", (int) lowerLimit); - element.setAttribute("upperLimitActive", (int) upperLimitActive); - element.setAttribute("upperLimit", (int) upperLimit); - - saveColor(element, "normalDigitColor", normalDigitColor); - saveColor(element, "alarmDigitColor", alarmDigitColor); - saveColor(element, "backgroundColor", lcd->backgroundColor()); - - SensorDisplay::saveSettings(doc, element); - - if (save) - setModified(false); - - return (true); -} - -void -MultiMeter::configureSettings() -{ - mms = new MultiMeterSettings(this, "MultiMeterSettings"); - TQ_CHECK_PTR(mms); - mms->setTitle(title()); - mms->setShowUnit(showUnit()); - mms->setLowerLimitActive(lowerLimitActive); - mms->setLowerLimit(lowerLimit); - mms->setUpperLimitActive(upperLimitActive); - mms->setUpperLimit(upperLimit); - mms->setNormalDigitColor(normalDigitColor); - mms->setAlarmDigitColor(alarmDigitColor); - mms->setMeterBackgroundColor(lcd->backgroundColor()); - - connect(mms, TQT_SIGNAL(applyClicked()), TQT_SLOT(applySettings())); - - if (mms->exec()) - applySettings(); - - delete mms; - mms = 0; -} - -void -MultiMeter::applySettings() -{ - setShowUnit( mms->showUnit() ); - setTitle(mms->title()); - lowerLimitActive = mms->lowerLimitActive(); - lowerLimit = mms->lowerLimit(); - upperLimitActive = mms->upperLimitActive(); - upperLimit = mms->upperLimit(); - - normalDigitColor = mms->normalDigitColor(); - alarmDigitColor = mms->alarmDigitColor(); - setBackgroundColor(mms->meterBackgroundColor()); - - repaint(); - setModified(true); -} - -void -MultiMeter::applyStyle() -{ - normalDigitColor = KSGRD::Style->firstForegroundColor(); - setBackgroundColor(KSGRD::Style->backgroundColor()); - repaint(); - setModified(true); -} - -void -MultiMeter::setDigitColor(const TQColor& col) -{ - TQPalette p = lcd->palette(); - p.setColor(TQColorGroup::Foreground, col); - lcd->setPalette(p); -} - -void -MultiMeter::setBackgroundColor(const TQColor& col) -{ - lcd->setBackgroundColor(col); - - TQPalette p = lcd->palette(); - p.setColor(TQColorGroup::Light, col); - p.setColor(TQColorGroup::Dark, col); - lcd->setPalette(p); -} diff --git a/ksysguard/gui/SensorDisplayLib/MultiMeter.cpp b/ksysguard/gui/SensorDisplayLib/MultiMeter.cpp new file mode 100644 index 000000000..111c4787b --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/MultiMeter.cpp @@ -0,0 +1,258 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 1999, 2000, 2001 Chris Schlaeger + + This program is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + KSysGuard is currently maintained by Chris Schlaeger . + Please do not commit any changes without consulting me first. Thanks! + +*/ + +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include "MultiMeter.moc" +#include "MultiMeterSettings.h" + +MultiMeter::MultiMeter(TQWidget* parent, const char* name, + const TQString& title, double, double, bool nf, bool isApplet) + : KSGRD::SensorDisplay(parent, name, title, nf, isApplet) +{ + setShowUnit( true ); + lowerLimit = upperLimit = 0; + lowerLimitActive = upperLimitActive = false; + + normalDigitColor = KSGRD::Style->firstForegroundColor(); + alarmDigitColor = KSGRD::Style->alarmColor(); + if (noFrame()) + lcd = new TQLCDNumber(this, "meterLCD"); + else + lcd = new TQLCDNumber(frame(), "meterLCD"); + TQ_CHECK_PTR(lcd); + lcd->setSegmentStyle(TQLCDNumber::Filled); + setDigitColor(KSGRD::Style->backgroundColor()); + lcd->setSizePolicy(TQSizePolicy(TQSizePolicy::Expanding, + TQSizePolicy::Expanding, false)); + + setBackgroundColor(KSGRD::Style->backgroundColor()); + /* All RMB clicks to the lcd widget will be handled by + * SensorDisplay::eventFilter. */ + lcd->installEventFilter(this); + + setPlotterWidget(lcd); + + setMinimumSize(5, 5); + setModified(false); +} + +bool +MultiMeter::addSensor(const TQString& hostName, const TQString& sensorName, + const TQString& sensorType, const TQString& title) +{ + if (sensorType != "integer" && sensorType != "float") + return (false); + + registerSensor(new KSGRD::SensorProperties(hostName, sensorName, sensorType, title)); + + /* To differentiate between answers from value requests and info + * requests we use 100 for info requests. */ + sendRequest(hostName, sensorName + "?", 100); + + TQToolTip::remove(lcd); + TQToolTip::add(lcd, TQString("%1:%2").arg(hostName).arg(sensorName)); + + setModified(true); + return (true); +} + +void +MultiMeter::answerReceived(int id, const TQString& answer) +{ + /* We received something, so the sensor is probably ok. */ + sensorError(id, false); + + if (id == 100) + { + KSGRD::SensorIntegerInfo info(answer); + setUnit(KSGRD::SensorMgr->translateUnit(info.unit())); + } + else + { + double val = answer.toDouble(); + int digits = (int) log10(val) + 1; + + if (noFrame()) + if (digits > 4) + lcd->setNumDigits(4); + else + lcd->setNumDigits(digits); + else + { + if (digits > 5) + lcd->setNumDigits(digits); + else + lcd->setNumDigits(5); + } + + lcd->display(val); + if (lowerLimitActive && val < lowerLimit) + { + setDigitColor(alarmDigitColor); + } + else if (upperLimitActive && val > upperLimit) + { + setDigitColor(alarmDigitColor); + } + else + setDigitColor(normalDigitColor); + } +} + +void +MultiMeter::resizeEvent(TQResizeEvent*) +{ + if (noFrame()) + lcd->setGeometry(0, 0, width(), height()); + else + frame()->setGeometry(0, 0, width(), height()); +} + +bool +MultiMeter::restoreSettings(TQDomElement& element) +{ + lowerLimitActive = element.attribute("lowerLimitActive").toInt(); + lowerLimit = element.attribute("lowerLimit").toLong(); + upperLimitActive = element.attribute("upperLimitActive").toInt(); + upperLimit = element.attribute("upperLimit").toLong(); + + normalDigitColor = restoreColor(element, "normalDigitColor", + KSGRD::Style->firstForegroundColor()); + alarmDigitColor = restoreColor(element, "alarmDigitColor", + KSGRD::Style->alarmColor()); + setBackgroundColor(restoreColor(element, "backgroundColor", + KSGRD::Style->backgroundColor())); + + addSensor(element.attribute("hostName"), element.attribute("sensorName"), (element.attribute("sensorType").isEmpty() ? "integer" : element.attribute("sensorType")), ""); + + SensorDisplay::restoreSettings(element); + + setModified(false); + + return (true); +} + +bool +MultiMeter::saveSettings(TQDomDocument& doc, TQDomElement& element, bool save) +{ + element.setAttribute("hostName", sensors().at(0)->hostName()); + element.setAttribute("sensorName", sensors().at(0)->name()); + element.setAttribute("sensorType", sensors().at(0)->type()); + element.setAttribute("showUnit", showUnit()); + element.setAttribute("lowerLimitActive", (int) lowerLimitActive); + element.setAttribute("lowerLimit", (int) lowerLimit); + element.setAttribute("upperLimitActive", (int) upperLimitActive); + element.setAttribute("upperLimit", (int) upperLimit); + + saveColor(element, "normalDigitColor", normalDigitColor); + saveColor(element, "alarmDigitColor", alarmDigitColor); + saveColor(element, "backgroundColor", lcd->backgroundColor()); + + SensorDisplay::saveSettings(doc, element); + + if (save) + setModified(false); + + return (true); +} + +void +MultiMeter::configureSettings() +{ + mms = new MultiMeterSettings(this, "MultiMeterSettings"); + TQ_CHECK_PTR(mms); + mms->setTitle(title()); + mms->setShowUnit(showUnit()); + mms->setLowerLimitActive(lowerLimitActive); + mms->setLowerLimit(lowerLimit); + mms->setUpperLimitActive(upperLimitActive); + mms->setUpperLimit(upperLimit); + mms->setNormalDigitColor(normalDigitColor); + mms->setAlarmDigitColor(alarmDigitColor); + mms->setMeterBackgroundColor(lcd->backgroundColor()); + + connect(mms, TQT_SIGNAL(applyClicked()), TQT_SLOT(applySettings())); + + if (mms->exec()) + applySettings(); + + delete mms; + mms = 0; +} + +void +MultiMeter::applySettings() +{ + setShowUnit( mms->showUnit() ); + setTitle(mms->title()); + lowerLimitActive = mms->lowerLimitActive(); + lowerLimit = mms->lowerLimit(); + upperLimitActive = mms->upperLimitActive(); + upperLimit = mms->upperLimit(); + + normalDigitColor = mms->normalDigitColor(); + alarmDigitColor = mms->alarmDigitColor(); + setBackgroundColor(mms->meterBackgroundColor()); + + repaint(); + setModified(true); +} + +void +MultiMeter::applyStyle() +{ + normalDigitColor = KSGRD::Style->firstForegroundColor(); + setBackgroundColor(KSGRD::Style->backgroundColor()); + repaint(); + setModified(true); +} + +void +MultiMeter::setDigitColor(const TQColor& col) +{ + TQPalette p = lcd->palette(); + p.setColor(TQColorGroup::Foreground, col); + lcd->setPalette(p); +} + +void +MultiMeter::setBackgroundColor(const TQColor& col) +{ + lcd->setBackgroundColor(col); + + TQPalette p = lcd->palette(); + p.setColor(TQColorGroup::Light, col); + p.setColor(TQColorGroup::Dark, col); + lcd->setPalette(p); +} diff --git a/ksysguard/gui/SensorDisplayLib/MultiMeterSettings.cc b/ksysguard/gui/SensorDisplayLib/MultiMeterSettings.cc deleted file mode 100644 index 63e8d1d3d..000000000 --- a/ksysguard/gui/SensorDisplayLib/MultiMeterSettings.cc +++ /dev/null @@ -1,123 +0,0 @@ -/* This file is part of the KDE project - Copyright ( C ) 2003 Nadeem Hasan - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "MultiMeterSettings.h" -#include "MultiMeterSettingsWidget.h" - -#include - -MultiMeterSettings::MultiMeterSettings( TQWidget *parent, const char *name ) - : KDialogBase( parent, name, true, i18n( "Multimeter Settings" ), - Ok|Apply|Cancel, Ok, true ) -{ - m_settingsWidget = new MultiMeterSettingsWidget( this, "m_settingsWidget" ); - setMainWidget( m_settingsWidget ); -} - -TQString MultiMeterSettings::title() -{ - return m_settingsWidget->title(); -} - -bool MultiMeterSettings::showUnit() -{ - return m_settingsWidget->showUnit(); -} - -bool MultiMeterSettings::lowerLimitActive() -{ - return m_settingsWidget->lowerLimitActive(); -} - -bool MultiMeterSettings::upperLimitActive() -{ - return m_settingsWidget->upperLimitActive(); -} - -double MultiMeterSettings::lowerLimit() -{ - return m_settingsWidget->lowerLimit(); -} - -double MultiMeterSettings::upperLimit() -{ - return m_settingsWidget->upperLimit(); -} - -TQColor MultiMeterSettings::normalDigitColor() -{ - return m_settingsWidget->normalDigitColor(); -} - -TQColor MultiMeterSettings::alarmDigitColor() -{ - return m_settingsWidget->alarmDigitColor(); -} - -TQColor MultiMeterSettings::meterBackgroundColor() -{ - return m_settingsWidget->meterBackgroundColor(); -} - -void MultiMeterSettings::setTitle( const TQString &title ) -{ - m_settingsWidget->setTitle( title ); -} - -void MultiMeterSettings::setShowUnit( bool b ) -{ - m_settingsWidget->setShowUnit( b ); -} - -void MultiMeterSettings::setLowerLimitActive( bool b ) -{ - m_settingsWidget->setLowerLimitActive( b ); -} - -void MultiMeterSettings::setUpperLimitActive( bool b ) -{ - m_settingsWidget->setUpperLimitActive( b ); -} - -void MultiMeterSettings::setLowerLimit( double limit ) -{ - m_settingsWidget->setLowerLimit( limit ); -} - -void MultiMeterSettings::setUpperLimit( double limit ) -{ - m_settingsWidget->setUpperLimit( limit ); -} - -void MultiMeterSettings::setNormalDigitColor( const TQColor &c ) -{ - m_settingsWidget->setNormalDigitColor( c ); -} - -void MultiMeterSettings::setAlarmDigitColor( const TQColor &c ) -{ - m_settingsWidget->setAlarmDigitColor( c ); -} - -void MultiMeterSettings::setMeterBackgroundColor( const TQColor &c ) -{ - m_settingsWidget->setMeterBackgroundColor( c ); -} - -#include "MultiMeterSettings.moc" diff --git a/ksysguard/gui/SensorDisplayLib/MultiMeterSettings.cpp b/ksysguard/gui/SensorDisplayLib/MultiMeterSettings.cpp new file mode 100644 index 000000000..63e8d1d3d --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/MultiMeterSettings.cpp @@ -0,0 +1,123 @@ +/* This file is part of the KDE project + Copyright ( C ) 2003 Nadeem Hasan + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "MultiMeterSettings.h" +#include "MultiMeterSettingsWidget.h" + +#include + +MultiMeterSettings::MultiMeterSettings( TQWidget *parent, const char *name ) + : KDialogBase( parent, name, true, i18n( "Multimeter Settings" ), + Ok|Apply|Cancel, Ok, true ) +{ + m_settingsWidget = new MultiMeterSettingsWidget( this, "m_settingsWidget" ); + setMainWidget( m_settingsWidget ); +} + +TQString MultiMeterSettings::title() +{ + return m_settingsWidget->title(); +} + +bool MultiMeterSettings::showUnit() +{ + return m_settingsWidget->showUnit(); +} + +bool MultiMeterSettings::lowerLimitActive() +{ + return m_settingsWidget->lowerLimitActive(); +} + +bool MultiMeterSettings::upperLimitActive() +{ + return m_settingsWidget->upperLimitActive(); +} + +double MultiMeterSettings::lowerLimit() +{ + return m_settingsWidget->lowerLimit(); +} + +double MultiMeterSettings::upperLimit() +{ + return m_settingsWidget->upperLimit(); +} + +TQColor MultiMeterSettings::normalDigitColor() +{ + return m_settingsWidget->normalDigitColor(); +} + +TQColor MultiMeterSettings::alarmDigitColor() +{ + return m_settingsWidget->alarmDigitColor(); +} + +TQColor MultiMeterSettings::meterBackgroundColor() +{ + return m_settingsWidget->meterBackgroundColor(); +} + +void MultiMeterSettings::setTitle( const TQString &title ) +{ + m_settingsWidget->setTitle( title ); +} + +void MultiMeterSettings::setShowUnit( bool b ) +{ + m_settingsWidget->setShowUnit( b ); +} + +void MultiMeterSettings::setLowerLimitActive( bool b ) +{ + m_settingsWidget->setLowerLimitActive( b ); +} + +void MultiMeterSettings::setUpperLimitActive( bool b ) +{ + m_settingsWidget->setUpperLimitActive( b ); +} + +void MultiMeterSettings::setLowerLimit( double limit ) +{ + m_settingsWidget->setLowerLimit( limit ); +} + +void MultiMeterSettings::setUpperLimit( double limit ) +{ + m_settingsWidget->setUpperLimit( limit ); +} + +void MultiMeterSettings::setNormalDigitColor( const TQColor &c ) +{ + m_settingsWidget->setNormalDigitColor( c ); +} + +void MultiMeterSettings::setAlarmDigitColor( const TQColor &c ) +{ + m_settingsWidget->setAlarmDigitColor( c ); +} + +void MultiMeterSettings::setMeterBackgroundColor( const TQColor &c ) +{ + m_settingsWidget->setMeterBackgroundColor( c ); +} + +#include "MultiMeterSettings.moc" diff --git a/ksysguard/gui/SensorDisplayLib/ProcessController.cc b/ksysguard/gui/SensorDisplayLib/ProcessController.cc deleted file mode 100644 index 91851d113..000000000 --- a/ksysguard/gui/SensorDisplayLib/ProcessController.cc +++ /dev/null @@ -1,472 +0,0 @@ -/* - KSysGuard, the KDE System Guard - - Copyright (c) 1999 - 2001 Chris Schlaeger - - This program is free software; you can redistribute it and/or - modify it under the terms version 2 of of the GNU General Public - License as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - KSysGuard is currently maintained by Chris Schlaeger . - Please do not commit any changes without consulting me first. Thanks! - -*/ - -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "ProcessController.moc" -#include "SignalIDs.h" - -#include -#include -#include -#include - -#include -#include - - - -ProcessController::ProcessController(TQWidget* parent, const char* name, const TQString &title, bool nf) - : KSGRD::SensorDisplay(parent, name, title, nf) -{ - dict.setAutoDelete(true); - dict.insert("Name", new TQString(i18n("Name"))); - dict.insert("PID", new TQString(i18n("PID"))); - dict.insert("PPID", new TQString(i18n("PPID"))); - dict.insert("UID", new TQString(i18n("UID"))); - dict.insert("GID", new TQString(i18n("GID"))); - dict.insert("Status", new TQString(i18n("Status"))); - dict.insert("User%", new TQString(i18n("User%"))); - dict.insert("System%", new TQString(i18n("System%"))); - dict.insert("Nice", new TQString(i18n("Nice"))); - dict.insert("VmSize", new TQString(i18n("VmSize"))); - dict.insert("VmRss", new TQString(i18n("VmRss"))); - dict.insert("Login", new TQString(i18n("Login"))); - dict.insert("Command", new TQString(i18n("Command"))); - - // Setup the geometry management. - gm = new TQVBoxLayout(this, 10); - TQ_CHECK_PTR(gm); - gm->addSpacing(15); - - gmSearch = new TQHBoxLayout(); - TQ_CHECK_PTR(gmSearch); - gm->addLayout(gmSearch, 0); - - // Create the table that lists the processes. - pList = new ProcessList(this, "pList"); - TQ_CHECK_PTR(pList); - pList->setShowSortIndicator(true); - pListSearchLine = new TDEListViewSearchLineWidget(pList, this, "process_list_search_line"); - gmSearch->addWidget(pListSearchLine, 1); - - connect(pList, TQT_SIGNAL(killProcess(int, int)), - this, TQT_SLOT(killProcess(int, int))); - connect(pList, TQT_SIGNAL(reniceProcess(const TQValueList &, int)), - this, TQT_SLOT(reniceProcess(const TQValueList &, int))); - connect(pList, TQT_SIGNAL(listModified(bool)), - this, TQT_SLOT(setModified(bool))); - - /* Create the combo box to configure the process filter. The - * cbFilter must be created prior to constructing pList as the - * pList constructor sets cbFilter to its start value. */ - cbFilter = new TQComboBox(this, "pList_cbFilter"); - TQ_CHECK_PTR(cbFilter); - gmSearch->addWidget(cbFilter,0); - cbFilter->insertItem(i18n("All Processes"), 0); - cbFilter->insertItem(i18n("System Processes"), 1); - cbFilter->insertItem(i18n("User Processes"), 2); - cbFilter->insertItem(i18n("Own Processes"), 3); - cbFilter->setMinimumSize(cbFilter->sizeHint()); - // Create the check box to switch between tree view and list view. - xbTreeView = new TQCheckBox(i18n("&Tree View"), this, "xbTreeView"); - TQ_CHECK_PTR(xbTreeView); - xbTreeView->setMinimumSize(xbTreeView->sizeHint()); - connect(xbTreeView, TQT_SIGNAL(toggled(bool)), - this, TQT_SLOT(setTreeView(bool))); - - - /* When the both cbFilter and pList are constructed we can connect the - * missing link. */ - connect(cbFilter, TQT_SIGNAL(activated(int)), - this, TQT_SLOT(filterModeChanged(int))); - - // Create the 'Refresh' button. - bRefresh = new KPushButton( KGuiItem( i18n( "&Refresh" ), "reload" ), - this, "bRefresh" ); - TQ_CHECK_PTR(bRefresh); - bRefresh->setMinimumSize(bRefresh->sizeHint()); - connect(bRefresh, TQT_SIGNAL(clicked()), this, TQT_SLOT(updateList())); - - // Create the 'Kill' button. - bKill = new KPushButton(i18n("&Kill"), this, "bKill"); - TQ_CHECK_PTR(bKill); - bKill->setMinimumSize(bKill->sizeHint()); - connect(bKill, TQT_SIGNAL(clicked()), this, TQT_SLOT(killProcess())); - /* Disable the kill button until we know that the daemon supports the - * kill command. */ - bKill->setEnabled(false); - killSupported = false; - - gm->addWidget(pList, 1); - - gm1 = new TQHBoxLayout(); - TQ_CHECK_PTR(gm1); - gm->addLayout(gm1, 0); - gm1->addStretch(); - gm1->addWidget(xbTreeView); - gm1->addStretch(); - gm1->addWidget(bRefresh); - gm1->addStretch(); - gm1->addWidget(bKill); - gm1->addStretch(); - gm->addSpacing(5); - - gm->activate(); - - setPlotterWidget(pList); - - setMinimumSize(sizeHint()); - fixTabOrder(); -} - -void ProcessController::setSearchFocus() { - //stupid search line widget. See rant in fixTabOrder - if(!pListSearchLine->searchLine()) - TQTimer::singleShot(100, this, TQT_SLOT(setSearchFocus())); - else { - pListSearchLine->searchLine()->setFocus(); - } -} -void ProcessController::fixTabOrder() { - - //Wow, I hate this search line widget so much. - //It creates the searchline in a singleshot timer. This makes it totally unpredictable when searchLine is actually valid. - //So we set up singleshot timer and call ourselves over and over until it's ready. - // - //Did i mention I hate this? - if(!pListSearchLine->searchLine()) - TQTimer::singleShot(100, this, TQT_SLOT(fixTabOrder())); - else { - setTabOrder(pListSearchLine->searchLine(), cbFilter); - setTabOrder(cbFilter, pList); - setTabOrder(pList, xbTreeView); - setTabOrder(xbTreeView, bRefresh); - setTabOrder(bRefresh, bKill); - } -} - -void -ProcessController::resizeEvent(TQResizeEvent* ev) -{ - if(frame()) - frame()->setGeometry(0, 0, width(), height()); - - TQWidget::resizeEvent(ev); -} - -bool -ProcessController::addSensor(const TQString& hostName, - const TQString& sensorName, - const TQString& sensorType, - const TQString& title) -{ - if (sensorType != "table") - return (false); - - registerSensor(new KSGRD::SensorProperties(hostName, sensorName, sensorType, title)); - /* This just triggers the first communication. The full set of - * requests are send whenever the sensor reconnects (detected in - * sensorError(). */ - - sendRequest(hostName, "test kill", 4); - - if (title.isEmpty()) - setTitle(i18n("%1: Running Processes").arg(hostName)); - else - setTitle(title); - - return (true); -} - -void -ProcessController::updateList() -{ - sendRequest(sensors().at(0)->hostName(), "ps", 2); -} - -void -ProcessController::killProcess(int pid, int sig) -{ - sendRequest(sensors().at(0)->hostName(), - TQString("kill %1 %2" ).arg(pid).arg(sig), 3); - - if ( !timerOn() ) - // give ksysguardd time to update its proccess list - TQTimer::singleShot(3000, this, TQT_SLOT(updateList())); - else - updateList(); -} - -void -ProcessController::killProcess() -{ - const TQStringList& selectedAsStrings = pList->getSelectedAsStrings(); - if (selectedAsStrings.isEmpty()) - { - KMessageBox::sorry(this, - i18n("You need to select a process first.")); - return; - } - else - { - TQString msg = i18n("Do you want to kill the selected process?", - "Do you want to kill the %n selected processes?", - selectedAsStrings.count()); - - KDialogBase *dlg = new KDialogBase ( i18n ("Kill Process"), - KDialogBase::Yes | KDialogBase::Cancel, - KDialogBase::Yes, KDialogBase::Cancel, this->parentWidget(), - "killconfirmation", - true, true, KGuiItem(i18n("Kill"))); - - bool dontAgain = false; - - int res = KMessageBox::createKMessageBox(dlg, TQMessageBox::Question, - msg, selectedAsStrings, - i18n("Do not ask again"), &dontAgain, - KMessageBox::Notify); - - if (res != KDialogBase::Yes) - { - return; - } - } - - const TQValueList& selectedPIds = pList->getSelectedPIds(); - - // send kill signal to all seleted processes - TQValueListConstIterator it; - for (it = selectedPIds.begin(); it != selectedPIds.end(); ++it) - sendRequest(sensors().at(0)->hostName(), TQString("kill %1 %2" ).arg(*it) - .arg(MENU_ID_SIGKILL), 3); - - if ( !timerOn()) - // give ksysguardd time to update its proccess list - TQTimer::singleShot(3000, this, TQT_SLOT(updateList())); - else - updateList(); -} - -void -ProcessController::reniceProcess(const TQValueList &pids, int niceValue) -{ - for( TQValueList::ConstIterator it = pids.constBegin(), end = pids.constEnd(); it != end; ++it ) - sendRequest(sensors().at(0)->hostName(), - TQString("setpriority %1 %2" ).arg(*it).arg(niceValue), 5); - sendRequest(sensors().at(0)->hostName(), "ps", 2); //update the display afterwards -} - -void -ProcessController::answerReceived(int id, const TQString& answer) -{ - /* We received something, so the sensor is probably ok. */ - sensorError(id, false); - - switch (id) - { - case 1: - { - /* We have received the answer to a ps? command that contains - * the information about the table headers. */ - KSGRD::SensorTokenizer lines(answer, '\n'); - if (lines.count() != 2) - { - kdDebug (1215) << "ProcessController::answerReceived(1)" - "wrong number of lines [" << answer << "]" << endl; - sensorError(id, true); - return; - } - KSGRD::SensorTokenizer headers(lines[0], '\t'); - KSGRD::SensorTokenizer colTypes(lines[1], '\t'); - - pList->removeColumns(); - for (unsigned int i = 0; i < headers.count(); i++) - { - TQString header; - if (dict[headers[i]]) - header = *dict[headers[i]]; - else - header = headers[i]; - pList->addColumn(header, colTypes[i]); - } - - break; - } - case 2: - /* We have received the answer to a ps command that contains a - * list of processes with various additional information. */ - pList->update(answer); - pListSearchLine->searchLine()->updateSearch(); //re-apply the filter - break; - case 3: - { - // result of kill operation - kdDebug(1215) << answer << endl; - KSGRD::SensorTokenizer vals(answer, '\t'); - switch (vals[0].toInt()) - { - case 0: // successful kill operation - break; - case 1: // unknown error - KSGRD::SensorMgr->notify( - i18n("Error while attempting to kill process %1.") - .arg(vals[1])); - break; - case 2: - KSGRD::SensorMgr->notify( - i18n("Insufficient permissions to kill " - "process %1.").arg(vals[1])); - break; - case 3: - KSGRD::SensorMgr->notify( - i18n("Process %1 has already disappeared.") - .arg(vals[1])); - break; - case 4: - KSGRD::SensorMgr->notify(i18n("Invalid Signal.")); - break; - } - break; - } - case 4: - killSupported = (answer.toInt() == 1); - pList->setKillSupported(killSupported); - bKill->setEnabled(killSupported); - break; - case 5: - { - // result of renice operation - kdDebug(1215) << answer << endl; - KSGRD::SensorTokenizer vals(answer, '\t'); - switch (vals[0].toInt()) - { - case 0: // successful renice operation - break; - case 1: // unknown error - KSGRD::SensorMgr->notify( - i18n("Error while attempting to renice process %1.") - .arg(vals[1])); - break; - case 2: - KSGRD::SensorMgr->notify( - i18n("Insufficient permissions to renice " - "process %1.").arg(vals[1])); - break; - case 3: - KSGRD::SensorMgr->notify( - i18n("Process %1 has already disappeared.") - .arg(vals[1])); - break; - case 4: - KSGRD::SensorMgr->notify(i18n("Invalid argument.")); - break; - } - break; - } - } -} - -void -ProcessController::sensorError(int, bool err) -{ - if (err == sensors().at(0)->isOk()) - { - if (!err) - { - /* Whenever the communication with the sensor has been - * (re-)established we need to requests the full set of - * properties again, since the back-end might be a new - * one. */ - sendRequest(sensors().at(0)->hostName(), "test kill", 4); - sendRequest(sensors().at(0)->hostName(), "ps?", 1); - sendRequest(sensors().at(0)->hostName(), "ps", 2); - } - - /* This happens only when the sensorOk status needs to be changed. */ - sensors().at(0)->setIsOk( !err ); - } - setSensorOk(sensors().at(0)->isOk()); -} - -bool -ProcessController::restoreSettings(TQDomElement& element) -{ - bool result = addSensor(element.attribute("hostName"), - element.attribute("sensorName"), (element.attribute("sensorType").isEmpty() ? "table" : element.attribute("sensorType")), - TQString::null); - - xbTreeView->setChecked(element.attribute("tree").toInt()); - setTreeView(element.attribute("tree").toInt()); - - uint filter = element.attribute("filter").toUInt(); - cbFilter->setCurrentItem(filter); - filterModeChanged(filter); - - uint col = element.attribute("sortColumn").toUInt(); - bool inc = element.attribute("incrOrder").toUInt(); - - if (!pList->load(element)) - return (false); - - pList->setSortColumn(col, inc); - - SensorDisplay::restoreSettings(element); - - setModified(false); - - return (result); -} - -bool -ProcessController::saveSettings(TQDomDocument& doc, TQDomElement& element, bool save) -{ - element.setAttribute("hostName", sensors().at(0)->hostName()); - element.setAttribute("sensorName", sensors().at(0)->name()); - element.setAttribute("sensorType", sensors().at(0)->type()); - element.setAttribute("tree", (uint) xbTreeView->isChecked()); - element.setAttribute("filter", cbFilter->currentItem()); - element.setAttribute("sortColumn", pList->getSortColumn()); - element.setAttribute("incrOrder", pList->getIncreasing()); - - if (!pList->save(doc, element)) - return (false); - - SensorDisplay::saveSettings(doc, element); - - if (save) - setModified(false); - - return (true); -} diff --git a/ksysguard/gui/SensorDisplayLib/ProcessController.cpp b/ksysguard/gui/SensorDisplayLib/ProcessController.cpp new file mode 100644 index 000000000..91851d113 --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/ProcessController.cpp @@ -0,0 +1,472 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 1999 - 2001 Chris Schlaeger + + This program is free software; you can redistribute it and/or + modify it under the terms version 2 of of the GNU General Public + License as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + KSysGuard is currently maintained by Chris Schlaeger . + Please do not commit any changes without consulting me first. Thanks! + +*/ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "ProcessController.moc" +#include "SignalIDs.h" + +#include +#include +#include +#include + +#include +#include + + + +ProcessController::ProcessController(TQWidget* parent, const char* name, const TQString &title, bool nf) + : KSGRD::SensorDisplay(parent, name, title, nf) +{ + dict.setAutoDelete(true); + dict.insert("Name", new TQString(i18n("Name"))); + dict.insert("PID", new TQString(i18n("PID"))); + dict.insert("PPID", new TQString(i18n("PPID"))); + dict.insert("UID", new TQString(i18n("UID"))); + dict.insert("GID", new TQString(i18n("GID"))); + dict.insert("Status", new TQString(i18n("Status"))); + dict.insert("User%", new TQString(i18n("User%"))); + dict.insert("System%", new TQString(i18n("System%"))); + dict.insert("Nice", new TQString(i18n("Nice"))); + dict.insert("VmSize", new TQString(i18n("VmSize"))); + dict.insert("VmRss", new TQString(i18n("VmRss"))); + dict.insert("Login", new TQString(i18n("Login"))); + dict.insert("Command", new TQString(i18n("Command"))); + + // Setup the geometry management. + gm = new TQVBoxLayout(this, 10); + TQ_CHECK_PTR(gm); + gm->addSpacing(15); + + gmSearch = new TQHBoxLayout(); + TQ_CHECK_PTR(gmSearch); + gm->addLayout(gmSearch, 0); + + // Create the table that lists the processes. + pList = new ProcessList(this, "pList"); + TQ_CHECK_PTR(pList); + pList->setShowSortIndicator(true); + pListSearchLine = new TDEListViewSearchLineWidget(pList, this, "process_list_search_line"); + gmSearch->addWidget(pListSearchLine, 1); + + connect(pList, TQT_SIGNAL(killProcess(int, int)), + this, TQT_SLOT(killProcess(int, int))); + connect(pList, TQT_SIGNAL(reniceProcess(const TQValueList &, int)), + this, TQT_SLOT(reniceProcess(const TQValueList &, int))); + connect(pList, TQT_SIGNAL(listModified(bool)), + this, TQT_SLOT(setModified(bool))); + + /* Create the combo box to configure the process filter. The + * cbFilter must be created prior to constructing pList as the + * pList constructor sets cbFilter to its start value. */ + cbFilter = new TQComboBox(this, "pList_cbFilter"); + TQ_CHECK_PTR(cbFilter); + gmSearch->addWidget(cbFilter,0); + cbFilter->insertItem(i18n("All Processes"), 0); + cbFilter->insertItem(i18n("System Processes"), 1); + cbFilter->insertItem(i18n("User Processes"), 2); + cbFilter->insertItem(i18n("Own Processes"), 3); + cbFilter->setMinimumSize(cbFilter->sizeHint()); + // Create the check box to switch between tree view and list view. + xbTreeView = new TQCheckBox(i18n("&Tree View"), this, "xbTreeView"); + TQ_CHECK_PTR(xbTreeView); + xbTreeView->setMinimumSize(xbTreeView->sizeHint()); + connect(xbTreeView, TQT_SIGNAL(toggled(bool)), + this, TQT_SLOT(setTreeView(bool))); + + + /* When the both cbFilter and pList are constructed we can connect the + * missing link. */ + connect(cbFilter, TQT_SIGNAL(activated(int)), + this, TQT_SLOT(filterModeChanged(int))); + + // Create the 'Refresh' button. + bRefresh = new KPushButton( KGuiItem( i18n( "&Refresh" ), "reload" ), + this, "bRefresh" ); + TQ_CHECK_PTR(bRefresh); + bRefresh->setMinimumSize(bRefresh->sizeHint()); + connect(bRefresh, TQT_SIGNAL(clicked()), this, TQT_SLOT(updateList())); + + // Create the 'Kill' button. + bKill = new KPushButton(i18n("&Kill"), this, "bKill"); + TQ_CHECK_PTR(bKill); + bKill->setMinimumSize(bKill->sizeHint()); + connect(bKill, TQT_SIGNAL(clicked()), this, TQT_SLOT(killProcess())); + /* Disable the kill button until we know that the daemon supports the + * kill command. */ + bKill->setEnabled(false); + killSupported = false; + + gm->addWidget(pList, 1); + + gm1 = new TQHBoxLayout(); + TQ_CHECK_PTR(gm1); + gm->addLayout(gm1, 0); + gm1->addStretch(); + gm1->addWidget(xbTreeView); + gm1->addStretch(); + gm1->addWidget(bRefresh); + gm1->addStretch(); + gm1->addWidget(bKill); + gm1->addStretch(); + gm->addSpacing(5); + + gm->activate(); + + setPlotterWidget(pList); + + setMinimumSize(sizeHint()); + fixTabOrder(); +} + +void ProcessController::setSearchFocus() { + //stupid search line widget. See rant in fixTabOrder + if(!pListSearchLine->searchLine()) + TQTimer::singleShot(100, this, TQT_SLOT(setSearchFocus())); + else { + pListSearchLine->searchLine()->setFocus(); + } +} +void ProcessController::fixTabOrder() { + + //Wow, I hate this search line widget so much. + //It creates the searchline in a singleshot timer. This makes it totally unpredictable when searchLine is actually valid. + //So we set up singleshot timer and call ourselves over and over until it's ready. + // + //Did i mention I hate this? + if(!pListSearchLine->searchLine()) + TQTimer::singleShot(100, this, TQT_SLOT(fixTabOrder())); + else { + setTabOrder(pListSearchLine->searchLine(), cbFilter); + setTabOrder(cbFilter, pList); + setTabOrder(pList, xbTreeView); + setTabOrder(xbTreeView, bRefresh); + setTabOrder(bRefresh, bKill); + } +} + +void +ProcessController::resizeEvent(TQResizeEvent* ev) +{ + if(frame()) + frame()->setGeometry(0, 0, width(), height()); + + TQWidget::resizeEvent(ev); +} + +bool +ProcessController::addSensor(const TQString& hostName, + const TQString& sensorName, + const TQString& sensorType, + const TQString& title) +{ + if (sensorType != "table") + return (false); + + registerSensor(new KSGRD::SensorProperties(hostName, sensorName, sensorType, title)); + /* This just triggers the first communication. The full set of + * requests are send whenever the sensor reconnects (detected in + * sensorError(). */ + + sendRequest(hostName, "test kill", 4); + + if (title.isEmpty()) + setTitle(i18n("%1: Running Processes").arg(hostName)); + else + setTitle(title); + + return (true); +} + +void +ProcessController::updateList() +{ + sendRequest(sensors().at(0)->hostName(), "ps", 2); +} + +void +ProcessController::killProcess(int pid, int sig) +{ + sendRequest(sensors().at(0)->hostName(), + TQString("kill %1 %2" ).arg(pid).arg(sig), 3); + + if ( !timerOn() ) + // give ksysguardd time to update its proccess list + TQTimer::singleShot(3000, this, TQT_SLOT(updateList())); + else + updateList(); +} + +void +ProcessController::killProcess() +{ + const TQStringList& selectedAsStrings = pList->getSelectedAsStrings(); + if (selectedAsStrings.isEmpty()) + { + KMessageBox::sorry(this, + i18n("You need to select a process first.")); + return; + } + else + { + TQString msg = i18n("Do you want to kill the selected process?", + "Do you want to kill the %n selected processes?", + selectedAsStrings.count()); + + KDialogBase *dlg = new KDialogBase ( i18n ("Kill Process"), + KDialogBase::Yes | KDialogBase::Cancel, + KDialogBase::Yes, KDialogBase::Cancel, this->parentWidget(), + "killconfirmation", + true, true, KGuiItem(i18n("Kill"))); + + bool dontAgain = false; + + int res = KMessageBox::createKMessageBox(dlg, TQMessageBox::Question, + msg, selectedAsStrings, + i18n("Do not ask again"), &dontAgain, + KMessageBox::Notify); + + if (res != KDialogBase::Yes) + { + return; + } + } + + const TQValueList& selectedPIds = pList->getSelectedPIds(); + + // send kill signal to all seleted processes + TQValueListConstIterator it; + for (it = selectedPIds.begin(); it != selectedPIds.end(); ++it) + sendRequest(sensors().at(0)->hostName(), TQString("kill %1 %2" ).arg(*it) + .arg(MENU_ID_SIGKILL), 3); + + if ( !timerOn()) + // give ksysguardd time to update its proccess list + TQTimer::singleShot(3000, this, TQT_SLOT(updateList())); + else + updateList(); +} + +void +ProcessController::reniceProcess(const TQValueList &pids, int niceValue) +{ + for( TQValueList::ConstIterator it = pids.constBegin(), end = pids.constEnd(); it != end; ++it ) + sendRequest(sensors().at(0)->hostName(), + TQString("setpriority %1 %2" ).arg(*it).arg(niceValue), 5); + sendRequest(sensors().at(0)->hostName(), "ps", 2); //update the display afterwards +} + +void +ProcessController::answerReceived(int id, const TQString& answer) +{ + /* We received something, so the sensor is probably ok. */ + sensorError(id, false); + + switch (id) + { + case 1: + { + /* We have received the answer to a ps? command that contains + * the information about the table headers. */ + KSGRD::SensorTokenizer lines(answer, '\n'); + if (lines.count() != 2) + { + kdDebug (1215) << "ProcessController::answerReceived(1)" + "wrong number of lines [" << answer << "]" << endl; + sensorError(id, true); + return; + } + KSGRD::SensorTokenizer headers(lines[0], '\t'); + KSGRD::SensorTokenizer colTypes(lines[1], '\t'); + + pList->removeColumns(); + for (unsigned int i = 0; i < headers.count(); i++) + { + TQString header; + if (dict[headers[i]]) + header = *dict[headers[i]]; + else + header = headers[i]; + pList->addColumn(header, colTypes[i]); + } + + break; + } + case 2: + /* We have received the answer to a ps command that contains a + * list of processes with various additional information. */ + pList->update(answer); + pListSearchLine->searchLine()->updateSearch(); //re-apply the filter + break; + case 3: + { + // result of kill operation + kdDebug(1215) << answer << endl; + KSGRD::SensorTokenizer vals(answer, '\t'); + switch (vals[0].toInt()) + { + case 0: // successful kill operation + break; + case 1: // unknown error + KSGRD::SensorMgr->notify( + i18n("Error while attempting to kill process %1.") + .arg(vals[1])); + break; + case 2: + KSGRD::SensorMgr->notify( + i18n("Insufficient permissions to kill " + "process %1.").arg(vals[1])); + break; + case 3: + KSGRD::SensorMgr->notify( + i18n("Process %1 has already disappeared.") + .arg(vals[1])); + break; + case 4: + KSGRD::SensorMgr->notify(i18n("Invalid Signal.")); + break; + } + break; + } + case 4: + killSupported = (answer.toInt() == 1); + pList->setKillSupported(killSupported); + bKill->setEnabled(killSupported); + break; + case 5: + { + // result of renice operation + kdDebug(1215) << answer << endl; + KSGRD::SensorTokenizer vals(answer, '\t'); + switch (vals[0].toInt()) + { + case 0: // successful renice operation + break; + case 1: // unknown error + KSGRD::SensorMgr->notify( + i18n("Error while attempting to renice process %1.") + .arg(vals[1])); + break; + case 2: + KSGRD::SensorMgr->notify( + i18n("Insufficient permissions to renice " + "process %1.").arg(vals[1])); + break; + case 3: + KSGRD::SensorMgr->notify( + i18n("Process %1 has already disappeared.") + .arg(vals[1])); + break; + case 4: + KSGRD::SensorMgr->notify(i18n("Invalid argument.")); + break; + } + break; + } + } +} + +void +ProcessController::sensorError(int, bool err) +{ + if (err == sensors().at(0)->isOk()) + { + if (!err) + { + /* Whenever the communication with the sensor has been + * (re-)established we need to requests the full set of + * properties again, since the back-end might be a new + * one. */ + sendRequest(sensors().at(0)->hostName(), "test kill", 4); + sendRequest(sensors().at(0)->hostName(), "ps?", 1); + sendRequest(sensors().at(0)->hostName(), "ps", 2); + } + + /* This happens only when the sensorOk status needs to be changed. */ + sensors().at(0)->setIsOk( !err ); + } + setSensorOk(sensors().at(0)->isOk()); +} + +bool +ProcessController::restoreSettings(TQDomElement& element) +{ + bool result = addSensor(element.attribute("hostName"), + element.attribute("sensorName"), (element.attribute("sensorType").isEmpty() ? "table" : element.attribute("sensorType")), + TQString::null); + + xbTreeView->setChecked(element.attribute("tree").toInt()); + setTreeView(element.attribute("tree").toInt()); + + uint filter = element.attribute("filter").toUInt(); + cbFilter->setCurrentItem(filter); + filterModeChanged(filter); + + uint col = element.attribute("sortColumn").toUInt(); + bool inc = element.attribute("incrOrder").toUInt(); + + if (!pList->load(element)) + return (false); + + pList->setSortColumn(col, inc); + + SensorDisplay::restoreSettings(element); + + setModified(false); + + return (result); +} + +bool +ProcessController::saveSettings(TQDomDocument& doc, TQDomElement& element, bool save) +{ + element.setAttribute("hostName", sensors().at(0)->hostName()); + element.setAttribute("sensorName", sensors().at(0)->name()); + element.setAttribute("sensorType", sensors().at(0)->type()); + element.setAttribute("tree", (uint) xbTreeView->isChecked()); + element.setAttribute("filter", cbFilter->currentItem()); + element.setAttribute("sortColumn", pList->getSortColumn()); + element.setAttribute("incrOrder", pList->getIncreasing()); + + if (!pList->save(doc, element)) + return (false); + + SensorDisplay::saveSettings(doc, element); + + if (save) + setModified(false); + + return (true); +} diff --git a/ksysguard/gui/SensorDisplayLib/ProcessList.cc b/ksysguard/gui/SensorDisplayLib/ProcessList.cc deleted file mode 100644 index 9293ef6a0..000000000 --- a/ksysguard/gui/SensorDisplayLib/ProcessList.cc +++ /dev/null @@ -1,977 +0,0 @@ -/* - KSysGuard, the KDE System Guard - - Copyright (C) 1997 Bernd Johannes Wuebben - - - Copyright (C) 1998 Nicolas Leclercq - - Copyright (c) 1999, 2000, 2001, 2002 Chris Schlaeger - - This program is free software; you can redistribute it and/or - modify it under the terms of version 2 of the GNU General Public - License as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - KSysGuard is currently maintained by Chris Schlaeger . - Please do not commit any changes without consulting me first. Thanks! - -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "ProcessController.h" -#include "ProcessList.h" -#include "ReniceDlg.h" -#include "SignalIDs.h" - -#define NONE -1 -#define INIT_PID 1 - -//extern const char* intKey(const char* text); -//extern const char* timeKey(const char* text); -//extern const char* floatKey(const char* text); - -TQDict ProcessList::aliases; - -int ProcessLVI::compare( TQListViewItem *item, int col, bool ascending ) const -{ - int type = ((ProcessList*)listView())->columnType( col ); - - if ( type == ProcessList::Int ) { - int prev = (int)TDEGlobal::locale()->readNumber( key( col, ascending ) ); - int next = (int)TDEGlobal::locale()->readNumber( item->key( col, ascending ) ); - if ( prev < next ) - return -1; - else if ( prev == next ) - return 0; - else - return 1; - } - - if ( type == ProcessList::Float ) { - double prev = TDEGlobal::locale()->readNumber( key( col, ascending ) ); - double next = TDEGlobal::locale()->readNumber( item->key( col, ascending ) ); - if ( prev < next ) - return -1; - else - return 1; - } - - if ( type == ProcessList::Time ) { - int hourPrev, hourNext, minutesPrev, minutesNext; - sscanf( key( col, ascending ).latin1(), "%d:%d", &hourPrev, &minutesPrev ); - sscanf( item->key( col, ascending ).latin1(), "%d:%d", &hourNext, &minutesNext ); - int prev = hourPrev * 60 + minutesPrev; - int next = hourNext * 60 + minutesNext; - if ( prev < next ) - return -1; - else if ( prev == next ) - return 0; - else - return 1; - } - - return key( col, ascending ).localeAwareCompare( item->key( col, ascending ) ); -} - -ProcessList::ProcessList(TQWidget *parent, const char* name) - : TDEListView(parent, name) -{ - iconCache.setAutoDelete(true); - - columnDict.setAutoDelete(true); - columnDict.insert("running", - new TQString(i18n("process status", "running"))); - columnDict.insert("sleeping", - new TQString(i18n("process status", "sleeping"))); - columnDict.insert("disk sleep", - new TQString(i18n("process status", "disk sleep"))); - columnDict.insert("zombie", new TQString(i18n("process status", "zombie"))); - columnDict.insert("stopped", - new TQString(i18n("process status", "stopped"))); - columnDict.insert("paging", new TQString(i18n("process status", "paging"))); - columnDict.insert("idle", new TQString(i18n("process status", "idle"))); - - if (aliases.isEmpty()) - { -#ifdef Q_OS_LINUX - aliases.insert("init", new TQString("penguin")); -#else - aliases.insert("init", new TQString("system")); -#endif - /* kernel stuff */ - aliases.insert("bdflush", new TQString("kernel")); - aliases.insert("dhcpcd", new TQString("kernel")); - aliases.insert("kapm-idled", new TQString("kernel")); - aliases.insert("keventd", new TQString("kernel")); - aliases.insert("khubd", new TQString("kernel")); - aliases.insert("klogd", new TQString("kernel")); - aliases.insert("kreclaimd", new TQString("kernel")); - aliases.insert("kreiserfsd", new TQString("kernel")); - aliases.insert("ksoftirqd_CPU0", new TQString("kernel")); - aliases.insert("ksoftirqd_CPU1", new TQString("kernel")); - aliases.insert("ksoftirqd_CPU2", new TQString("kernel")); - aliases.insert("ksoftirqd_CPU3", new TQString("kernel")); - aliases.insert("ksoftirqd_CPU4", new TQString("kernel")); - aliases.insert("ksoftirqd_CPU5", new TQString("kernel")); - aliases.insert("ksoftirqd_CPU6", new TQString("kernel")); - aliases.insert("ksoftirqd_CPU7", new TQString("kernel")); - aliases.insert("kswapd", new TQString("kernel")); - aliases.insert("kupdated", new TQString("kernel")); - aliases.insert("mdrecoveryd", new TQString("kernel")); - aliases.insert("scsi_eh_0", new TQString("kernel")); - aliases.insert("scsi_eh_1", new TQString("kernel")); - aliases.insert("scsi_eh_2", new TQString("kernel")); - aliases.insert("scsi_eh_3", new TQString("kernel")); - aliases.insert("scsi_eh_4", new TQString("kernel")); - aliases.insert("scsi_eh_5", new TQString("kernel")); - aliases.insert("scsi_eh_6", new TQString("kernel")); - aliases.insert("scsi_eh_7", new TQString("kernel")); - /* daemon and other service providers */ - aliases.insert("artsd", new TQString("daemon")); - aliases.insert("atd", new TQString("daemon")); - aliases.insert("automount", new TQString("daemon")); - aliases.insert("cardmgr", new TQString("daemon")); - aliases.insert("cron", new TQString("daemon")); - aliases.insert("cupsd", new TQString("daemon")); - aliases.insert("in.identd", new TQString("daemon")); - aliases.insert("lpd", new TQString("daemon")); - aliases.insert("mingetty", new TQString("daemon")); - aliases.insert("nscd", new TQString("daemon")); - aliases.insert("portmap", new TQString("daemon")); - aliases.insert("rpc.statd", new TQString("daemon")); - aliases.insert("rpciod", new TQString("daemon")); - aliases.insert("sendmail", new TQString("daemon")); - aliases.insert("sshd", new TQString("daemon")); - aliases.insert("syslogd", new TQString("daemon")); - aliases.insert("usbmgr", new TQString("daemon")); - aliases.insert("wwwoffled", new TQString("daemon")); - aliases.insert("xntpd", new TQString("daemon")); - aliases.insert("ypbind", new TQString("daemon")); - aliases.insert("apmd", new TQString("daemon")); - aliases.insert("getty", new TQString("daemon")); - aliases.insert("mountd", new TQString("daemon")); - aliases.insert("inetd", new TQString("daemon")); - aliases.insert("nfsd", new TQString("daemon")); - aliases.insert("wsmoused", new TQString("daemon")); - /* kde applications */ - aliases.insert("appletproxy", new TQString("tdeapp")); - aliases.insert("dcopserver", new TQString("tdeapp")); - aliases.insert("kcookiejar", new TQString("tdeapp")); - aliases.insert("kde", new TQString("tdeapp")); - aliases.insert("kded", new TQString("tdeapp")); - aliases.insert("tdeinit", new TQString("tdeapp")); - aliases.insert("kdesktop", new TQString("tdeapp")); - aliases.insert("tdesud", new TQString("tdeapp")); - aliases.insert("tdm", new TQString("tdeapp")); - aliases.insert("khotkeys", new TQString("tdeapp")); - aliases.insert("tdeio_file", new TQString("tdeapp")); - aliases.insert("tdeio_uiserver", new TQString("tdeapp")); - aliases.insert("tdelauncher", new TQString("tdeapp")); - aliases.insert("ksmserver", new TQString("tdeapp")); - aliases.insert("kwrapper", new TQString("tdeapp")); - aliases.insert("kwrited", new TQString("tdeapp")); - aliases.insert("kxmlrpcd", new TQString("tdeapp")); - aliases.insert("starttde", new TQString("tdeapp")); - /* other processes */ - aliases.insert("bash", new TQString("shell")); - aliases.insert("cat", new TQString("tools")); - aliases.insert("egrep", new TQString("tools")); - aliases.insert("emacs", new TQString("application-vnd.oasis.opendocument.text")); - aliases.insert("fgrep", new TQString("tools")); - aliases.insert("find", new TQString("tools")); - aliases.insert("grep", new TQString("tools")); - aliases.insert("ksh", new TQString("shell")); - aliases.insert("screen", new TQString("openterm")); - aliases.insert("sh", new TQString("shell")); - aliases.insert("sort", new TQString("tools")); - aliases.insert("ssh", new TQString("shell")); - aliases.insert("su", new TQString("tools")); - aliases.insert("tcsh", new TQString("shell")); - aliases.insert("tee", new TQString("tools")); - aliases.insert("vi", new TQString("application-vnd.oasis.opendocument.text")); - aliases.insert("vim", new TQString("application-vnd.oasis.opendocument.text")); - } - - /* The filter mode is controlled by a combo box of the parent. If - * the mode is changed we get a signal. */ - connect(parent, TQT_SIGNAL(setFilterMode(int)), - this, TQT_SLOT(setFilterMode(int))); - - /* We need to catch this signal to show various popup menues. */ - connect(this, - TQT_SIGNAL(rightButtonPressed(TQListViewItem*, const TQPoint&, int)), - this, - TQT_SLOT(handleRMBPressed(TQListViewItem*, const TQPoint&, int))); - - /* Since Qt does not tell us the sorting details we have to do our - * own bookkeping, so we can save and restore the sorting - * settings. */ - connect(header(), TQT_SIGNAL(clicked(int)), this, TQT_SLOT(sortingChanged(int))); - - ctrlKeyDown = false; - shiftKeyDown = false; - treeViewEnabled = false; - openAll = true; - - filterMode = FILTER_ALL; - - sortColumn = 1; - increasing = false; - - // Elements in the process list may only live in this list. - pl.setAutoDelete(true); - - setItemMargin(2); - setAllColumnsShowFocus(true); - setTreeStepSize(17); - setSorting(sortColumn, increasing); - setSelectionMode(TQListView::Extended); - - // Create popup menu for RMB clicks on table header - headerPM = new TQPopupMenu(); - headerPM->insertItem(i18n("Remove Column"), HEADER_REMOVE); - headerPM->insertItem(i18n("Add Column"), HEADER_ADD); - headerPM->insertItem(i18n("Help on Column"), HEADER_HELP); - - connect(header(), TQT_SIGNAL(sizeChange(int, int, int)), - this, TQT_SLOT(sizeChanged(int, int, int))); - connect(header(), TQT_SIGNAL(indexChange(int, int, int)), - this, TQT_SLOT(indexChanged(int, int, int))); - - killSupported = false; - setModified(false); -} - -ProcessList::~ProcessList() -{ - delete(headerPM); -} - -const TQValueList& -ProcessList::getSelectedPIds() -{ - selectedPIds.clear(); - // iterate through all selected visible items of the listview - TQListViewItemIterator it(this, TQListViewItemIterator::Visible | TQListViewItemIterator::Selected ); - for ( ; it.current(); ++it ) - selectedPIds.append(it.current()->text(1).toInt()); - - return (selectedPIds); -} - -const TQStringList& -ProcessList::getSelectedAsStrings() -{ - selectedAsStrings.clear(); - // iterate through all selected visible items of the listview - TQListViewItemIterator it(this, TQListViewItemIterator::Visible | TQListViewItemIterator::Selected ); - TQString spaces; - for ( ; it.current(); ++it ) { - spaces.fill(TQChar(' '), 7 - it.current()->text(1).length()); - selectedAsStrings.append("(PID: " + it.current()->text(1) + ")" + spaces + " " + it.current()->text(0)); - } - - return (selectedAsStrings); -} -bool -ProcessList::update(const TQString& list) -{ - if ((!shiftKeyDown) && (!ctrlKeyDown)) - { - /* Disable painting to avoid flickering effects, - * especially when in tree view mode. - * Ditto for the scrollbar. */ - setUpdatesEnabled(false); - viewport()->setUpdatesEnabled(false); - - pl.clear(); - - // Convert ps answer in a list of tokenized lines - KSGRD::SensorTokenizer procs(list, '\n'); - for (unsigned int i = 0; i < procs.count(); i++) - { - KSGRD::SensorPSLine* line = new KSGRD::SensorPSLine(procs[i]); - if (line->count() != (uint) columns()) - { -#if 0 - // This is needed for debugging only. - kdDebug(1215) << list << endl; - TQString l; - for (uint j = 0; j < line->count(); j++) - l += (*line)[j] + "|"; - kdDebug(1215) << "Incomplete ps line:" << l << endl; -#endif - return (false); - } - else - pl.append(line); - } - - int currItemPos = itemPos(currentItem()); - int vpos = verticalScrollBar()->value(); - int hpos = horizontalScrollBar()->value(); - - updateMetaInfo(); - - clear(); - - if (treeViewEnabled) - buildTree(); - else - buildList(); - - TQListViewItemIterator it( this ); - while ( it.current() ) { - if ( itemPos( it.current() ) == currItemPos ) { - setCurrentItem( it.current() ); - break; - } - ++it; - } - - verticalScrollBar()->setValue(vpos); - horizontalScrollBar()->setValue(hpos); - - // Re-enable painting, and force an update. - setUpdatesEnabled(true); - viewport()->setUpdatesEnabled(true); - - triggerUpdate(); - } - - return (true); -} - -void -ProcessList::setTreeView(bool tv) -{ - if ((treeViewEnabled = tv)) - { - savedWidth[0] = columnWidth(0); - openAll = true; - } - else - { - /* In tree view the first column is wider than in list view mode. - * So we shrink it to 1 pixel. The next update will resize it again - * appropriately. */ - setColumnWidth(0, savedWidth[0]); - } - /* In tree view mode borders are added to the icons. So we have to clear - * the cache when we change the tree view mode. */ - iconCache.clear(); -} - -bool -ProcessList::load(TQDomElement& el) -{ - TQDomNodeList dnList = el.elementsByTagName("column"); - for (uint i = 0; i < dnList.count(); ++i) - { - TQDomElement lel = dnList.item(i).toElement(); - if (savedWidth.count() <= i) - savedWidth.append(lel.attribute("savedWidth").toInt()); - else - savedWidth[i] = lel.attribute("savedWidth").toInt(); - if (currentWidth.count() <= i) - currentWidth.append(lel.attribute("currentWidth").toInt()); - else - currentWidth[i] = lel.attribute("currentWidth").toInt(); - if (index.count() <= i) - index.append(lel.attribute("index").toInt()); - else - index[i] = lel.attribute("index").toInt(); - } - - setModified(false); - - return (true); -} - -bool -ProcessList::save(TQDomDocument& doc, TQDomElement& display) -{ - for (int i = 0; i < columns(); ++i) - { - TQDomElement col = doc.createElement("column"); - display.appendChild(col); - col.setAttribute("currentWidth", columnWidth(i)); - col.setAttribute("savedWidth", savedWidth[i]); - col.setAttribute("index", header()->mapToIndex(i)); - } - - setModified(false); - - return (true); -} - -void -ProcessList::sortingChanged(int col) -{ - if (col == sortColumn) - increasing = !increasing; - else - { - sortColumn = col; - increasing = true; - } - setSorting(sortColumn, increasing); - setModified(true); -} - -int ProcessList::columnType( uint pos ) const -{ - if ( pos >= mColumnTypes.count() ) - return 0; - - if ( mColumnTypes[ pos ] == "d" || mColumnTypes[ pos ] == "D" ) - return Int; - else if ( mColumnTypes[ pos ] == "f" || mColumnTypes[ pos ] == "F" ) - return Float; - else if ( mColumnTypes[ pos ] == "t" ) - return Time; - else - return Text; -} - -bool -ProcessList::matchesFilter(KSGRD::SensorPSLine* p) const -{ - // This mechanism is likely to change in the future! - - switch (filterMode) - { - case FILTER_ALL: - return (true); - - case FILTER_SYSTEM: - return (p->uid() < 100 ? true : false); - - case FILTER_USER: - return (p->uid() >= 100 ? true : false); - - case FILTER_OWN: - default: - return (p->uid() == (long) getuid() ? true : false); - } -} - -void -ProcessList::buildList() -{ - /* Get the first process in the list, check whether it matches the - * filter and append it to TQListView widget if so. */ - while (!pl.isEmpty()) - { - KSGRD::SensorPSLine* p = pl.first(); - - if (matchesFilter(p)) - { - ProcessLVI* pli = new ProcessLVI(this); - - addProcess(p, pli); - - if (selectedPIds.findIndex(p->pid()) != -1) - pli->setSelected(true); - } - pl.removeFirst(); - } -} - -void -ProcessList::buildTree() -{ - // remove all leaves that do not match the filter - deleteLeaves(); - - KSGRD::SensorPSLine* ps = pl.first(); - - while (ps) - { - if (ps->pid() == INIT_PID) - { - // insert root item into the tree widget - ProcessLVI* pli = new ProcessLVI(this); - addProcess(ps, pli); - - // remove the process from the process list, ps is now invalid - int pid = ps->pid(); - pl.remove(); - - if (selectedPIds.findIndex(pid) != -1) - pli->setSelected(true); - - // insert all child processes of current process - extendTree(&pl, pli, pid); - break; - } - else - ps = pl.next(); - } -} - -void -ProcessList::deleteLeaves(void) -{ - for ( ; ; ) - { - unsigned int i; - for (i = 0; i < pl.count() && - (!isLeafProcess(pl.at(i)->pid()) || - matchesFilter(pl.at(i))); i++) - ; - if (i == pl.count()) - return; - - pl.remove(i); - } -} - -bool -ProcessList::isLeafProcess(int pid) -{ - for (unsigned int i = 0; i < pl.count(); i++) - if (pl.at(i)->ppid() == pid) - return (false); - - return (true); -} - -void -ProcessList::extendTree(TQPtrList* pl, ProcessLVI* parent, int ppid) -{ - KSGRD::SensorPSLine* ps; - - // start at top list - ps = pl->first(); - - while (ps) - { - // look for a child process of the current parent - if (ps->ppid() == ppid) - { - ProcessLVI* pli = new ProcessLVI(parent); - - addProcess(ps, pli); - - if (selectedPIds.findIndex(ps->pid()) != -1) - pli->setSelected(true); - - if (ps->ppid() != INIT_PID && closedSubTrees.findIndex(ps->ppid()) != -1) - parent->setOpen(false); - else - parent->setOpen(true); - - // remove the process from the process list, ps is now invalid - int pid = ps->pid(); - pl->remove(); - - // now look for the childs of the inserted process - extendTree(pl, pli, pid); - - /* Since buildTree can remove processes from the list we - * can't find a "current" process. So we start searching - * at the top again. It's no endless loops since this - * branch is only entered when there are children of the - * current parent in the list. When we have removed them - * all the while loop will exit. */ - ps = pl->first(); - } - else - ps = pl->next(); - } -} -void -ProcessList::addProcess(KSGRD::SensorPSLine* p, ProcessLVI* pli) -{ - TQString name = p->name(); - if (aliases[name]) - name = *aliases[name]; - - /* Get icon from icon list that might be appropriate for a process - * with this name. */ - TQPixmap pix; - if (!iconCache[name]) - { - pix = TDEGlobal::iconLoader()->loadIcon(name, TDEIcon::Small, - TDEIcon::SizeSmall, TDEIcon::DefaultState, - 0L, true); - if (pix.isNull() || !pix.mask()) - pix = TDEGlobal::iconLoader()->loadIcon("unknownapp", TDEIcon::User, - TDEIcon::SizeSmall); - - if (pix.width() != 16 || pix.height() != 16) - { - /* I guess this isn't needed too often. The TDEIconLoader should - * scale the pixmaps already appropriately. Since I got a bug - * report claiming that it doesn't work with GNOME apps I've - * added this safeguard. */ - TQImage img; - img = pix; - img.smoothScale(16, 16); - pix = img; - } - /* We copy the icon into a 24x16 pixmap to add a 4 pixel margin on - * the left and right side. In tree view mode we use the original - * icon. */ - TQPixmap icon(24, 16, pix.depth()); - if (!treeViewEnabled) - { - icon.fill(); - bitBlt(&icon, 4, 0, &pix, 0, 0, pix.width(), pix.height()); - TQBitmap mask(24, 16, true); - bitBlt(&mask, 4, 0, pix.mask(), 0, 0, pix.width(), pix.height()); - icon.setMask(mask); - pix = icon; - } - iconCache.insert(name, new TQPixmap(pix)); - } - else - pix = *(iconCache[name]); - - // icon + process name - pli->setPixmap(0, pix); - pli->setText(0, p->name()); - - // insert remaining field into table - for (unsigned int col = 1; col < p->count(); col++) - { - if (mColumnTypes[col] == "S" && columnDict[(*p)[col]]) - pli->setText(col, *columnDict[(*p)[col]]); - else if ( mColumnTypes[col] == "f" ) - pli->setText( col, TDEGlobal::locale()->formatNumber( (*p)[col].toFloat() ) ); - else if ( mColumnTypes[col] == "D" ) - pli->setText( col, TDEGlobal::locale()->formatNumber( (*p)[col].toInt(), 0 ) ); - else - pli->setText(col, (*p)[col]); - } -} - -void -ProcessList::updateMetaInfo(void) -{ - selectedPIds.clear(); - closedSubTrees.clear(); - - TQListViewItemIterator it(this); - - // iterate through all items of the listview - for ( ; it.current(); ++it ) - { - if (it.current()->isSelected() && it.current()->isVisible()) - selectedPIds.append(it.current()->text(1).toInt()); - if (treeViewEnabled && !it.current()->isOpen()) - closedSubTrees.append(it.current()->text(1).toInt()); - } - - /* In list view mode all list items are set to closed by TQListView. - * If the tree view is now selected, all item will be closed. This is - * annoying. So we use the openAll flag to force all trees to open when - * the treeViewEnbled flag was set to true. */ - if (openAll) - { - if (treeViewEnabled) - closedSubTrees.clear(); - openAll = false; - } -} - -void -ProcessList::removeColumns(void) -{ - for (int i = columns() - 1; i >= 0; --i) - removeColumn(i); -} - -void -ProcessList::addColumn(const TQString& label, const TQString& type) -{ - TQListView::addColumn(label); - uint col = columns() - 1; - if (type == "s" || type == "S") - setColumnAlignment(col, AlignLeft); - else if (type == "d" || type == "D") - setColumnAlignment(col, AlignRight); - else if (type == "t") - setColumnAlignment(col, AlignRight); - else if (type == "f") - setColumnAlignment(col, AlignRight); - else - { - kdDebug(1215) << "Unknown type " << type << " of column " << label - << " in ProcessList!" << endl; - return; - } - - mColumnTypes.append(type); - - /* Just use some sensible default values as initial setting. */ - TQFontMetrics fm = fontMetrics(); - setColumnWidth(col, fm.width(label) + 10); - - if (currentWidth.count() - 1 == col) - { - /* Table has been loaded from file. We can restore the settings - * when the last column has been added. */ - for (uint i = 0; i < col; ++i) - { - /* In case the language has been changed the column width - * might need to be increased. */ - if (currentWidth[i] == 0) - { - if (fm.width(header()->label(i)) + 10 > savedWidth[i]) - savedWidth[i] = fm.width(header()->label(i)) + 10; - setColumnWidth(i, 0); - } - else - { - if (fm.width(header()->label(i)) + 10 > currentWidth[i]) - setColumnWidth(i, fm.width(header()->label(i)) + 10); - else - setColumnWidth(i, currentWidth[i]); - } - setColumnWidthMode(i, currentWidth[i] == 0 ? - TQListView::Manual : TQListView::Maximum); - header()->moveSection(i, index[i]); - } - setSorting(sortColumn, increasing); - } -} - -void -ProcessList::handleRMBPressed(TQListViewItem* lvi, const TQPoint& p, int col) -{ - if (!lvi) - return; - - lvi->setSelected( true ); - - /* lvi is only valid until the next time we hit the main event - * loop. So we need to save the information we need after calling - * processPM->exec(). */ - int currentPId = lvi->text(1).toInt(); - - int currentNiceValue = 0; - for (int i = 0; i < columns(); ++i) - if (TQString::compare(header()->label(i), i18n("Nice")) == 0) - currentNiceValue = lvi->text(i).toInt(); - - TQPopupMenu processPM; - if (columnWidth(col) != 0) - processPM.insertItem(i18n("Hide Column"), 5); - TQPopupMenu* hiddenPM = new TQPopupMenu(&processPM); - for (int i = 0; i < columns(); ++i) - if (columnWidth(i) == 0) - hiddenPM->insertItem(header()->label(i), i + 100); - if(columns()) - processPM.insertItem(i18n("Show Column"), hiddenPM); - - processPM.insertSeparator(); - - processPM.insertItem(i18n("Select All Processes"), 1); - processPM.insertItem(i18n("Unselect All Processes"), 2); - - TQPopupMenu* signalPM = new TQPopupMenu(&processPM); - if (killSupported && lvi->isSelected()) - { - processPM.insertSeparator(); - processPM.insertItem(i18n("Select All Child Processes"), 3); - processPM.insertItem(i18n("Unselect All Child Processes"), 4); - - signalPM->insertItem(i18n("SIGABRT"), MENU_ID_SIGABRT); - signalPM->insertItem(i18n("SIGALRM"), MENU_ID_SIGALRM); - signalPM->insertItem(i18n("SIGCHLD"), MENU_ID_SIGCHLD); - signalPM->insertItem(i18n("SIGCONT"), MENU_ID_SIGCONT); - signalPM->insertItem(i18n("SIGFPE"), MENU_ID_SIGFPE); - signalPM->insertItem(i18n("SIGHUP"), MENU_ID_SIGHUP); - signalPM->insertItem(i18n("SIGILL"), MENU_ID_SIGILL); - signalPM->insertItem(i18n("SIGINT"), MENU_ID_SIGINT); - signalPM->insertItem(i18n("SIGKILL"), MENU_ID_SIGKILL); - signalPM->insertItem(i18n("SIGPIPE"), MENU_ID_SIGPIPE); - signalPM->insertItem(i18n("SIGQUIT"), MENU_ID_SIGQUIT); - signalPM->insertItem(i18n("SIGSEGV"), MENU_ID_SIGSEGV); - signalPM->insertItem(i18n("SIGSTOP"), MENU_ID_SIGSTOP); - signalPM->insertItem(i18n("SIGTERM"), MENU_ID_SIGTERM); - signalPM->insertItem(i18n("SIGTSTP"), MENU_ID_SIGTSTP); - signalPM->insertItem(i18n("SIGTTIN"), MENU_ID_SIGTTIN); - signalPM->insertItem(i18n("SIGTTOU"), MENU_ID_SIGTTOU); - signalPM->insertItem(i18n("SIGUSR1"), MENU_ID_SIGUSR1); - signalPM->insertItem(i18n("SIGUSR2"), MENU_ID_SIGUSR2); - - processPM.insertSeparator(); - processPM.insertItem(i18n("Send Signal"), signalPM); - } - - /* differ between killSupported and reniceSupported in a future - * version. */ - if (killSupported && lvi->isSelected()) - { - processPM.insertSeparator(); - processPM.insertItem(i18n("Renice Process..."), 300); - } - - int id; - switch (id = processPM.exec(p)) - { - case -1: - break; - case 1: - case 2: - selectAllItems(id & 1); - break; - case 3: - case 4: - selectAllChilds(currentPId, id & 1); - break; - case 5: - setColumnWidthMode(col, TQListView::Manual); - savedWidth[col] = columnWidth(col); - setColumnWidth(col, 0); - setModified(true); - break; - case 300: - { - ReniceDlg reniceDlg(this, "reniceDlg", currentNiceValue, currentPId); - - int reniceVal; - if ((reniceVal = reniceDlg.exec()) != 40) { - emit reniceProcess(selectedPIds, reniceVal); - } - } - break; - default: - /* IDs < 100 are used for signals. */ - if (id < 100) - { - /* we go through list to get all task also - when update interval is paused */ - selectedPIds.clear(); - TQListViewItemIterator it(this, TQListViewItemIterator::Visible | TQListViewItemIterator::Selected); - - // iterate through all selected visible items of the listview - for ( ; it.current(); ++it ) - { - selectedPIds.append(it.current()->text(1).toInt()); - } - - TQString msg = i18n("Do you really want to send signal %1 to the selected process?", - "Do you really want to send signal %1 to the %n selected processes?", - selectedPIds.count()) - .arg(signalPM->text(id)); - int answ; - switch(answ = KMessageBox::questionYesNo(this, msg, TQString::null, i18n("Send"), KStdGuiItem::cancel())) - { - case KMessageBox::Yes: - { - TQValueList::Iterator it; - for (it = selectedPIds.begin(); it != selectedPIds.end(); ++it) - emit (killProcess(*it, id)); - break; - } - default: - break; - } - } - else - { - /* IDs >= 100 are used for hidden columns. */ - int col = id - 100; - setColumnWidthMode(col, TQListView::Maximum); - setColumnWidth(col, savedWidth[col]); - setModified(true); - } - } -} - -void -ProcessList::selectAllItems(bool select) -{ - selectedPIds.clear(); - - TQListViewItemIterator it(this, TQListViewItemIterator::Visible); - - // iterate through all items of the listview - for ( ; it.current(); ++it ) - { - it.current()->setSelected(select); - repaintItem(it.current()); - if (select) - selectedPIds.append(it.current()->text(1).toInt()); - } -} - -void -ProcessList::selectAllChilds(int pid, bool select) -{ - TQListViewItemIterator it(this, TQListViewItemIterator::Visible ); - - // iterate through all items of the listview - for ( ; it.current(); ++it ) - { - // Check if PPID matches the pid (current is a child of pid) - if (it.current()->text(2).toInt() == pid) - { - int currPId = it.current()->text(1).toInt(); - it.current()->setSelected(select); - repaintItem(it.current()); - if (select) - selectedPIds.append(currPId); - else - selectedPIds.remove(currPId); - selectAllChilds(currPId, select); - } - } -} - -void -ProcessList::keyPressEvent(TQKeyEvent *e) -{ - if (e->key() == Key_Shift) { - shiftKeyDown = true; - } - if (e->key() == Key_Control) { - ctrlKeyDown = true; - } - TDEListView::keyPressEvent(e); -} - -void -ProcessList::keyReleaseEvent(TQKeyEvent *e) -{ - if (e->key() == Key_Shift) { - shiftKeyDown = false; - } - if (e->key() == Key_Control) { - ctrlKeyDown = false; - } - TDEListView::keyReleaseEvent(e); -} - -#include "ProcessList.moc" diff --git a/ksysguard/gui/SensorDisplayLib/ProcessList.cpp b/ksysguard/gui/SensorDisplayLib/ProcessList.cpp new file mode 100644 index 000000000..9293ef6a0 --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/ProcessList.cpp @@ -0,0 +1,977 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (C) 1997 Bernd Johannes Wuebben + + + Copyright (C) 1998 Nicolas Leclercq + + Copyright (c) 1999, 2000, 2001, 2002 Chris Schlaeger + + This program is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + KSysGuard is currently maintained by Chris Schlaeger . + Please do not commit any changes without consulting me first. Thanks! + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "ProcessController.h" +#include "ProcessList.h" +#include "ReniceDlg.h" +#include "SignalIDs.h" + +#define NONE -1 +#define INIT_PID 1 + +//extern const char* intKey(const char* text); +//extern const char* timeKey(const char* text); +//extern const char* floatKey(const char* text); + +TQDict ProcessList::aliases; + +int ProcessLVI::compare( TQListViewItem *item, int col, bool ascending ) const +{ + int type = ((ProcessList*)listView())->columnType( col ); + + if ( type == ProcessList::Int ) { + int prev = (int)TDEGlobal::locale()->readNumber( key( col, ascending ) ); + int next = (int)TDEGlobal::locale()->readNumber( item->key( col, ascending ) ); + if ( prev < next ) + return -1; + else if ( prev == next ) + return 0; + else + return 1; + } + + if ( type == ProcessList::Float ) { + double prev = TDEGlobal::locale()->readNumber( key( col, ascending ) ); + double next = TDEGlobal::locale()->readNumber( item->key( col, ascending ) ); + if ( prev < next ) + return -1; + else + return 1; + } + + if ( type == ProcessList::Time ) { + int hourPrev, hourNext, minutesPrev, minutesNext; + sscanf( key( col, ascending ).latin1(), "%d:%d", &hourPrev, &minutesPrev ); + sscanf( item->key( col, ascending ).latin1(), "%d:%d", &hourNext, &minutesNext ); + int prev = hourPrev * 60 + minutesPrev; + int next = hourNext * 60 + minutesNext; + if ( prev < next ) + return -1; + else if ( prev == next ) + return 0; + else + return 1; + } + + return key( col, ascending ).localeAwareCompare( item->key( col, ascending ) ); +} + +ProcessList::ProcessList(TQWidget *parent, const char* name) + : TDEListView(parent, name) +{ + iconCache.setAutoDelete(true); + + columnDict.setAutoDelete(true); + columnDict.insert("running", + new TQString(i18n("process status", "running"))); + columnDict.insert("sleeping", + new TQString(i18n("process status", "sleeping"))); + columnDict.insert("disk sleep", + new TQString(i18n("process status", "disk sleep"))); + columnDict.insert("zombie", new TQString(i18n("process status", "zombie"))); + columnDict.insert("stopped", + new TQString(i18n("process status", "stopped"))); + columnDict.insert("paging", new TQString(i18n("process status", "paging"))); + columnDict.insert("idle", new TQString(i18n("process status", "idle"))); + + if (aliases.isEmpty()) + { +#ifdef Q_OS_LINUX + aliases.insert("init", new TQString("penguin")); +#else + aliases.insert("init", new TQString("system")); +#endif + /* kernel stuff */ + aliases.insert("bdflush", new TQString("kernel")); + aliases.insert("dhcpcd", new TQString("kernel")); + aliases.insert("kapm-idled", new TQString("kernel")); + aliases.insert("keventd", new TQString("kernel")); + aliases.insert("khubd", new TQString("kernel")); + aliases.insert("klogd", new TQString("kernel")); + aliases.insert("kreclaimd", new TQString("kernel")); + aliases.insert("kreiserfsd", new TQString("kernel")); + aliases.insert("ksoftirqd_CPU0", new TQString("kernel")); + aliases.insert("ksoftirqd_CPU1", new TQString("kernel")); + aliases.insert("ksoftirqd_CPU2", new TQString("kernel")); + aliases.insert("ksoftirqd_CPU3", new TQString("kernel")); + aliases.insert("ksoftirqd_CPU4", new TQString("kernel")); + aliases.insert("ksoftirqd_CPU5", new TQString("kernel")); + aliases.insert("ksoftirqd_CPU6", new TQString("kernel")); + aliases.insert("ksoftirqd_CPU7", new TQString("kernel")); + aliases.insert("kswapd", new TQString("kernel")); + aliases.insert("kupdated", new TQString("kernel")); + aliases.insert("mdrecoveryd", new TQString("kernel")); + aliases.insert("scsi_eh_0", new TQString("kernel")); + aliases.insert("scsi_eh_1", new TQString("kernel")); + aliases.insert("scsi_eh_2", new TQString("kernel")); + aliases.insert("scsi_eh_3", new TQString("kernel")); + aliases.insert("scsi_eh_4", new TQString("kernel")); + aliases.insert("scsi_eh_5", new TQString("kernel")); + aliases.insert("scsi_eh_6", new TQString("kernel")); + aliases.insert("scsi_eh_7", new TQString("kernel")); + /* daemon and other service providers */ + aliases.insert("artsd", new TQString("daemon")); + aliases.insert("atd", new TQString("daemon")); + aliases.insert("automount", new TQString("daemon")); + aliases.insert("cardmgr", new TQString("daemon")); + aliases.insert("cron", new TQString("daemon")); + aliases.insert("cupsd", new TQString("daemon")); + aliases.insert("in.identd", new TQString("daemon")); + aliases.insert("lpd", new TQString("daemon")); + aliases.insert("mingetty", new TQString("daemon")); + aliases.insert("nscd", new TQString("daemon")); + aliases.insert("portmap", new TQString("daemon")); + aliases.insert("rpc.statd", new TQString("daemon")); + aliases.insert("rpciod", new TQString("daemon")); + aliases.insert("sendmail", new TQString("daemon")); + aliases.insert("sshd", new TQString("daemon")); + aliases.insert("syslogd", new TQString("daemon")); + aliases.insert("usbmgr", new TQString("daemon")); + aliases.insert("wwwoffled", new TQString("daemon")); + aliases.insert("xntpd", new TQString("daemon")); + aliases.insert("ypbind", new TQString("daemon")); + aliases.insert("apmd", new TQString("daemon")); + aliases.insert("getty", new TQString("daemon")); + aliases.insert("mountd", new TQString("daemon")); + aliases.insert("inetd", new TQString("daemon")); + aliases.insert("nfsd", new TQString("daemon")); + aliases.insert("wsmoused", new TQString("daemon")); + /* kde applications */ + aliases.insert("appletproxy", new TQString("tdeapp")); + aliases.insert("dcopserver", new TQString("tdeapp")); + aliases.insert("kcookiejar", new TQString("tdeapp")); + aliases.insert("kde", new TQString("tdeapp")); + aliases.insert("kded", new TQString("tdeapp")); + aliases.insert("tdeinit", new TQString("tdeapp")); + aliases.insert("kdesktop", new TQString("tdeapp")); + aliases.insert("tdesud", new TQString("tdeapp")); + aliases.insert("tdm", new TQString("tdeapp")); + aliases.insert("khotkeys", new TQString("tdeapp")); + aliases.insert("tdeio_file", new TQString("tdeapp")); + aliases.insert("tdeio_uiserver", new TQString("tdeapp")); + aliases.insert("tdelauncher", new TQString("tdeapp")); + aliases.insert("ksmserver", new TQString("tdeapp")); + aliases.insert("kwrapper", new TQString("tdeapp")); + aliases.insert("kwrited", new TQString("tdeapp")); + aliases.insert("kxmlrpcd", new TQString("tdeapp")); + aliases.insert("starttde", new TQString("tdeapp")); + /* other processes */ + aliases.insert("bash", new TQString("shell")); + aliases.insert("cat", new TQString("tools")); + aliases.insert("egrep", new TQString("tools")); + aliases.insert("emacs", new TQString("application-vnd.oasis.opendocument.text")); + aliases.insert("fgrep", new TQString("tools")); + aliases.insert("find", new TQString("tools")); + aliases.insert("grep", new TQString("tools")); + aliases.insert("ksh", new TQString("shell")); + aliases.insert("screen", new TQString("openterm")); + aliases.insert("sh", new TQString("shell")); + aliases.insert("sort", new TQString("tools")); + aliases.insert("ssh", new TQString("shell")); + aliases.insert("su", new TQString("tools")); + aliases.insert("tcsh", new TQString("shell")); + aliases.insert("tee", new TQString("tools")); + aliases.insert("vi", new TQString("application-vnd.oasis.opendocument.text")); + aliases.insert("vim", new TQString("application-vnd.oasis.opendocument.text")); + } + + /* The filter mode is controlled by a combo box of the parent. If + * the mode is changed we get a signal. */ + connect(parent, TQT_SIGNAL(setFilterMode(int)), + this, TQT_SLOT(setFilterMode(int))); + + /* We need to catch this signal to show various popup menues. */ + connect(this, + TQT_SIGNAL(rightButtonPressed(TQListViewItem*, const TQPoint&, int)), + this, + TQT_SLOT(handleRMBPressed(TQListViewItem*, const TQPoint&, int))); + + /* Since Qt does not tell us the sorting details we have to do our + * own bookkeping, so we can save and restore the sorting + * settings. */ + connect(header(), TQT_SIGNAL(clicked(int)), this, TQT_SLOT(sortingChanged(int))); + + ctrlKeyDown = false; + shiftKeyDown = false; + treeViewEnabled = false; + openAll = true; + + filterMode = FILTER_ALL; + + sortColumn = 1; + increasing = false; + + // Elements in the process list may only live in this list. + pl.setAutoDelete(true); + + setItemMargin(2); + setAllColumnsShowFocus(true); + setTreeStepSize(17); + setSorting(sortColumn, increasing); + setSelectionMode(TQListView::Extended); + + // Create popup menu for RMB clicks on table header + headerPM = new TQPopupMenu(); + headerPM->insertItem(i18n("Remove Column"), HEADER_REMOVE); + headerPM->insertItem(i18n("Add Column"), HEADER_ADD); + headerPM->insertItem(i18n("Help on Column"), HEADER_HELP); + + connect(header(), TQT_SIGNAL(sizeChange(int, int, int)), + this, TQT_SLOT(sizeChanged(int, int, int))); + connect(header(), TQT_SIGNAL(indexChange(int, int, int)), + this, TQT_SLOT(indexChanged(int, int, int))); + + killSupported = false; + setModified(false); +} + +ProcessList::~ProcessList() +{ + delete(headerPM); +} + +const TQValueList& +ProcessList::getSelectedPIds() +{ + selectedPIds.clear(); + // iterate through all selected visible items of the listview + TQListViewItemIterator it(this, TQListViewItemIterator::Visible | TQListViewItemIterator::Selected ); + for ( ; it.current(); ++it ) + selectedPIds.append(it.current()->text(1).toInt()); + + return (selectedPIds); +} + +const TQStringList& +ProcessList::getSelectedAsStrings() +{ + selectedAsStrings.clear(); + // iterate through all selected visible items of the listview + TQListViewItemIterator it(this, TQListViewItemIterator::Visible | TQListViewItemIterator::Selected ); + TQString spaces; + for ( ; it.current(); ++it ) { + spaces.fill(TQChar(' '), 7 - it.current()->text(1).length()); + selectedAsStrings.append("(PID: " + it.current()->text(1) + ")" + spaces + " " + it.current()->text(0)); + } + + return (selectedAsStrings); +} +bool +ProcessList::update(const TQString& list) +{ + if ((!shiftKeyDown) && (!ctrlKeyDown)) + { + /* Disable painting to avoid flickering effects, + * especially when in tree view mode. + * Ditto for the scrollbar. */ + setUpdatesEnabled(false); + viewport()->setUpdatesEnabled(false); + + pl.clear(); + + // Convert ps answer in a list of tokenized lines + KSGRD::SensorTokenizer procs(list, '\n'); + for (unsigned int i = 0; i < procs.count(); i++) + { + KSGRD::SensorPSLine* line = new KSGRD::SensorPSLine(procs[i]); + if (line->count() != (uint) columns()) + { +#if 0 + // This is needed for debugging only. + kdDebug(1215) << list << endl; + TQString l; + for (uint j = 0; j < line->count(); j++) + l += (*line)[j] + "|"; + kdDebug(1215) << "Incomplete ps line:" << l << endl; +#endif + return (false); + } + else + pl.append(line); + } + + int currItemPos = itemPos(currentItem()); + int vpos = verticalScrollBar()->value(); + int hpos = horizontalScrollBar()->value(); + + updateMetaInfo(); + + clear(); + + if (treeViewEnabled) + buildTree(); + else + buildList(); + + TQListViewItemIterator it( this ); + while ( it.current() ) { + if ( itemPos( it.current() ) == currItemPos ) { + setCurrentItem( it.current() ); + break; + } + ++it; + } + + verticalScrollBar()->setValue(vpos); + horizontalScrollBar()->setValue(hpos); + + // Re-enable painting, and force an update. + setUpdatesEnabled(true); + viewport()->setUpdatesEnabled(true); + + triggerUpdate(); + } + + return (true); +} + +void +ProcessList::setTreeView(bool tv) +{ + if ((treeViewEnabled = tv)) + { + savedWidth[0] = columnWidth(0); + openAll = true; + } + else + { + /* In tree view the first column is wider than in list view mode. + * So we shrink it to 1 pixel. The next update will resize it again + * appropriately. */ + setColumnWidth(0, savedWidth[0]); + } + /* In tree view mode borders are added to the icons. So we have to clear + * the cache when we change the tree view mode. */ + iconCache.clear(); +} + +bool +ProcessList::load(TQDomElement& el) +{ + TQDomNodeList dnList = el.elementsByTagName("column"); + for (uint i = 0; i < dnList.count(); ++i) + { + TQDomElement lel = dnList.item(i).toElement(); + if (savedWidth.count() <= i) + savedWidth.append(lel.attribute("savedWidth").toInt()); + else + savedWidth[i] = lel.attribute("savedWidth").toInt(); + if (currentWidth.count() <= i) + currentWidth.append(lel.attribute("currentWidth").toInt()); + else + currentWidth[i] = lel.attribute("currentWidth").toInt(); + if (index.count() <= i) + index.append(lel.attribute("index").toInt()); + else + index[i] = lel.attribute("index").toInt(); + } + + setModified(false); + + return (true); +} + +bool +ProcessList::save(TQDomDocument& doc, TQDomElement& display) +{ + for (int i = 0; i < columns(); ++i) + { + TQDomElement col = doc.createElement("column"); + display.appendChild(col); + col.setAttribute("currentWidth", columnWidth(i)); + col.setAttribute("savedWidth", savedWidth[i]); + col.setAttribute("index", header()->mapToIndex(i)); + } + + setModified(false); + + return (true); +} + +void +ProcessList::sortingChanged(int col) +{ + if (col == sortColumn) + increasing = !increasing; + else + { + sortColumn = col; + increasing = true; + } + setSorting(sortColumn, increasing); + setModified(true); +} + +int ProcessList::columnType( uint pos ) const +{ + if ( pos >= mColumnTypes.count() ) + return 0; + + if ( mColumnTypes[ pos ] == "d" || mColumnTypes[ pos ] == "D" ) + return Int; + else if ( mColumnTypes[ pos ] == "f" || mColumnTypes[ pos ] == "F" ) + return Float; + else if ( mColumnTypes[ pos ] == "t" ) + return Time; + else + return Text; +} + +bool +ProcessList::matchesFilter(KSGRD::SensorPSLine* p) const +{ + // This mechanism is likely to change in the future! + + switch (filterMode) + { + case FILTER_ALL: + return (true); + + case FILTER_SYSTEM: + return (p->uid() < 100 ? true : false); + + case FILTER_USER: + return (p->uid() >= 100 ? true : false); + + case FILTER_OWN: + default: + return (p->uid() == (long) getuid() ? true : false); + } +} + +void +ProcessList::buildList() +{ + /* Get the first process in the list, check whether it matches the + * filter and append it to TQListView widget if so. */ + while (!pl.isEmpty()) + { + KSGRD::SensorPSLine* p = pl.first(); + + if (matchesFilter(p)) + { + ProcessLVI* pli = new ProcessLVI(this); + + addProcess(p, pli); + + if (selectedPIds.findIndex(p->pid()) != -1) + pli->setSelected(true); + } + pl.removeFirst(); + } +} + +void +ProcessList::buildTree() +{ + // remove all leaves that do not match the filter + deleteLeaves(); + + KSGRD::SensorPSLine* ps = pl.first(); + + while (ps) + { + if (ps->pid() == INIT_PID) + { + // insert root item into the tree widget + ProcessLVI* pli = new ProcessLVI(this); + addProcess(ps, pli); + + // remove the process from the process list, ps is now invalid + int pid = ps->pid(); + pl.remove(); + + if (selectedPIds.findIndex(pid) != -1) + pli->setSelected(true); + + // insert all child processes of current process + extendTree(&pl, pli, pid); + break; + } + else + ps = pl.next(); + } +} + +void +ProcessList::deleteLeaves(void) +{ + for ( ; ; ) + { + unsigned int i; + for (i = 0; i < pl.count() && + (!isLeafProcess(pl.at(i)->pid()) || + matchesFilter(pl.at(i))); i++) + ; + if (i == pl.count()) + return; + + pl.remove(i); + } +} + +bool +ProcessList::isLeafProcess(int pid) +{ + for (unsigned int i = 0; i < pl.count(); i++) + if (pl.at(i)->ppid() == pid) + return (false); + + return (true); +} + +void +ProcessList::extendTree(TQPtrList* pl, ProcessLVI* parent, int ppid) +{ + KSGRD::SensorPSLine* ps; + + // start at top list + ps = pl->first(); + + while (ps) + { + // look for a child process of the current parent + if (ps->ppid() == ppid) + { + ProcessLVI* pli = new ProcessLVI(parent); + + addProcess(ps, pli); + + if (selectedPIds.findIndex(ps->pid()) != -1) + pli->setSelected(true); + + if (ps->ppid() != INIT_PID && closedSubTrees.findIndex(ps->ppid()) != -1) + parent->setOpen(false); + else + parent->setOpen(true); + + // remove the process from the process list, ps is now invalid + int pid = ps->pid(); + pl->remove(); + + // now look for the childs of the inserted process + extendTree(pl, pli, pid); + + /* Since buildTree can remove processes from the list we + * can't find a "current" process. So we start searching + * at the top again. It's no endless loops since this + * branch is only entered when there are children of the + * current parent in the list. When we have removed them + * all the while loop will exit. */ + ps = pl->first(); + } + else + ps = pl->next(); + } +} +void +ProcessList::addProcess(KSGRD::SensorPSLine* p, ProcessLVI* pli) +{ + TQString name = p->name(); + if (aliases[name]) + name = *aliases[name]; + + /* Get icon from icon list that might be appropriate for a process + * with this name. */ + TQPixmap pix; + if (!iconCache[name]) + { + pix = TDEGlobal::iconLoader()->loadIcon(name, TDEIcon::Small, + TDEIcon::SizeSmall, TDEIcon::DefaultState, + 0L, true); + if (pix.isNull() || !pix.mask()) + pix = TDEGlobal::iconLoader()->loadIcon("unknownapp", TDEIcon::User, + TDEIcon::SizeSmall); + + if (pix.width() != 16 || pix.height() != 16) + { + /* I guess this isn't needed too often. The TDEIconLoader should + * scale the pixmaps already appropriately. Since I got a bug + * report claiming that it doesn't work with GNOME apps I've + * added this safeguard. */ + TQImage img; + img = pix; + img.smoothScale(16, 16); + pix = img; + } + /* We copy the icon into a 24x16 pixmap to add a 4 pixel margin on + * the left and right side. In tree view mode we use the original + * icon. */ + TQPixmap icon(24, 16, pix.depth()); + if (!treeViewEnabled) + { + icon.fill(); + bitBlt(&icon, 4, 0, &pix, 0, 0, pix.width(), pix.height()); + TQBitmap mask(24, 16, true); + bitBlt(&mask, 4, 0, pix.mask(), 0, 0, pix.width(), pix.height()); + icon.setMask(mask); + pix = icon; + } + iconCache.insert(name, new TQPixmap(pix)); + } + else + pix = *(iconCache[name]); + + // icon + process name + pli->setPixmap(0, pix); + pli->setText(0, p->name()); + + // insert remaining field into table + for (unsigned int col = 1; col < p->count(); col++) + { + if (mColumnTypes[col] == "S" && columnDict[(*p)[col]]) + pli->setText(col, *columnDict[(*p)[col]]); + else if ( mColumnTypes[col] == "f" ) + pli->setText( col, TDEGlobal::locale()->formatNumber( (*p)[col].toFloat() ) ); + else if ( mColumnTypes[col] == "D" ) + pli->setText( col, TDEGlobal::locale()->formatNumber( (*p)[col].toInt(), 0 ) ); + else + pli->setText(col, (*p)[col]); + } +} + +void +ProcessList::updateMetaInfo(void) +{ + selectedPIds.clear(); + closedSubTrees.clear(); + + TQListViewItemIterator it(this); + + // iterate through all items of the listview + for ( ; it.current(); ++it ) + { + if (it.current()->isSelected() && it.current()->isVisible()) + selectedPIds.append(it.current()->text(1).toInt()); + if (treeViewEnabled && !it.current()->isOpen()) + closedSubTrees.append(it.current()->text(1).toInt()); + } + + /* In list view mode all list items are set to closed by TQListView. + * If the tree view is now selected, all item will be closed. This is + * annoying. So we use the openAll flag to force all trees to open when + * the treeViewEnbled flag was set to true. */ + if (openAll) + { + if (treeViewEnabled) + closedSubTrees.clear(); + openAll = false; + } +} + +void +ProcessList::removeColumns(void) +{ + for (int i = columns() - 1; i >= 0; --i) + removeColumn(i); +} + +void +ProcessList::addColumn(const TQString& label, const TQString& type) +{ + TQListView::addColumn(label); + uint col = columns() - 1; + if (type == "s" || type == "S") + setColumnAlignment(col, AlignLeft); + else if (type == "d" || type == "D") + setColumnAlignment(col, AlignRight); + else if (type == "t") + setColumnAlignment(col, AlignRight); + else if (type == "f") + setColumnAlignment(col, AlignRight); + else + { + kdDebug(1215) << "Unknown type " << type << " of column " << label + << " in ProcessList!" << endl; + return; + } + + mColumnTypes.append(type); + + /* Just use some sensible default values as initial setting. */ + TQFontMetrics fm = fontMetrics(); + setColumnWidth(col, fm.width(label) + 10); + + if (currentWidth.count() - 1 == col) + { + /* Table has been loaded from file. We can restore the settings + * when the last column has been added. */ + for (uint i = 0; i < col; ++i) + { + /* In case the language has been changed the column width + * might need to be increased. */ + if (currentWidth[i] == 0) + { + if (fm.width(header()->label(i)) + 10 > savedWidth[i]) + savedWidth[i] = fm.width(header()->label(i)) + 10; + setColumnWidth(i, 0); + } + else + { + if (fm.width(header()->label(i)) + 10 > currentWidth[i]) + setColumnWidth(i, fm.width(header()->label(i)) + 10); + else + setColumnWidth(i, currentWidth[i]); + } + setColumnWidthMode(i, currentWidth[i] == 0 ? + TQListView::Manual : TQListView::Maximum); + header()->moveSection(i, index[i]); + } + setSorting(sortColumn, increasing); + } +} + +void +ProcessList::handleRMBPressed(TQListViewItem* lvi, const TQPoint& p, int col) +{ + if (!lvi) + return; + + lvi->setSelected( true ); + + /* lvi is only valid until the next time we hit the main event + * loop. So we need to save the information we need after calling + * processPM->exec(). */ + int currentPId = lvi->text(1).toInt(); + + int currentNiceValue = 0; + for (int i = 0; i < columns(); ++i) + if (TQString::compare(header()->label(i), i18n("Nice")) == 0) + currentNiceValue = lvi->text(i).toInt(); + + TQPopupMenu processPM; + if (columnWidth(col) != 0) + processPM.insertItem(i18n("Hide Column"), 5); + TQPopupMenu* hiddenPM = new TQPopupMenu(&processPM); + for (int i = 0; i < columns(); ++i) + if (columnWidth(i) == 0) + hiddenPM->insertItem(header()->label(i), i + 100); + if(columns()) + processPM.insertItem(i18n("Show Column"), hiddenPM); + + processPM.insertSeparator(); + + processPM.insertItem(i18n("Select All Processes"), 1); + processPM.insertItem(i18n("Unselect All Processes"), 2); + + TQPopupMenu* signalPM = new TQPopupMenu(&processPM); + if (killSupported && lvi->isSelected()) + { + processPM.insertSeparator(); + processPM.insertItem(i18n("Select All Child Processes"), 3); + processPM.insertItem(i18n("Unselect All Child Processes"), 4); + + signalPM->insertItem(i18n("SIGABRT"), MENU_ID_SIGABRT); + signalPM->insertItem(i18n("SIGALRM"), MENU_ID_SIGALRM); + signalPM->insertItem(i18n("SIGCHLD"), MENU_ID_SIGCHLD); + signalPM->insertItem(i18n("SIGCONT"), MENU_ID_SIGCONT); + signalPM->insertItem(i18n("SIGFPE"), MENU_ID_SIGFPE); + signalPM->insertItem(i18n("SIGHUP"), MENU_ID_SIGHUP); + signalPM->insertItem(i18n("SIGILL"), MENU_ID_SIGILL); + signalPM->insertItem(i18n("SIGINT"), MENU_ID_SIGINT); + signalPM->insertItem(i18n("SIGKILL"), MENU_ID_SIGKILL); + signalPM->insertItem(i18n("SIGPIPE"), MENU_ID_SIGPIPE); + signalPM->insertItem(i18n("SIGQUIT"), MENU_ID_SIGQUIT); + signalPM->insertItem(i18n("SIGSEGV"), MENU_ID_SIGSEGV); + signalPM->insertItem(i18n("SIGSTOP"), MENU_ID_SIGSTOP); + signalPM->insertItem(i18n("SIGTERM"), MENU_ID_SIGTERM); + signalPM->insertItem(i18n("SIGTSTP"), MENU_ID_SIGTSTP); + signalPM->insertItem(i18n("SIGTTIN"), MENU_ID_SIGTTIN); + signalPM->insertItem(i18n("SIGTTOU"), MENU_ID_SIGTTOU); + signalPM->insertItem(i18n("SIGUSR1"), MENU_ID_SIGUSR1); + signalPM->insertItem(i18n("SIGUSR2"), MENU_ID_SIGUSR2); + + processPM.insertSeparator(); + processPM.insertItem(i18n("Send Signal"), signalPM); + } + + /* differ between killSupported and reniceSupported in a future + * version. */ + if (killSupported && lvi->isSelected()) + { + processPM.insertSeparator(); + processPM.insertItem(i18n("Renice Process..."), 300); + } + + int id; + switch (id = processPM.exec(p)) + { + case -1: + break; + case 1: + case 2: + selectAllItems(id & 1); + break; + case 3: + case 4: + selectAllChilds(currentPId, id & 1); + break; + case 5: + setColumnWidthMode(col, TQListView::Manual); + savedWidth[col] = columnWidth(col); + setColumnWidth(col, 0); + setModified(true); + break; + case 300: + { + ReniceDlg reniceDlg(this, "reniceDlg", currentNiceValue, currentPId); + + int reniceVal; + if ((reniceVal = reniceDlg.exec()) != 40) { + emit reniceProcess(selectedPIds, reniceVal); + } + } + break; + default: + /* IDs < 100 are used for signals. */ + if (id < 100) + { + /* we go through list to get all task also + when update interval is paused */ + selectedPIds.clear(); + TQListViewItemIterator it(this, TQListViewItemIterator::Visible | TQListViewItemIterator::Selected); + + // iterate through all selected visible items of the listview + for ( ; it.current(); ++it ) + { + selectedPIds.append(it.current()->text(1).toInt()); + } + + TQString msg = i18n("Do you really want to send signal %1 to the selected process?", + "Do you really want to send signal %1 to the %n selected processes?", + selectedPIds.count()) + .arg(signalPM->text(id)); + int answ; + switch(answ = KMessageBox::questionYesNo(this, msg, TQString::null, i18n("Send"), KStdGuiItem::cancel())) + { + case KMessageBox::Yes: + { + TQValueList::Iterator it; + for (it = selectedPIds.begin(); it != selectedPIds.end(); ++it) + emit (killProcess(*it, id)); + break; + } + default: + break; + } + } + else + { + /* IDs >= 100 are used for hidden columns. */ + int col = id - 100; + setColumnWidthMode(col, TQListView::Maximum); + setColumnWidth(col, savedWidth[col]); + setModified(true); + } + } +} + +void +ProcessList::selectAllItems(bool select) +{ + selectedPIds.clear(); + + TQListViewItemIterator it(this, TQListViewItemIterator::Visible); + + // iterate through all items of the listview + for ( ; it.current(); ++it ) + { + it.current()->setSelected(select); + repaintItem(it.current()); + if (select) + selectedPIds.append(it.current()->text(1).toInt()); + } +} + +void +ProcessList::selectAllChilds(int pid, bool select) +{ + TQListViewItemIterator it(this, TQListViewItemIterator::Visible ); + + // iterate through all items of the listview + for ( ; it.current(); ++it ) + { + // Check if PPID matches the pid (current is a child of pid) + if (it.current()->text(2).toInt() == pid) + { + int currPId = it.current()->text(1).toInt(); + it.current()->setSelected(select); + repaintItem(it.current()); + if (select) + selectedPIds.append(currPId); + else + selectedPIds.remove(currPId); + selectAllChilds(currPId, select); + } + } +} + +void +ProcessList::keyPressEvent(TQKeyEvent *e) +{ + if (e->key() == Key_Shift) { + shiftKeyDown = true; + } + if (e->key() == Key_Control) { + ctrlKeyDown = true; + } + TDEListView::keyPressEvent(e); +} + +void +ProcessList::keyReleaseEvent(TQKeyEvent *e) +{ + if (e->key() == Key_Shift) { + shiftKeyDown = false; + } + if (e->key() == Key_Control) { + ctrlKeyDown = false; + } + TDEListView::keyReleaseEvent(e); +} + +#include "ProcessList.moc" diff --git a/ksysguard/gui/SensorDisplayLib/ReniceDlg.cc b/ksysguard/gui/SensorDisplayLib/ReniceDlg.cc deleted file mode 100644 index e71c6e0a0..000000000 --- a/ksysguard/gui/SensorDisplayLib/ReniceDlg.cc +++ /dev/null @@ -1,70 +0,0 @@ -/* - KSysGuard, the KDE System Guard - - Copyright (c) 1999 Chris Schlaeger - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - KSysGuard is currently maintained by Chris Schlaeger . Please do - not commit any changes without consulting me first. Thanks! - -*/ - -#include -#include - -#include "ReniceDlg.moc" - -ReniceDlg::ReniceDlg(TQWidget* parent, const char* name, int currentPPrio, - int pid) - : KDialogBase( parent, name, true, i18n("Renice Process"), - KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true ) -{ - TQWidget *page = new TQWidget( this ); - setMainWidget(page); - vLay = new TQVBoxLayout(page, 20, -1, "ReniceLayout"); - - TQString msg; - msg = i18n("You are about to change the scheduling priority of\n" - "process %1. Be aware that only the Superuser (root)\n" - "can decrease the nice level of a process. The lower\n" - "the number is the higher the priority.\n\n" - "Please enter the desired nice level:").arg(pid); - message = new TQLabel(msg, page); - message->setMinimumSize(message->sizeHint()); - vLay->addWidget(message); - - /* - * Create a slider with an LCD display to the right using a horizontal - * layout. The slider and the LCD are kept in sync through signals - */ - input = new KIntNumInput(currentPPrio, page, 10); - input->setRange(-20, 19); - vLay->addWidget(input); -} - -ReniceDlg::~ReniceDlg() { - // -} - -void ReniceDlg::slotOk() -{ - done(input->value()); -} - -void ReniceDlg::slotCancel() -{ - done(40); -} diff --git a/ksysguard/gui/SensorDisplayLib/ReniceDlg.cpp b/ksysguard/gui/SensorDisplayLib/ReniceDlg.cpp new file mode 100644 index 000000000..e71c6e0a0 --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/ReniceDlg.cpp @@ -0,0 +1,70 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 1999 Chris Schlaeger + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + KSysGuard is currently maintained by Chris Schlaeger . Please do + not commit any changes without consulting me first. Thanks! + +*/ + +#include +#include + +#include "ReniceDlg.moc" + +ReniceDlg::ReniceDlg(TQWidget* parent, const char* name, int currentPPrio, + int pid) + : KDialogBase( parent, name, true, i18n("Renice Process"), + KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true ) +{ + TQWidget *page = new TQWidget( this ); + setMainWidget(page); + vLay = new TQVBoxLayout(page, 20, -1, "ReniceLayout"); + + TQString msg; + msg = i18n("You are about to change the scheduling priority of\n" + "process %1. Be aware that only the Superuser (root)\n" + "can decrease the nice level of a process. The lower\n" + "the number is the higher the priority.\n\n" + "Please enter the desired nice level:").arg(pid); + message = new TQLabel(msg, page); + message->setMinimumSize(message->sizeHint()); + vLay->addWidget(message); + + /* + * Create a slider with an LCD display to the right using a horizontal + * layout. The slider and the LCD are kept in sync through signals + */ + input = new KIntNumInput(currentPPrio, page, 10); + input->setRange(-20, 19); + vLay->addWidget(input); +} + +ReniceDlg::~ReniceDlg() { + // +} + +void ReniceDlg::slotOk() +{ + done(input->value()); +} + +void ReniceDlg::slotCancel() +{ + done(40); +} diff --git a/ksysguard/gui/SensorDisplayLib/SensorDisplay.cc b/ksysguard/gui/SensorDisplayLib/SensorDisplay.cc deleted file mode 100644 index 4dfff7957..000000000 --- a/ksysguard/gui/SensorDisplayLib/SensorDisplay.cc +++ /dev/null @@ -1,611 +0,0 @@ -/* - KSysGuard, the KDE System Guard - - Copyright (c) 1999 - 2002 Chris Schlaeger - - This program is free software; you can redistribute it and/or - modify it under the terms of version 2 of the GNU General Public - License as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - KSysGuard is currently maintained by Chris Schlaeger . - Please do not commit any changes without consulting me first. Thanks! - -*/ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "SensorManager.h" -#include "TimerSettings.h" - -#include "SensorDisplay.h" - -using namespace KSGRD; - -SensorDisplay::SensorDisplay( TQWidget *parent, const char *name, - const TQString &title, bool nf, bool isApplet) - : TQWidget( parent, name ) -{ - mIsApplet = isApplet; - mSensors.setAutoDelete( true ); - - // default interval is 2 seconds. - mUpdateInterval = 2; - mUseGlobalUpdateInterval = true; - mModified = false; - mShowUnit = false; - mTimerId = NONE; - mFrame = 0; - mErrorIndicator = 0; - mPlotterWdg = 0; - - setTimerOn( true ); - TQWhatsThis::add( this, "dummy" ); - - if(!nf) { - mFrame = new TQGroupBox( 2, Qt::Vertical, "", this, "displayFrame"); - mFrame->setFlat(true); - mFrame->setAlignment(Qt::AlignHCenter); - mFrame->setInsideMargin(2); - - setTitle( title ); - /* All RMB clicks to the box frame will be handled by - * SensorDisplay::eventFilter. */ - mFrame->installEventFilter( this ); - } - - - setMinimumSize( 16, 16 ); - setModified( false ); - setSensorOk( false ); - - /* Let's call updateWhatsThis() in case the derived class does not do - * this. */ - updateWhatsThis(); -} - -SensorDisplay::~SensorDisplay() -{ - if ( SensorMgr != 0 ) - SensorMgr->disconnectClient( this ); - - killTimer( mTimerId ); -} - -void SensorDisplay::registerSensor( SensorProperties *sp ) -{ - /* Make sure that we have a connection established to the specified - * host. When a work sheet has been saved while it had dangling - * sensors, the connect info is not saved in the work sheet. In such - * a case the user can re-enter the connect information and the - * connection will be established. */ - if ( !SensorMgr->engageHost( sp->hostName() ) ) { - TQString msg = i18n( "It is impossible to connect to \'%1\'." ).arg( sp->hostName() ); - KMessageBox::error( this, msg ); - } - - mSensors.append( sp ); -} - -void SensorDisplay::unregisterSensor( uint pos ) -{ - mSensors.remove( pos ); -} - -void SensorDisplay::configureUpdateInterval() -{ - TimerSettings dlg( this ); - - dlg.setUseGlobalUpdate( mUseGlobalUpdateInterval ); - dlg.setInterval( mUpdateInterval ); - - if ( dlg.exec() ) { - if ( dlg.useGlobalUpdate() ) { - mUseGlobalUpdateInterval = true; - - SensorBoard* sb = dynamic_cast( parentWidget() ); - if ( !sb ) { - kdDebug(1215) << "dynamic cast lacks" << endl; - setUpdateInterval( 2 ); - } else { - setUpdateInterval( sb->updateInterval() ); - } - } else { - mUseGlobalUpdateInterval = false; - setUpdateInterval( dlg.interval() ); - } - - setModified( true ); - } -} - -void SensorDisplay::timerEvent( TQTimerEvent* ) -{ - int i = 0; - for ( SensorProperties *s = mSensors.first(); s; s = mSensors.next(), ++i ) - sendRequest( s->hostName(), s->name(), i ); -} - -void SensorDisplay::resizeEvent( TQResizeEvent* ) -{ - if(mFrame) - mFrame->setGeometry( rect() ); -} - -bool SensorDisplay::eventFilter( TQObject *object, TQEvent *event ) -{ - if ( event->type() == TQEvent::MouseButtonPress && - ( (TQMouseEvent*)event)->button() == Qt::RightButton ) { - TQPopupMenu pm; - if ( mIsApplet ) { - pm.insertItem( i18n( "Launch &System Guard"), 1 ); - pm.insertSeparator(); - } - if ( hasSettingsDialog() ) - pm.insertItem( i18n( "&Properties" ), 2 ); - pm.insertItem( i18n( "&Remove Display" ), 3 ); - pm.insertSeparator(); - pm.insertItem( i18n( "&Setup Update Interval..." ), 4 ); - if ( !timerOn() ) - pm.insertItem( i18n( "&Continue Update" ), 5 ); - else - pm.insertItem( i18n( "P&ause Update" ), 6 ); - - switch ( pm.exec( TQCursor::pos() ) ) { - case 1: - KRun::run(*KService::serviceByDesktopName("ksysguard"), KURL::List()); - break; - case 2: - configureSettings(); - break; - case 3: { - TQCustomEvent *e = new TQCustomEvent( TQEvent::User ); - e->setData( this ); - kapp->postEvent( parent(), e ); - } - break; - case 4: - configureUpdateInterval(); - break; - case 5: - setTimerOn( true ); - setModified( true ); - break; - case 6: - setTimerOn( false ); - setModified( true ); - break; - } - - return true; - } else if ( event->type() == TQEvent::MouseButtonRelease && - ( ( TQMouseEvent*)event)->button() == Qt::LeftButton ) { - setFocus(); - } - - return TQWidget::eventFilter( object, event ); -} - -void SensorDisplay::sendRequest( const TQString &hostName, - const TQString &command, int id ) -{ - if ( !SensorMgr->sendRequest( hostName, command, (SensorClient*)this, id ) ) - sensorError( id, true ); -} - -void SensorDisplay::sensorError( int sensorId, bool err ) -{ - if ( sensorId >= (int)mSensors.count() || sensorId < 0 ) - return; - - if ( err == mSensors.at( sensorId )->isOk() ) { - // this happens only when the sensorOk status needs to be changed. - mSensors.at( sensorId )->setIsOk( !err ); - } - - bool ok = true; - for ( uint i = 0; i < mSensors.count(); ++i ) - if ( !mSensors.at( i )->isOk() ) { - ok = false; - break; - } - - setSensorOk( ok ); -} - -void SensorDisplay::updateWhatsThis() -{ - TQWhatsThis::add( this, i18n( - "

This is a sensor display. To customize a sensor display click " - "and hold the right mouse button on either the frame or the " - "display box and select the Properties entry from the popup " - "menu. Select Remove to delete the display from the worksheet." - "

%1
" ).arg( additionalWhatsThis() ) ); -} - -void SensorDisplay::hosts( TQStringList& list ) -{ - for ( SensorProperties *s = mSensors.first(); s; s = mSensors.next() ) - if ( !list.contains( s->hostName() ) ) - list.append( s->hostName() ); -} - -TQColor SensorDisplay::restoreColor( TQDomElement &element, const TQString &attr, - const TQColor& fallback ) -{ - bool ok; - uint c = element.attribute( attr ).toUInt( &ok ); - if ( !ok ) - return fallback; - else - return TQColor( (c >> 16) & 0xFF, (c >> 8) & 0xFF, c & 0xFF ); -} - -void SensorDisplay::saveColor( TQDomElement &element, const TQString &attr, - const TQColor &color ) -{ - int r, g, b; - color.rgb( &r, &g, &b ); - element.setAttribute( attr, (r << 16) | (g << 8) | b ); -} - -bool SensorDisplay::addSensor( const TQString &hostName, const TQString &name, - const TQString &type, const TQString &description ) -{ - registerSensor( new SensorProperties( hostName, name, type, description ) ); - return true; -} - -bool SensorDisplay::removeSensor( uint pos ) -{ - unregisterSensor( pos ); - return true; -} - -void SensorDisplay::setUpdateInterval( uint interval ) -{ - bool timerActive = timerOn(); - - if ( timerActive ) - setTimerOn( false ); - - mUpdateInterval = interval; - - if ( timerActive ) - setTimerOn( true ); -} - -bool SensorDisplay::hasSettingsDialog() const -{ - return false; -} - -void SensorDisplay::configureSettings() -{ -} - -void SensorDisplay::setUseGlobalUpdateInterval( bool value ) -{ - mUseGlobalUpdateInterval = value; -} - -bool SensorDisplay::useGlobalUpdateInterval() const -{ - return mUseGlobalUpdateInterval; -} - -TQString SensorDisplay::additionalWhatsThis() -{ - return TQString::null; -} - -void SensorDisplay::sensorLost( int reqId ) -{ - sensorError( reqId, true ); -} - -bool SensorDisplay::restoreSettings( TQDomElement &element ) -{ - TQString str = element.attribute( "showUnit", "X" ); - if(!str.isEmpty() && str != "X") { - mShowUnit = str.toInt(); - } - str = element.attribute( "unit", TQString::null ); - if(!str.isEmpty()) - setUnit(str); - str = element.attribute( "title", TQString::null ); - if(!str.isEmpty()) - setTitle(str); - - if ( element.attribute( "updateInterval" ) != TQString::null ) { - mUseGlobalUpdateInterval = false; - setUpdateInterval( element.attribute( "updateInterval", "2" ).toInt() ); - } else { - mUseGlobalUpdateInterval = true; - - SensorBoard* sb = dynamic_cast( parentWidget() ); - if ( !sb ) { - kdDebug(1215) << "dynamic cast lacks" << endl; - setUpdateInterval( 2 ); - } else - setUpdateInterval( sb->updateInterval() ); - } - - if ( element.attribute( "pause", "0" ).toInt() == 0 ) - setTimerOn( true ); - else - setTimerOn( false ); - - return true; -} - -bool SensorDisplay::saveSettings( TQDomDocument&, TQDomElement &element, bool ) -{ - element.setAttribute( "title", title() ); - element.setAttribute( "unit", unit() ); - element.setAttribute( "showUnit", mShowUnit ); - - if ( mUseGlobalUpdateInterval ) - element.setAttribute( "globalUpdate", "1" ); - else { - element.setAttribute( "globalUpdate", "0" ); - element.setAttribute( "updateInterval", mUpdateInterval ); - } - - if ( !timerOn() ) - element.setAttribute( "pause", 1 ); - else - element.setAttribute( "pause", 0 ); - - return true; -} - -void SensorDisplay::setTimerOn( bool on ) -{ - if ( on ) { - if ( mTimerId == NONE ) - mTimerId = startTimer( mUpdateInterval * 1000 ); - } else { - if ( mTimerId != NONE ) { - killTimer( mTimerId ); - mTimerId = NONE; - } - } -} - -bool SensorDisplay::timerOn() const -{ - return ( mTimerId != NONE ); -} - -bool SensorDisplay::modified() const -{ - return mModified; -} - -TQPtrList &SensorDisplay::sensors() -{ - return mSensors; -} - -void SensorDisplay::rmbPressed() -{ - emit showPopupMenu( this ); -} - -void SensorDisplay::applySettings() -{ -} - -void SensorDisplay::applyStyle() -{ -} - -void SensorDisplay::setModified( bool value ) -{ - if ( value != mModified ) { - mModified = value; - emit modified( mModified ); - } -} - -void SensorDisplay::setSensorOk( bool ok ) -{ - if ( ok ) { - delete mErrorIndicator; - mErrorIndicator = 0; - } else { - if ( mErrorIndicator ) - return; - - TQPixmap errorIcon = TDEGlobal::iconLoader()->loadIcon( "connect_creating", TDEIcon::Desktop, - TDEIcon::SizeSmall ); - if ( !mPlotterWdg ) - return; - - mErrorIndicator = new TQWidget( mPlotterWdg ); - mErrorIndicator->setErasePixmap( errorIcon ); - mErrorIndicator->resize( errorIcon.size() ); - if ( errorIcon.mask() ) - mErrorIndicator->setMask( *errorIcon.mask() ); - mErrorIndicator->move( 0, 0 ); - mErrorIndicator->show(); - } -} - -void SensorDisplay::setTitle( const TQString &title ) -{ - mTitle = title; - - if(!mFrame) { - return; //fixme. create a frame and move widget inside it. - } - - /* Changing the frame title may increase the width of the frame and - * hence breaks the layout. To avoid this, we save the original size - * and restore it after we have set the frame title. */ - TQSize s = mFrame->size(); - - if ( mShowUnit && !mUnit.isEmpty() ) - mFrame->setTitle( mTitle + " [" + mUnit + "]" ); - else - mFrame->setTitle( mTitle ); - mFrame->setGeometry( 0, 0, s.width(), s.height() ); -} - -TQString SensorDisplay::title() const -{ - return mTitle; -} - -void SensorDisplay::setUnit( const TQString &unit ) -{ - mUnit = unit; -} - -TQString SensorDisplay::unit() const -{ - return mUnit; -} - -void SensorDisplay::setShowUnit( bool value ) -{ - mShowUnit = value; -} - -bool SensorDisplay::showUnit() const -{ - return mShowUnit; -} - -void SensorDisplay::setPlotterWidget( TQWidget *wdg ) -{ - mPlotterWdg = wdg; - -} - -TQWidget *SensorDisplay::frame() -{ - return mFrame; -} - -//void SensorDisplay::setNoFrame( bool /*value*/ ) -//{ - //FIXME - delete or create the frame as needed -//} - -bool SensorDisplay::noFrame() const -{ - return !mFrame; -} - -void SensorDisplay::reorderSensors(const TQValueList &orderOfSensors) -{ - TQPtrList newSensors; - for ( uint i = 0; i < orderOfSensors.count(); ++i ) { - newSensors.append( mSensors.at(orderOfSensors[i] )); - } - - mSensors.setAutoDelete( false ); - mSensors = newSensors; - mSensors.setAutoDelete( true ); -} - - -SensorProperties::SensorProperties() -{ -} - -SensorProperties::SensorProperties( const TQString &hostName, const TQString &name, - const TQString &type, const TQString &description ) - : mHostName( hostName ), mName( name ), mType( type ), mDescription( description ) -{ - mOk = false; -} - -SensorProperties::~SensorProperties() -{ -} - -void SensorProperties::setHostName( const TQString &hostName ) -{ - mHostName = hostName; -} - -TQString SensorProperties::hostName() const -{ - return mHostName; -} - -void SensorProperties::setName( const TQString &name ) -{ - mName = name; -} - -TQString SensorProperties::name() const -{ - return mName; -} - -void SensorProperties::setType( const TQString &type ) -{ - mType = type; -} - -TQString SensorProperties::type() const -{ - return mType; -} - -void SensorProperties::setDescription( const TQString &description ) -{ - mDescription = description; -} - -TQString SensorProperties::description() const -{ - return mDescription; -} - -void SensorProperties::setUnit( const TQString &unit ) -{ - mUnit = unit; -} - -TQString SensorProperties::unit() const -{ - return mUnit; -} - -void SensorProperties::setIsOk( bool value ) -{ - mOk = value; -} - -bool SensorProperties::isOk() const -{ - return mOk; -} - -#include "SensorDisplay.moc" diff --git a/ksysguard/gui/SensorDisplayLib/SensorDisplay.cpp b/ksysguard/gui/SensorDisplayLib/SensorDisplay.cpp new file mode 100644 index 000000000..4dfff7957 --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/SensorDisplay.cpp @@ -0,0 +1,611 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 1999 - 2002 Chris Schlaeger + + This program is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + KSysGuard is currently maintained by Chris Schlaeger . + Please do not commit any changes without consulting me first. Thanks! + +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "SensorManager.h" +#include "TimerSettings.h" + +#include "SensorDisplay.h" + +using namespace KSGRD; + +SensorDisplay::SensorDisplay( TQWidget *parent, const char *name, + const TQString &title, bool nf, bool isApplet) + : TQWidget( parent, name ) +{ + mIsApplet = isApplet; + mSensors.setAutoDelete( true ); + + // default interval is 2 seconds. + mUpdateInterval = 2; + mUseGlobalUpdateInterval = true; + mModified = false; + mShowUnit = false; + mTimerId = NONE; + mFrame = 0; + mErrorIndicator = 0; + mPlotterWdg = 0; + + setTimerOn( true ); + TQWhatsThis::add( this, "dummy" ); + + if(!nf) { + mFrame = new TQGroupBox( 2, Qt::Vertical, "", this, "displayFrame"); + mFrame->setFlat(true); + mFrame->setAlignment(Qt::AlignHCenter); + mFrame->setInsideMargin(2); + + setTitle( title ); + /* All RMB clicks to the box frame will be handled by + * SensorDisplay::eventFilter. */ + mFrame->installEventFilter( this ); + } + + + setMinimumSize( 16, 16 ); + setModified( false ); + setSensorOk( false ); + + /* Let's call updateWhatsThis() in case the derived class does not do + * this. */ + updateWhatsThis(); +} + +SensorDisplay::~SensorDisplay() +{ + if ( SensorMgr != 0 ) + SensorMgr->disconnectClient( this ); + + killTimer( mTimerId ); +} + +void SensorDisplay::registerSensor( SensorProperties *sp ) +{ + /* Make sure that we have a connection established to the specified + * host. When a work sheet has been saved while it had dangling + * sensors, the connect info is not saved in the work sheet. In such + * a case the user can re-enter the connect information and the + * connection will be established. */ + if ( !SensorMgr->engageHost( sp->hostName() ) ) { + TQString msg = i18n( "It is impossible to connect to \'%1\'." ).arg( sp->hostName() ); + KMessageBox::error( this, msg ); + } + + mSensors.append( sp ); +} + +void SensorDisplay::unregisterSensor( uint pos ) +{ + mSensors.remove( pos ); +} + +void SensorDisplay::configureUpdateInterval() +{ + TimerSettings dlg( this ); + + dlg.setUseGlobalUpdate( mUseGlobalUpdateInterval ); + dlg.setInterval( mUpdateInterval ); + + if ( dlg.exec() ) { + if ( dlg.useGlobalUpdate() ) { + mUseGlobalUpdateInterval = true; + + SensorBoard* sb = dynamic_cast( parentWidget() ); + if ( !sb ) { + kdDebug(1215) << "dynamic cast lacks" << endl; + setUpdateInterval( 2 ); + } else { + setUpdateInterval( sb->updateInterval() ); + } + } else { + mUseGlobalUpdateInterval = false; + setUpdateInterval( dlg.interval() ); + } + + setModified( true ); + } +} + +void SensorDisplay::timerEvent( TQTimerEvent* ) +{ + int i = 0; + for ( SensorProperties *s = mSensors.first(); s; s = mSensors.next(), ++i ) + sendRequest( s->hostName(), s->name(), i ); +} + +void SensorDisplay::resizeEvent( TQResizeEvent* ) +{ + if(mFrame) + mFrame->setGeometry( rect() ); +} + +bool SensorDisplay::eventFilter( TQObject *object, TQEvent *event ) +{ + if ( event->type() == TQEvent::MouseButtonPress && + ( (TQMouseEvent*)event)->button() == Qt::RightButton ) { + TQPopupMenu pm; + if ( mIsApplet ) { + pm.insertItem( i18n( "Launch &System Guard"), 1 ); + pm.insertSeparator(); + } + if ( hasSettingsDialog() ) + pm.insertItem( i18n( "&Properties" ), 2 ); + pm.insertItem( i18n( "&Remove Display" ), 3 ); + pm.insertSeparator(); + pm.insertItem( i18n( "&Setup Update Interval..." ), 4 ); + if ( !timerOn() ) + pm.insertItem( i18n( "&Continue Update" ), 5 ); + else + pm.insertItem( i18n( "P&ause Update" ), 6 ); + + switch ( pm.exec( TQCursor::pos() ) ) { + case 1: + KRun::run(*KService::serviceByDesktopName("ksysguard"), KURL::List()); + break; + case 2: + configureSettings(); + break; + case 3: { + TQCustomEvent *e = new TQCustomEvent( TQEvent::User ); + e->setData( this ); + kapp->postEvent( parent(), e ); + } + break; + case 4: + configureUpdateInterval(); + break; + case 5: + setTimerOn( true ); + setModified( true ); + break; + case 6: + setTimerOn( false ); + setModified( true ); + break; + } + + return true; + } else if ( event->type() == TQEvent::MouseButtonRelease && + ( ( TQMouseEvent*)event)->button() == Qt::LeftButton ) { + setFocus(); + } + + return TQWidget::eventFilter( object, event ); +} + +void SensorDisplay::sendRequest( const TQString &hostName, + const TQString &command, int id ) +{ + if ( !SensorMgr->sendRequest( hostName, command, (SensorClient*)this, id ) ) + sensorError( id, true ); +} + +void SensorDisplay::sensorError( int sensorId, bool err ) +{ + if ( sensorId >= (int)mSensors.count() || sensorId < 0 ) + return; + + if ( err == mSensors.at( sensorId )->isOk() ) { + // this happens only when the sensorOk status needs to be changed. + mSensors.at( sensorId )->setIsOk( !err ); + } + + bool ok = true; + for ( uint i = 0; i < mSensors.count(); ++i ) + if ( !mSensors.at( i )->isOk() ) { + ok = false; + break; + } + + setSensorOk( ok ); +} + +void SensorDisplay::updateWhatsThis() +{ + TQWhatsThis::add( this, i18n( + "

This is a sensor display. To customize a sensor display click " + "and hold the right mouse button on either the frame or the " + "display box and select the Properties entry from the popup " + "menu. Select Remove to delete the display from the worksheet." + "

%1
" ).arg( additionalWhatsThis() ) ); +} + +void SensorDisplay::hosts( TQStringList& list ) +{ + for ( SensorProperties *s = mSensors.first(); s; s = mSensors.next() ) + if ( !list.contains( s->hostName() ) ) + list.append( s->hostName() ); +} + +TQColor SensorDisplay::restoreColor( TQDomElement &element, const TQString &attr, + const TQColor& fallback ) +{ + bool ok; + uint c = element.attribute( attr ).toUInt( &ok ); + if ( !ok ) + return fallback; + else + return TQColor( (c >> 16) & 0xFF, (c >> 8) & 0xFF, c & 0xFF ); +} + +void SensorDisplay::saveColor( TQDomElement &element, const TQString &attr, + const TQColor &color ) +{ + int r, g, b; + color.rgb( &r, &g, &b ); + element.setAttribute( attr, (r << 16) | (g << 8) | b ); +} + +bool SensorDisplay::addSensor( const TQString &hostName, const TQString &name, + const TQString &type, const TQString &description ) +{ + registerSensor( new SensorProperties( hostName, name, type, description ) ); + return true; +} + +bool SensorDisplay::removeSensor( uint pos ) +{ + unregisterSensor( pos ); + return true; +} + +void SensorDisplay::setUpdateInterval( uint interval ) +{ + bool timerActive = timerOn(); + + if ( timerActive ) + setTimerOn( false ); + + mUpdateInterval = interval; + + if ( timerActive ) + setTimerOn( true ); +} + +bool SensorDisplay::hasSettingsDialog() const +{ + return false; +} + +void SensorDisplay::configureSettings() +{ +} + +void SensorDisplay::setUseGlobalUpdateInterval( bool value ) +{ + mUseGlobalUpdateInterval = value; +} + +bool SensorDisplay::useGlobalUpdateInterval() const +{ + return mUseGlobalUpdateInterval; +} + +TQString SensorDisplay::additionalWhatsThis() +{ + return TQString::null; +} + +void SensorDisplay::sensorLost( int reqId ) +{ + sensorError( reqId, true ); +} + +bool SensorDisplay::restoreSettings( TQDomElement &element ) +{ + TQString str = element.attribute( "showUnit", "X" ); + if(!str.isEmpty() && str != "X") { + mShowUnit = str.toInt(); + } + str = element.attribute( "unit", TQString::null ); + if(!str.isEmpty()) + setUnit(str); + str = element.attribute( "title", TQString::null ); + if(!str.isEmpty()) + setTitle(str); + + if ( element.attribute( "updateInterval" ) != TQString::null ) { + mUseGlobalUpdateInterval = false; + setUpdateInterval( element.attribute( "updateInterval", "2" ).toInt() ); + } else { + mUseGlobalUpdateInterval = true; + + SensorBoard* sb = dynamic_cast( parentWidget() ); + if ( !sb ) { + kdDebug(1215) << "dynamic cast lacks" << endl; + setUpdateInterval( 2 ); + } else + setUpdateInterval( sb->updateInterval() ); + } + + if ( element.attribute( "pause", "0" ).toInt() == 0 ) + setTimerOn( true ); + else + setTimerOn( false ); + + return true; +} + +bool SensorDisplay::saveSettings( TQDomDocument&, TQDomElement &element, bool ) +{ + element.setAttribute( "title", title() ); + element.setAttribute( "unit", unit() ); + element.setAttribute( "showUnit", mShowUnit ); + + if ( mUseGlobalUpdateInterval ) + element.setAttribute( "globalUpdate", "1" ); + else { + element.setAttribute( "globalUpdate", "0" ); + element.setAttribute( "updateInterval", mUpdateInterval ); + } + + if ( !timerOn() ) + element.setAttribute( "pause", 1 ); + else + element.setAttribute( "pause", 0 ); + + return true; +} + +void SensorDisplay::setTimerOn( bool on ) +{ + if ( on ) { + if ( mTimerId == NONE ) + mTimerId = startTimer( mUpdateInterval * 1000 ); + } else { + if ( mTimerId != NONE ) { + killTimer( mTimerId ); + mTimerId = NONE; + } + } +} + +bool SensorDisplay::timerOn() const +{ + return ( mTimerId != NONE ); +} + +bool SensorDisplay::modified() const +{ + return mModified; +} + +TQPtrList &SensorDisplay::sensors() +{ + return mSensors; +} + +void SensorDisplay::rmbPressed() +{ + emit showPopupMenu( this ); +} + +void SensorDisplay::applySettings() +{ +} + +void SensorDisplay::applyStyle() +{ +} + +void SensorDisplay::setModified( bool value ) +{ + if ( value != mModified ) { + mModified = value; + emit modified( mModified ); + } +} + +void SensorDisplay::setSensorOk( bool ok ) +{ + if ( ok ) { + delete mErrorIndicator; + mErrorIndicator = 0; + } else { + if ( mErrorIndicator ) + return; + + TQPixmap errorIcon = TDEGlobal::iconLoader()->loadIcon( "connect_creating", TDEIcon::Desktop, + TDEIcon::SizeSmall ); + if ( !mPlotterWdg ) + return; + + mErrorIndicator = new TQWidget( mPlotterWdg ); + mErrorIndicator->setErasePixmap( errorIcon ); + mErrorIndicator->resize( errorIcon.size() ); + if ( errorIcon.mask() ) + mErrorIndicator->setMask( *errorIcon.mask() ); + mErrorIndicator->move( 0, 0 ); + mErrorIndicator->show(); + } +} + +void SensorDisplay::setTitle( const TQString &title ) +{ + mTitle = title; + + if(!mFrame) { + return; //fixme. create a frame and move widget inside it. + } + + /* Changing the frame title may increase the width of the frame and + * hence breaks the layout. To avoid this, we save the original size + * and restore it after we have set the frame title. */ + TQSize s = mFrame->size(); + + if ( mShowUnit && !mUnit.isEmpty() ) + mFrame->setTitle( mTitle + " [" + mUnit + "]" ); + else + mFrame->setTitle( mTitle ); + mFrame->setGeometry( 0, 0, s.width(), s.height() ); +} + +TQString SensorDisplay::title() const +{ + return mTitle; +} + +void SensorDisplay::setUnit( const TQString &unit ) +{ + mUnit = unit; +} + +TQString SensorDisplay::unit() const +{ + return mUnit; +} + +void SensorDisplay::setShowUnit( bool value ) +{ + mShowUnit = value; +} + +bool SensorDisplay::showUnit() const +{ + return mShowUnit; +} + +void SensorDisplay::setPlotterWidget( TQWidget *wdg ) +{ + mPlotterWdg = wdg; + +} + +TQWidget *SensorDisplay::frame() +{ + return mFrame; +} + +//void SensorDisplay::setNoFrame( bool /*value*/ ) +//{ + //FIXME - delete or create the frame as needed +//} + +bool SensorDisplay::noFrame() const +{ + return !mFrame; +} + +void SensorDisplay::reorderSensors(const TQValueList &orderOfSensors) +{ + TQPtrList newSensors; + for ( uint i = 0; i < orderOfSensors.count(); ++i ) { + newSensors.append( mSensors.at(orderOfSensors[i] )); + } + + mSensors.setAutoDelete( false ); + mSensors = newSensors; + mSensors.setAutoDelete( true ); +} + + +SensorProperties::SensorProperties() +{ +} + +SensorProperties::SensorProperties( const TQString &hostName, const TQString &name, + const TQString &type, const TQString &description ) + : mHostName( hostName ), mName( name ), mType( type ), mDescription( description ) +{ + mOk = false; +} + +SensorProperties::~SensorProperties() +{ +} + +void SensorProperties::setHostName( const TQString &hostName ) +{ + mHostName = hostName; +} + +TQString SensorProperties::hostName() const +{ + return mHostName; +} + +void SensorProperties::setName( const TQString &name ) +{ + mName = name; +} + +TQString SensorProperties::name() const +{ + return mName; +} + +void SensorProperties::setType( const TQString &type ) +{ + mType = type; +} + +TQString SensorProperties::type() const +{ + return mType; +} + +void SensorProperties::setDescription( const TQString &description ) +{ + mDescription = description; +} + +TQString SensorProperties::description() const +{ + return mDescription; +} + +void SensorProperties::setUnit( const TQString &unit ) +{ + mUnit = unit; +} + +TQString SensorProperties::unit() const +{ + return mUnit; +} + +void SensorProperties::setIsOk( bool value ) +{ + mOk = value; +} + +bool SensorProperties::isOk() const +{ + return mOk; +} + +#include "SensorDisplay.moc" diff --git a/ksysguard/gui/SensorDisplayLib/SensorLogger.cc b/ksysguard/gui/SensorDisplayLib/SensorLogger.cc deleted file mode 100644 index 88083fca1..000000000 --- a/ksysguard/gui/SensorDisplayLib/SensorLogger.cc +++ /dev/null @@ -1,437 +0,0 @@ -/* - KSysGuard, the KDE System Guard - - Copyright (c) 2001 Tobias Koenig - - This program is free software; you can redistribute it and/or - modify it under the terms of version 2 of the GNU General Public - License as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -*/ - -#include -#include -#include - -#include -#include - -#include - -#include "SensorLogger.moc" -#include "SensorLoggerSettings.h" - -SLListViewItem::SLListViewItem(TQListView *parent) - : TQListViewItem(parent) -{ -} - -LogSensor::LogSensor(TQListView *parent) - : timerID( NONE ), lowerLimitActive( 0 ), upperLimitActive( 0 ), - lowerLimit( 0 ), upperLimit( 0 ) -{ - TQ_CHECK_PTR(parent); - - monitor = parent; - - lvi = new SLListViewItem(monitor); - TQ_CHECK_PTR(lvi); - - pixmap_running = UserIcon( "running" ); - pixmap_waiting = UserIcon( "waiting" ); - - lvi->setPixmap(0, pixmap_waiting); - lvi->setTextColor(monitor->colorGroup().text()); - - monitor->insertItem(lvi); -} - -LogSensor::~LogSensor(void) -{ - if ((lvi) && (monitor)) - delete lvi; -} - -void -LogSensor::startLogging(void) -{ - lvi->setPixmap(0, pixmap_running); - timerOn(); -} - -void -LogSensor::stopLogging(void) -{ - lvi->setPixmap(0, pixmap_waiting); - lvi->setTextColor(monitor->colorGroup().text()); - lvi->repaint(); - timerOff(); -} - -void -LogSensor::timerEvent(TQTimerEvent*) -{ - KSGRD::SensorMgr->sendRequest(hostName, sensorName, (KSGRD::SensorClient*) this, 42); -} - -void -LogSensor::answerReceived(int id, const TQString& answer) -{ - TQFile logFile(fileName); - - if (!logFile.open(IO_ReadWrite | IO_Append)) - { - stopLogging(); - return; - } - - switch (id) - { - case 42: { - TQTextStream stream(&logFile); - double value = answer.toDouble(); - - if (lowerLimitActive && value < lowerLimit) - { - timerOff(); - lowerLimitActive = false; - lvi->setTextColor(monitor->colorGroup().foreground()); - lvi->repaint(); - KNotifyClient::event(monitor->winId(), "sensor_alarm", TQString("sensor '%1' at '%2' reached lower limit").arg(sensorName).arg(hostName)); - timerOn(); - } else if (upperLimitActive && value > upperLimit) - { - timerOff(); - upperLimitActive = false; - lvi->setTextColor(monitor->colorGroup().foreground()); - lvi->repaint(); - KNotifyClient::event(monitor->winId(), "sensor_alarm", TQString("sensor '%1' at '%2' reached upper limit").arg(sensorName).arg(hostName)); - timerOn(); - } - TQDate date = TQT_TQDATE_OBJECT(TQDateTime::currentDateTime().date()); - TQTime time = TQT_TQTIME_OBJECT(TQDateTime::currentDateTime().time()); - - stream << TQString("%1 %2 %3 %4 %5: %6\n").arg(date.shortMonthName(date.month())).arg(date.day()).arg(time.toString()).arg(hostName).arg(sensorName).arg(value); - } - } - - logFile.close(); -} - -SensorLogger::SensorLogger(TQWidget *parent, const char *name, const TQString& title) - : KSGRD::SensorDisplay(parent, name, title) -{ - monitor = new TQListView(this, "monitor"); - TQ_CHECK_PTR(monitor); - - monitor->addColumn(i18n("Logging")); - monitor->addColumn(i18n("Timer Interval")); - monitor->addColumn(i18n("Sensor Name")); - monitor->addColumn(i18n("Host Name")); - monitor->addColumn(i18n("Log File")); - - TQColorGroup cgroup = monitor->colorGroup(); - cgroup.setColor(TQColorGroup::Text, KSGRD::Style->firstForegroundColor()); - cgroup.setColor(TQColorGroup::Base, KSGRD::Style->backgroundColor()); - cgroup.setColor(TQColorGroup::Foreground, KSGRD::Style->alarmColor()); - monitor->setPalette(TQPalette(cgroup, cgroup, cgroup)); - monitor->setSelectionMode(TQListView::NoSelection); - - connect(monitor, TQT_SIGNAL(rightButtonClicked(TQListViewItem*, const TQPoint&, int)), this, TQT_SLOT(RMBClicked(TQListViewItem*, const TQPoint&, int))); - - setTitle(i18n("Sensor Logger")); - - logSensors.setAutoDelete(true); - - setPlotterWidget(monitor); - - setMinimumSize(50, 25); - setModified(false); -} - -SensorLogger::~SensorLogger(void) -{ -} - -bool -SensorLogger::addSensor(const TQString& hostName, const TQString& sensorName, const TQString& sensorType, const TQString&) -{ - if (sensorType != "integer" && sensorType != "float") - return (false); - - sld = new SensorLoggerDlg(this, "SensorLoggerDlg"); - TQ_CHECK_PTR(sld); - - if (sld->exec()) { - if (!sld->fileName().isEmpty()) { - LogSensor *sensor = new LogSensor(monitor); - TQ_CHECK_PTR(sensor); - - sensor->setHostName(hostName); - sensor->setSensorName(sensorName); - sensor->setFileName(sld->fileName()); - sensor->setTimerInterval(sld->timerInterval()); - sensor->setLowerLimitActive(sld->lowerLimitActive()); - sensor->setUpperLimitActive(sld->upperLimitActive()); - sensor->setLowerLimit(sld->lowerLimit()); - sensor->setUpperLimit(sld->upperLimit()); - - logSensors.append(sensor); - - setModified(true); - } - } - - delete sld; - sld = 0; - - return (true); -} - -bool -SensorLogger::editSensor(LogSensor* sensor) -{ - sld = new SensorLoggerDlg(this, "SensorLoggerDlg"); - TQ_CHECK_PTR(sld); - - sld->setFileName(sensor->getFileName()); - sld->setTimerInterval(sensor->getTimerInterval()); - sld->setLowerLimitActive(sensor->getLowerLimitActive()); - sld->setLowerLimit(sensor->getLowerLimit()); - sld->setUpperLimitActive(sensor->getUpperLimitActive()); - sld->setUpperLimit(sensor->getUpperLimit()); - - if (sld->exec()) { - if (!sld->fileName().isEmpty()) { - sensor->setFileName(sld->fileName()); - sensor->setTimerInterval(sld->timerInterval()); - sensor->setLowerLimitActive(sld->lowerLimitActive()); - sensor->setUpperLimitActive(sld->upperLimitActive()); - sensor->setLowerLimit(sld->lowerLimit()); - sensor->setUpperLimit(sld->upperLimit()); - - setModified(true); - } - } - - delete sld; - sld = 0; - - return (true); -} - -void -SensorLogger::configureSettings() -{ - TQColorGroup cgroup = monitor->colorGroup(); - - sls = new SensorLoggerSettings(this, "SensorLoggerSettings"); - TQ_CHECK_PTR(sls); - - connect( sls, TQT_SIGNAL( applyClicked() ), TQT_SLOT( applySettings() ) ); - - sls->setTitle(title()); - sls->setForegroundColor(cgroup.text()); - sls->setBackgroundColor(cgroup.base()); - sls->setAlarmColor(cgroup.foreground()); - - if (sls->exec()) - applySettings(); - - delete sls; - sls = 0; -} - -void -SensorLogger::applySettings() -{ - TQColorGroup cgroup = monitor->colorGroup(); - - setTitle(sls->title()); - - cgroup.setColor(TQColorGroup::Text, sls->foregroundColor()); - cgroup.setColor(TQColorGroup::Base, sls->backgroundColor()); - cgroup.setColor(TQColorGroup::Foreground, sls->alarmColor()); - monitor->setPalette(TQPalette(cgroup, cgroup, cgroup)); - - setModified(true); -} - -void -SensorLogger::applyStyle(void) -{ - TQColorGroup cgroup = monitor->colorGroup(); - - cgroup.setColor(TQColorGroup::Text, KSGRD::Style->firstForegroundColor()); - cgroup.setColor(TQColorGroup::Base, KSGRD::Style->backgroundColor()); - cgroup.setColor(TQColorGroup::Foreground, KSGRD::Style->alarmColor()); - monitor->setPalette(TQPalette(cgroup, cgroup, cgroup)); - - setModified(true); -} - -bool -SensorLogger::restoreSettings(TQDomElement& element) -{ - TQColorGroup cgroup = monitor->colorGroup(); - - cgroup.setColor(TQColorGroup::Text, restoreColor(element, "textColor", Qt::green)); - cgroup.setColor(TQColorGroup::Base, restoreColor(element, "backgroundColor", Qt::black)); - cgroup.setColor(TQColorGroup::Foreground, restoreColor(element, "alarmColor", Qt::red)); - monitor->setPalette(TQPalette(cgroup, cgroup, cgroup)); - - logSensors.clear(); - - TQDomNodeList dnList = element.elementsByTagName("logsensors"); - for (uint i = 0; i < dnList.count(); i++) { - TQDomElement element = dnList.item(i).toElement(); - LogSensor* sensor = new LogSensor(monitor); - TQ_CHECK_PTR(sensor); - - sensor->setHostName(element.attribute("hostName")); - sensor->setSensorName(element.attribute("sensorName")); - sensor->setFileName(element.attribute("fileName")); - sensor->setTimerInterval(element.attribute("timerInterval").toInt()); - sensor->setLowerLimitActive(element.attribute("lowerLimitActive").toInt()); - sensor->setLowerLimit(element.attribute("lowerLimit").toDouble()); - sensor->setUpperLimitActive(element.attribute("upperLimitActive").toInt()); - sensor->setUpperLimit(element.attribute("upperLimit").toDouble()); - - logSensors.append(sensor); - } - - SensorDisplay::restoreSettings(element); - - setModified(false); - - return (true); -} - -bool -SensorLogger::saveSettings(TQDomDocument& doc, TQDomElement& element, bool save) -{ - saveColor(element, "textColor", monitor->colorGroup().text()); - saveColor(element, "backgroundColor", monitor->colorGroup().base()); - saveColor(element, "alarmColor", monitor->colorGroup().foreground()); - - for (LogSensor* sensor = logSensors.first(); sensor != 0; sensor = logSensors.next()) - { - TQDomElement log = doc.createElement("logsensors"); - log.setAttribute("sensorName", sensor->getSensorName()); - log.setAttribute("hostName", sensor->getHostName()); - log.setAttribute("fileName", sensor->getFileName()); - log.setAttribute("timerInterval", sensor->getTimerInterval()); - log.setAttribute("lowerLimitActive", TQString("%1").arg(sensor->getLowerLimitActive())); - log.setAttribute("lowerLimit", TQString("%1").arg(sensor->getLowerLimit())); - log.setAttribute("upperLimitActive", TQString("%1").arg(sensor->getUpperLimitActive())); - log.setAttribute("upperLimit", TQString("%1").arg(sensor->getUpperLimit())); - - element.appendChild(log); - } - - SensorDisplay::saveSettings(doc, element); - - if (save) - setModified(false); - - return (true); -} - -void -SensorLogger::answerReceived(int, const TQString&) -{ - // we do not use this, since all answers are received by the LogSensors -} - -void -SensorLogger::resizeEvent(TQResizeEvent*) -{ - frame()->setGeometry(0, 0, this->width(), this->height()); - monitor->setGeometry(10, 20, this->width() - 20, this->height() - 30); -} - -LogSensor* -SensorLogger::getLogSensor(TQListViewItem* item) -{ - for (LogSensor* sensor = logSensors.first(); sensor != 0; sensor = logSensors.next()) - { - if (item == sensor->getListViewItem()) { - return sensor; - } - } - - return NULL; -} - -void -SensorLogger::RMBClicked(TQListViewItem* item, const TQPoint& point, int) -{ - TQPopupMenu pm; - if (hasSettingsDialog()) - pm.insertItem(i18n("&Properties"), 1); - pm.insertItem(i18n("&Remove Display"), 2); - pm.insertSeparator(-1); - pm.insertItem(i18n("&Remove Sensor"), 3); - pm.insertItem(i18n("&Edit Sensor..."), 4); - - if ( !item ) - { - pm.setItemEnabled( 3, false ); - pm.setItemEnabled( 4, false ); - } - else - { - LogSensor* sensor = getLogSensor(item); - - if ( sensor->isLogging() ) - pm.insertItem(i18n("St&op Logging"), 6); - else - pm.insertItem(i18n("S&tart Logging"), 5); - } - - switch (pm.exec(point)) - { - case 1: - configureSettings(); - break; - case 2: { - TQCustomEvent* ev = new TQCustomEvent(TQEvent::User); - ev->setData(this); - kapp->postEvent(parent(), ev); - break; - } - case 3: { - LogSensor* sensor = getLogSensor(item); - if (sensor) - logSensors.remove(sensor); - break; - } - case 4: { - LogSensor* sensor = getLogSensor(item); - if (sensor) - editSensor(sensor); - break; - } - case 5: { - LogSensor* sensor = getLogSensor(item); - if (sensor) - sensor->startLogging(); - break; - } - case 6: { - LogSensor* sensor = getLogSensor(item); - if (sensor) - sensor->stopLogging(); - break; - } - } -} diff --git a/ksysguard/gui/SensorDisplayLib/SensorLogger.cpp b/ksysguard/gui/SensorDisplayLib/SensorLogger.cpp new file mode 100644 index 000000000..88083fca1 --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/SensorLogger.cpp @@ -0,0 +1,437 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 2001 Tobias Koenig + + This program is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include +#include +#include + +#include +#include + +#include + +#include "SensorLogger.moc" +#include "SensorLoggerSettings.h" + +SLListViewItem::SLListViewItem(TQListView *parent) + : TQListViewItem(parent) +{ +} + +LogSensor::LogSensor(TQListView *parent) + : timerID( NONE ), lowerLimitActive( 0 ), upperLimitActive( 0 ), + lowerLimit( 0 ), upperLimit( 0 ) +{ + TQ_CHECK_PTR(parent); + + monitor = parent; + + lvi = new SLListViewItem(monitor); + TQ_CHECK_PTR(lvi); + + pixmap_running = UserIcon( "running" ); + pixmap_waiting = UserIcon( "waiting" ); + + lvi->setPixmap(0, pixmap_waiting); + lvi->setTextColor(monitor->colorGroup().text()); + + monitor->insertItem(lvi); +} + +LogSensor::~LogSensor(void) +{ + if ((lvi) && (monitor)) + delete lvi; +} + +void +LogSensor::startLogging(void) +{ + lvi->setPixmap(0, pixmap_running); + timerOn(); +} + +void +LogSensor::stopLogging(void) +{ + lvi->setPixmap(0, pixmap_waiting); + lvi->setTextColor(monitor->colorGroup().text()); + lvi->repaint(); + timerOff(); +} + +void +LogSensor::timerEvent(TQTimerEvent*) +{ + KSGRD::SensorMgr->sendRequest(hostName, sensorName, (KSGRD::SensorClient*) this, 42); +} + +void +LogSensor::answerReceived(int id, const TQString& answer) +{ + TQFile logFile(fileName); + + if (!logFile.open(IO_ReadWrite | IO_Append)) + { + stopLogging(); + return; + } + + switch (id) + { + case 42: { + TQTextStream stream(&logFile); + double value = answer.toDouble(); + + if (lowerLimitActive && value < lowerLimit) + { + timerOff(); + lowerLimitActive = false; + lvi->setTextColor(monitor->colorGroup().foreground()); + lvi->repaint(); + KNotifyClient::event(monitor->winId(), "sensor_alarm", TQString("sensor '%1' at '%2' reached lower limit").arg(sensorName).arg(hostName)); + timerOn(); + } else if (upperLimitActive && value > upperLimit) + { + timerOff(); + upperLimitActive = false; + lvi->setTextColor(monitor->colorGroup().foreground()); + lvi->repaint(); + KNotifyClient::event(monitor->winId(), "sensor_alarm", TQString("sensor '%1' at '%2' reached upper limit").arg(sensorName).arg(hostName)); + timerOn(); + } + TQDate date = TQT_TQDATE_OBJECT(TQDateTime::currentDateTime().date()); + TQTime time = TQT_TQTIME_OBJECT(TQDateTime::currentDateTime().time()); + + stream << TQString("%1 %2 %3 %4 %5: %6\n").arg(date.shortMonthName(date.month())).arg(date.day()).arg(time.toString()).arg(hostName).arg(sensorName).arg(value); + } + } + + logFile.close(); +} + +SensorLogger::SensorLogger(TQWidget *parent, const char *name, const TQString& title) + : KSGRD::SensorDisplay(parent, name, title) +{ + monitor = new TQListView(this, "monitor"); + TQ_CHECK_PTR(monitor); + + monitor->addColumn(i18n("Logging")); + monitor->addColumn(i18n("Timer Interval")); + monitor->addColumn(i18n("Sensor Name")); + monitor->addColumn(i18n("Host Name")); + monitor->addColumn(i18n("Log File")); + + TQColorGroup cgroup = monitor->colorGroup(); + cgroup.setColor(TQColorGroup::Text, KSGRD::Style->firstForegroundColor()); + cgroup.setColor(TQColorGroup::Base, KSGRD::Style->backgroundColor()); + cgroup.setColor(TQColorGroup::Foreground, KSGRD::Style->alarmColor()); + monitor->setPalette(TQPalette(cgroup, cgroup, cgroup)); + monitor->setSelectionMode(TQListView::NoSelection); + + connect(monitor, TQT_SIGNAL(rightButtonClicked(TQListViewItem*, const TQPoint&, int)), this, TQT_SLOT(RMBClicked(TQListViewItem*, const TQPoint&, int))); + + setTitle(i18n("Sensor Logger")); + + logSensors.setAutoDelete(true); + + setPlotterWidget(monitor); + + setMinimumSize(50, 25); + setModified(false); +} + +SensorLogger::~SensorLogger(void) +{ +} + +bool +SensorLogger::addSensor(const TQString& hostName, const TQString& sensorName, const TQString& sensorType, const TQString&) +{ + if (sensorType != "integer" && sensorType != "float") + return (false); + + sld = new SensorLoggerDlg(this, "SensorLoggerDlg"); + TQ_CHECK_PTR(sld); + + if (sld->exec()) { + if (!sld->fileName().isEmpty()) { + LogSensor *sensor = new LogSensor(monitor); + TQ_CHECK_PTR(sensor); + + sensor->setHostName(hostName); + sensor->setSensorName(sensorName); + sensor->setFileName(sld->fileName()); + sensor->setTimerInterval(sld->timerInterval()); + sensor->setLowerLimitActive(sld->lowerLimitActive()); + sensor->setUpperLimitActive(sld->upperLimitActive()); + sensor->setLowerLimit(sld->lowerLimit()); + sensor->setUpperLimit(sld->upperLimit()); + + logSensors.append(sensor); + + setModified(true); + } + } + + delete sld; + sld = 0; + + return (true); +} + +bool +SensorLogger::editSensor(LogSensor* sensor) +{ + sld = new SensorLoggerDlg(this, "SensorLoggerDlg"); + TQ_CHECK_PTR(sld); + + sld->setFileName(sensor->getFileName()); + sld->setTimerInterval(sensor->getTimerInterval()); + sld->setLowerLimitActive(sensor->getLowerLimitActive()); + sld->setLowerLimit(sensor->getLowerLimit()); + sld->setUpperLimitActive(sensor->getUpperLimitActive()); + sld->setUpperLimit(sensor->getUpperLimit()); + + if (sld->exec()) { + if (!sld->fileName().isEmpty()) { + sensor->setFileName(sld->fileName()); + sensor->setTimerInterval(sld->timerInterval()); + sensor->setLowerLimitActive(sld->lowerLimitActive()); + sensor->setUpperLimitActive(sld->upperLimitActive()); + sensor->setLowerLimit(sld->lowerLimit()); + sensor->setUpperLimit(sld->upperLimit()); + + setModified(true); + } + } + + delete sld; + sld = 0; + + return (true); +} + +void +SensorLogger::configureSettings() +{ + TQColorGroup cgroup = monitor->colorGroup(); + + sls = new SensorLoggerSettings(this, "SensorLoggerSettings"); + TQ_CHECK_PTR(sls); + + connect( sls, TQT_SIGNAL( applyClicked() ), TQT_SLOT( applySettings() ) ); + + sls->setTitle(title()); + sls->setForegroundColor(cgroup.text()); + sls->setBackgroundColor(cgroup.base()); + sls->setAlarmColor(cgroup.foreground()); + + if (sls->exec()) + applySettings(); + + delete sls; + sls = 0; +} + +void +SensorLogger::applySettings() +{ + TQColorGroup cgroup = monitor->colorGroup(); + + setTitle(sls->title()); + + cgroup.setColor(TQColorGroup::Text, sls->foregroundColor()); + cgroup.setColor(TQColorGroup::Base, sls->backgroundColor()); + cgroup.setColor(TQColorGroup::Foreground, sls->alarmColor()); + monitor->setPalette(TQPalette(cgroup, cgroup, cgroup)); + + setModified(true); +} + +void +SensorLogger::applyStyle(void) +{ + TQColorGroup cgroup = monitor->colorGroup(); + + cgroup.setColor(TQColorGroup::Text, KSGRD::Style->firstForegroundColor()); + cgroup.setColor(TQColorGroup::Base, KSGRD::Style->backgroundColor()); + cgroup.setColor(TQColorGroup::Foreground, KSGRD::Style->alarmColor()); + monitor->setPalette(TQPalette(cgroup, cgroup, cgroup)); + + setModified(true); +} + +bool +SensorLogger::restoreSettings(TQDomElement& element) +{ + TQColorGroup cgroup = monitor->colorGroup(); + + cgroup.setColor(TQColorGroup::Text, restoreColor(element, "textColor", Qt::green)); + cgroup.setColor(TQColorGroup::Base, restoreColor(element, "backgroundColor", Qt::black)); + cgroup.setColor(TQColorGroup::Foreground, restoreColor(element, "alarmColor", Qt::red)); + monitor->setPalette(TQPalette(cgroup, cgroup, cgroup)); + + logSensors.clear(); + + TQDomNodeList dnList = element.elementsByTagName("logsensors"); + for (uint i = 0; i < dnList.count(); i++) { + TQDomElement element = dnList.item(i).toElement(); + LogSensor* sensor = new LogSensor(monitor); + TQ_CHECK_PTR(sensor); + + sensor->setHostName(element.attribute("hostName")); + sensor->setSensorName(element.attribute("sensorName")); + sensor->setFileName(element.attribute("fileName")); + sensor->setTimerInterval(element.attribute("timerInterval").toInt()); + sensor->setLowerLimitActive(element.attribute("lowerLimitActive").toInt()); + sensor->setLowerLimit(element.attribute("lowerLimit").toDouble()); + sensor->setUpperLimitActive(element.attribute("upperLimitActive").toInt()); + sensor->setUpperLimit(element.attribute("upperLimit").toDouble()); + + logSensors.append(sensor); + } + + SensorDisplay::restoreSettings(element); + + setModified(false); + + return (true); +} + +bool +SensorLogger::saveSettings(TQDomDocument& doc, TQDomElement& element, bool save) +{ + saveColor(element, "textColor", monitor->colorGroup().text()); + saveColor(element, "backgroundColor", monitor->colorGroup().base()); + saveColor(element, "alarmColor", monitor->colorGroup().foreground()); + + for (LogSensor* sensor = logSensors.first(); sensor != 0; sensor = logSensors.next()) + { + TQDomElement log = doc.createElement("logsensors"); + log.setAttribute("sensorName", sensor->getSensorName()); + log.setAttribute("hostName", sensor->getHostName()); + log.setAttribute("fileName", sensor->getFileName()); + log.setAttribute("timerInterval", sensor->getTimerInterval()); + log.setAttribute("lowerLimitActive", TQString("%1").arg(sensor->getLowerLimitActive())); + log.setAttribute("lowerLimit", TQString("%1").arg(sensor->getLowerLimit())); + log.setAttribute("upperLimitActive", TQString("%1").arg(sensor->getUpperLimitActive())); + log.setAttribute("upperLimit", TQString("%1").arg(sensor->getUpperLimit())); + + element.appendChild(log); + } + + SensorDisplay::saveSettings(doc, element); + + if (save) + setModified(false); + + return (true); +} + +void +SensorLogger::answerReceived(int, const TQString&) +{ + // we do not use this, since all answers are received by the LogSensors +} + +void +SensorLogger::resizeEvent(TQResizeEvent*) +{ + frame()->setGeometry(0, 0, this->width(), this->height()); + monitor->setGeometry(10, 20, this->width() - 20, this->height() - 30); +} + +LogSensor* +SensorLogger::getLogSensor(TQListViewItem* item) +{ + for (LogSensor* sensor = logSensors.first(); sensor != 0; sensor = logSensors.next()) + { + if (item == sensor->getListViewItem()) { + return sensor; + } + } + + return NULL; +} + +void +SensorLogger::RMBClicked(TQListViewItem* item, const TQPoint& point, int) +{ + TQPopupMenu pm; + if (hasSettingsDialog()) + pm.insertItem(i18n("&Properties"), 1); + pm.insertItem(i18n("&Remove Display"), 2); + pm.insertSeparator(-1); + pm.insertItem(i18n("&Remove Sensor"), 3); + pm.insertItem(i18n("&Edit Sensor..."), 4); + + if ( !item ) + { + pm.setItemEnabled( 3, false ); + pm.setItemEnabled( 4, false ); + } + else + { + LogSensor* sensor = getLogSensor(item); + + if ( sensor->isLogging() ) + pm.insertItem(i18n("St&op Logging"), 6); + else + pm.insertItem(i18n("S&tart Logging"), 5); + } + + switch (pm.exec(point)) + { + case 1: + configureSettings(); + break; + case 2: { + TQCustomEvent* ev = new TQCustomEvent(TQEvent::User); + ev->setData(this); + kapp->postEvent(parent(), ev); + break; + } + case 3: { + LogSensor* sensor = getLogSensor(item); + if (sensor) + logSensors.remove(sensor); + break; + } + case 4: { + LogSensor* sensor = getLogSensor(item); + if (sensor) + editSensor(sensor); + break; + } + case 5: { + LogSensor* sensor = getLogSensor(item); + if (sensor) + sensor->startLogging(); + break; + } + case 6: { + LogSensor* sensor = getLogSensor(item); + if (sensor) + sensor->stopLogging(); + break; + } + } +} diff --git a/ksysguard/gui/SensorDisplayLib/SensorLoggerDlg.cc b/ksysguard/gui/SensorDisplayLib/SensorLoggerDlg.cc deleted file mode 100644 index 64c76f5b8..000000000 --- a/ksysguard/gui/SensorDisplayLib/SensorLoggerDlg.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* This file is part of the KDE project - Copyright ( C ) 2003 Nadeem Hasan - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "SensorLoggerDlg.h" -#include "SensorLoggerDlgWidget.h" - -#include - -#include - -SensorLoggerDlg::SensorLoggerDlg( TQWidget *parent, const char *name ) - : KDialogBase( parent, name, true, i18n( "Sensor Logger" ), - Ok|Cancel, Ok, true ) -{ - TQWidget *main = new TQWidget( this ); - - TQVBoxLayout *topLayout = new TQVBoxLayout( main, 0, KDialog::spacingHint() ); - - m_loggerWidget = new SensorLoggerDlgWidget( main, "m_loggerWidget" ); - topLayout->addWidget( m_loggerWidget ); - topLayout->addStretch(); - - setMainWidget( main ); -} - -TQString SensorLoggerDlg::fileName() const -{ - return m_loggerWidget->fileName(); -} - -int SensorLoggerDlg::timerInterval() const -{ - return m_loggerWidget->timerInterval(); -} - -bool SensorLoggerDlg::lowerLimitActive() const -{ - return m_loggerWidget->lowerLimitActive(); -} - -bool SensorLoggerDlg::upperLimitActive() const -{ - return m_loggerWidget->upperLimitActive(); -} - -double SensorLoggerDlg::lowerLimit() const -{ - return m_loggerWidget->lowerLimit(); -} - -double SensorLoggerDlg::upperLimit() const -{ - return m_loggerWidget->upperLimit(); -} - -void SensorLoggerDlg::setFileName( const TQString &url ) -{ - m_loggerWidget->setFileName( url ); -} - -void SensorLoggerDlg::setTimerInterval( int i ) -{ - m_loggerWidget->setTimerInterval( i ); -} - -void SensorLoggerDlg::setLowerLimitActive( bool b ) -{ - m_loggerWidget->setLowerLimitActive( b ); -} - -void SensorLoggerDlg::setUpperLimitActive( bool b ) -{ - m_loggerWidget->setUpperLimitActive( b ); -} - -void SensorLoggerDlg::setLowerLimit( double limit ) -{ - m_loggerWidget->setLowerLimit( limit ); -} - -void SensorLoggerDlg::setUpperLimit( double limit ) -{ - m_loggerWidget->setUpperLimit( limit ); -} - -#include "SensorLoggerDlg.moc" diff --git a/ksysguard/gui/SensorDisplayLib/SensorLoggerDlg.cpp b/ksysguard/gui/SensorDisplayLib/SensorLoggerDlg.cpp new file mode 100644 index 000000000..64c76f5b8 --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/SensorLoggerDlg.cpp @@ -0,0 +1,102 @@ +/* This file is part of the KDE project + Copyright ( C ) 2003 Nadeem Hasan + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "SensorLoggerDlg.h" +#include "SensorLoggerDlgWidget.h" + +#include + +#include + +SensorLoggerDlg::SensorLoggerDlg( TQWidget *parent, const char *name ) + : KDialogBase( parent, name, true, i18n( "Sensor Logger" ), + Ok|Cancel, Ok, true ) +{ + TQWidget *main = new TQWidget( this ); + + TQVBoxLayout *topLayout = new TQVBoxLayout( main, 0, KDialog::spacingHint() ); + + m_loggerWidget = new SensorLoggerDlgWidget( main, "m_loggerWidget" ); + topLayout->addWidget( m_loggerWidget ); + topLayout->addStretch(); + + setMainWidget( main ); +} + +TQString SensorLoggerDlg::fileName() const +{ + return m_loggerWidget->fileName(); +} + +int SensorLoggerDlg::timerInterval() const +{ + return m_loggerWidget->timerInterval(); +} + +bool SensorLoggerDlg::lowerLimitActive() const +{ + return m_loggerWidget->lowerLimitActive(); +} + +bool SensorLoggerDlg::upperLimitActive() const +{ + return m_loggerWidget->upperLimitActive(); +} + +double SensorLoggerDlg::lowerLimit() const +{ + return m_loggerWidget->lowerLimit(); +} + +double SensorLoggerDlg::upperLimit() const +{ + return m_loggerWidget->upperLimit(); +} + +void SensorLoggerDlg::setFileName( const TQString &url ) +{ + m_loggerWidget->setFileName( url ); +} + +void SensorLoggerDlg::setTimerInterval( int i ) +{ + m_loggerWidget->setTimerInterval( i ); +} + +void SensorLoggerDlg::setLowerLimitActive( bool b ) +{ + m_loggerWidget->setLowerLimitActive( b ); +} + +void SensorLoggerDlg::setUpperLimitActive( bool b ) +{ + m_loggerWidget->setUpperLimitActive( b ); +} + +void SensorLoggerDlg::setLowerLimit( double limit ) +{ + m_loggerWidget->setLowerLimit( limit ); +} + +void SensorLoggerDlg::setUpperLimit( double limit ) +{ + m_loggerWidget->setUpperLimit( limit ); +} + +#include "SensorLoggerDlg.moc" diff --git a/ksysguard/gui/SensorDisplayLib/SensorLoggerSettings.cc b/ksysguard/gui/SensorDisplayLib/SensorLoggerSettings.cc deleted file mode 100644 index c2206e092..000000000 --- a/ksysguard/gui/SensorDisplayLib/SensorLoggerSettings.cc +++ /dev/null @@ -1,73 +0,0 @@ -/* This file is part of the KDE project - Copyright ( C ) 2003 Nadeem Hasan - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "SensorLoggerSettings.h" -#include "SensorLoggerSettingsWidget.h" - -#include - -SensorLoggerSettings::SensorLoggerSettings( TQWidget *parent, const char *name ) - : KDialogBase( parent, name, true, i18n( "Sensor Logger Settings" ), - Ok|Apply|Cancel, Ok, true ) -{ - m_settingsWidget = new SensorLoggerSettingsWidget( this, "m_settingsWidget" ); - setMainWidget( m_settingsWidget ); -} - -TQString SensorLoggerSettings::title() -{ - return m_settingsWidget->title(); -} - -TQColor SensorLoggerSettings::foregroundColor() -{ - return m_settingsWidget->foregroundColor(); -} - -TQColor SensorLoggerSettings::backgroundColor() -{ - return m_settingsWidget->backgroundColor(); -} - -TQColor SensorLoggerSettings::alarmColor() -{ - return m_settingsWidget->alarmColor(); -} - -void SensorLoggerSettings::setTitle( const TQString &title ) -{ - m_settingsWidget->setTitle( title ); -} - -void SensorLoggerSettings::setBackgroundColor( const TQColor &c ) -{ - m_settingsWidget->setBackgroundColor( c ); -} - -void SensorLoggerSettings::setForegroundColor( const TQColor &c ) -{ - m_settingsWidget->setForegroundColor( c ); -} - -void SensorLoggerSettings::setAlarmColor( const TQColor &c ) -{ - m_settingsWidget->setAlarmColor( c ); -} - -#include "SensorLoggerSettings.moc" diff --git a/ksysguard/gui/SensorDisplayLib/SensorLoggerSettings.cpp b/ksysguard/gui/SensorDisplayLib/SensorLoggerSettings.cpp new file mode 100644 index 000000000..c2206e092 --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/SensorLoggerSettings.cpp @@ -0,0 +1,73 @@ +/* This file is part of the KDE project + Copyright ( C ) 2003 Nadeem Hasan + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "SensorLoggerSettings.h" +#include "SensorLoggerSettingsWidget.h" + +#include + +SensorLoggerSettings::SensorLoggerSettings( TQWidget *parent, const char *name ) + : KDialogBase( parent, name, true, i18n( "Sensor Logger Settings" ), + Ok|Apply|Cancel, Ok, true ) +{ + m_settingsWidget = new SensorLoggerSettingsWidget( this, "m_settingsWidget" ); + setMainWidget( m_settingsWidget ); +} + +TQString SensorLoggerSettings::title() +{ + return m_settingsWidget->title(); +} + +TQColor SensorLoggerSettings::foregroundColor() +{ + return m_settingsWidget->foregroundColor(); +} + +TQColor SensorLoggerSettings::backgroundColor() +{ + return m_settingsWidget->backgroundColor(); +} + +TQColor SensorLoggerSettings::alarmColor() +{ + return m_settingsWidget->alarmColor(); +} + +void SensorLoggerSettings::setTitle( const TQString &title ) +{ + m_settingsWidget->setTitle( title ); +} + +void SensorLoggerSettings::setBackgroundColor( const TQColor &c ) +{ + m_settingsWidget->setBackgroundColor( c ); +} + +void SensorLoggerSettings::setForegroundColor( const TQColor &c ) +{ + m_settingsWidget->setForegroundColor( c ); +} + +void SensorLoggerSettings::setAlarmColor( const TQColor &c ) +{ + m_settingsWidget->setAlarmColor( c ); +} + +#include "SensorLoggerSettings.moc" diff --git a/ksysguard/gui/SensorDisplayLib/SignalPlotter.cc b/ksysguard/gui/SensorDisplayLib/SignalPlotter.cc deleted file mode 100644 index bcb0b821b..000000000 --- a/ksysguard/gui/SensorDisplayLib/SignalPlotter.cc +++ /dev/null @@ -1,648 +0,0 @@ -/* - KSysGuard, the KDE System Guard - - Copyright (c) 1999 - 2002 Chris Schlaeger - - This program is free software; you can redistribute it and/or - modify it under the terms of version 2 of the GNU General Public - License as published by the Free Software Foundation - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - KSysGuard is currently maintained by Chris Schlaeger . - Please do not commit any changes without consulting me first. Thanks! - -*/ - -#include -#include - -#include -#include - -#include -#include - -#include - -#include "SignalPlotter.h" - -SignalPlotter::SignalPlotter( TQWidget *parent, const char *name ) - : TQWidget( parent, name ) -{ - // Auto deletion does not work for pointer to arrays. - mBeamData.setAutoDelete( false ); - - setBackgroundMode( NoBackground ); - mShowThinFrame = true; - mSamples = 0; - mMinValue = mMaxValue = 0.0; - mUseAutoRange = true; - - mGraphStyle = GRAPH_POLYGON; - - // Anything smaller than this does not make sense. - setMinimumSize( 16, 16 ); - setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, - TQSizePolicy::Expanding, false ) ); - - mShowVerticalLines = true; - mVerticalLinesColor = KSGRD::Style->firstForegroundColor(); - mVerticalLinesDistance = 30; - mVerticalLinesScroll = true; - mVerticalLinesOffset = 0; - mHorizontalScale = 1; - - mShowHorizontalLines = true; - mHorizontalLinesColor = KSGRD::Style->secondForegroundColor(); - mHorizontalLinesCount = 5; - - mShowLabels = true; - mShowTopBar = false; - mFontSize = KSGRD::Style->fontSize(); - - mBackgroundColor = KSGRD::Style->backgroundColor(); -} - -SignalPlotter::~SignalPlotter() -{ - for ( double* p = mBeamData.first(); p; p = mBeamData.next() ) - delete [] p; -} - -bool SignalPlotter::addBeam( const TQColor &color ) -{ - double* d = new double[ mSamples ]; - memset( d, 0, sizeof(double) * mSamples ); - mBeamData.append( d ); - mBeamColor.append( color ); - - return true; -} - -void SignalPlotter::addSample( const TQValueList& sampleBuf ) -{ - if ( mBeamData.count() != sampleBuf.count() ) - return; - - double* d; - if ( mUseAutoRange ) { - double sum = 0; - for ( d = mBeamData.first(); d; d = mBeamData.next() ) { - sum += d[ 0 ]; - if ( sum < mMinValue ) - mMinValue = sum; - if ( sum > mMaxValue ) - mMaxValue = sum; - } - } - - /* If the vertical lines are scrolling, increment the offset - * so they move with the data. The vOffset / hScale confusion - * is because v refers to Vertical Lines, and h to the horizontal - * distance between the vertical lines. */ - if ( mVerticalLinesScroll ) { - mVerticalLinesOffset = ( mVerticalLinesOffset + mHorizontalScale) - % mVerticalLinesDistance; - } - - // Shift data buffers one sample down and insert new samples. - TQValueList::ConstIterator s; - for ( d = mBeamData.first(), s = sampleBuf.begin(); d; d = mBeamData.next(), ++s ) { - memmove( d, d + 1, ( mSamples - 1 ) * sizeof( double ) ); - d[ mSamples - 1 ] = *s; - } - - update(); -} - -void SignalPlotter::reorderBeams( const TQValueList& newOrder ) -{ - if(newOrder.count() != mBeamData.count()) { - kdDebug() << "Serious problem in move sample" << endl; - return; - } - TQPtrList newBeamData; - TQValueList newBeamColor; - - for(uint i = 0; i < newOrder.count(); i++) { - int newIndex = newOrder[i]; - newBeamData.append(mBeamData.at(newIndex)); - newBeamColor.append(*mBeamColor.at(newIndex)); - } - mBeamData = newBeamData; - mBeamColor = newBeamColor; - -} - -void SignalPlotter::changeRange( int beam, double min, double max ) -{ - // Only the first beam affects range calculation. - if ( beam > 1 ) - return; - - mMinValue = min; - mMaxValue = max; -} - -TQValueList &SignalPlotter::beamColors() -{ - return mBeamColor; -} - -void SignalPlotter::removeBeam( uint pos ) -{ - mBeamColor.remove( mBeamColor.at( pos ) ); - double *p = mBeamData.take( pos ); - delete [] p; -} - -void SignalPlotter::setTitle( const TQString &title ) -{ - mTitle = title; -} - -TQString SignalPlotter::title() const -{ - return mTitle; -} - -void SignalPlotter::setUseAutoRange( bool value ) -{ - mUseAutoRange = value; -} - -bool SignalPlotter::useAutoRange() const -{ - return mUseAutoRange; -} - -void SignalPlotter::setMinValue( double min ) -{ - mMinValue = min; -} - -double SignalPlotter::minValue() const -{ - return ( mUseAutoRange ? 0 : mMinValue ); -} - -void SignalPlotter::setMaxValue( double max ) -{ - mMaxValue = max; -} - -double SignalPlotter::maxValue() const -{ - return ( mUseAutoRange ? 0 : mMaxValue ); -} - -void SignalPlotter::setGraphStyle( uint style ) -{ - mGraphStyle = style; -} - -uint SignalPlotter::graphStyle() const -{ - return mGraphStyle; -} - -void SignalPlotter::setHorizontalScale( uint scale ) -{ - if (scale == mHorizontalScale) - return; - - mHorizontalScale = scale; - if (isVisible()) - updateDataBuffers(); -} - -int SignalPlotter::horizontalScale() const -{ - return mHorizontalScale; -} - -void SignalPlotter::setShowVerticalLines( bool value ) -{ - mShowVerticalLines = value; -} - -bool SignalPlotter::showVerticalLines() const -{ - return mShowVerticalLines; -} - -void SignalPlotter::setVerticalLinesColor( const TQColor &color ) -{ - mVerticalLinesColor = color; -} - -TQColor SignalPlotter::verticalLinesColor() const -{ - return mVerticalLinesColor; -} - -void SignalPlotter::setVerticalLinesDistance( int distance ) -{ - mVerticalLinesDistance = distance; -} - -int SignalPlotter::verticalLinesDistance() const -{ - return mVerticalLinesDistance; -} - -void SignalPlotter::setVerticalLinesScroll( bool value ) -{ - mVerticalLinesScroll = value; -} - -bool SignalPlotter::verticalLinesScroll() const -{ - return mVerticalLinesScroll; -} - -void SignalPlotter::setShowHorizontalLines( bool value ) -{ - mShowHorizontalLines = value; -} - -bool SignalPlotter::showHorizontalLines() const -{ - return mShowHorizontalLines; -} - -void SignalPlotter::setHorizontalLinesColor( const TQColor &color ) -{ - mHorizontalLinesColor = color; -} - -TQColor SignalPlotter::horizontalLinesColor() const -{ - return mHorizontalLinesColor; -} - -void SignalPlotter::setHorizontalLinesCount( int count ) -{ - mHorizontalLinesCount = count; -} - -int SignalPlotter::horizontalLinesCount() const -{ - return mHorizontalLinesCount; -} - -void SignalPlotter::setShowLabels( bool value ) -{ - mShowLabels = value; -} - -bool SignalPlotter::showLabels() const -{ - return mShowLabels; -} - -void SignalPlotter::setShowTopBar( bool value ) -{ - mShowTopBar = value; -} - -bool SignalPlotter::showTopBar() const -{ - return mShowTopBar; -} - -void SignalPlotter::setFontSize( int size ) -{ - mFontSize = size; -} - -int SignalPlotter::fontSize() const -{ - return mFontSize; -} - -void SignalPlotter::setBackgroundColor( const TQColor &color ) -{ - mBackgroundColor = color; -} - -TQColor SignalPlotter::backgroundColor() const -{ - return mBackgroundColor; -} - -void SignalPlotter::resizeEvent( TQResizeEvent* ) -{ - Q_ASSERT( width() > 2 ); - - updateDataBuffers(); -} - -void SignalPlotter::updateDataBuffers() -{ - /* Since the data buffers for the beams are equal in size to the - * width of the widget minus 2 we have to enlarge or shrink the - * buffers accordingly when a resize occures. To have a nicer - * display we try to keep as much data as possible. Data that is - * lost due to shrinking the buffers cannot be recovered on - * enlarging though. */ - - /* Determine new number of samples first. - * +0.5 to ensure rounding up - * +2 for extra data points so there is - * 1) no wasted space and - * 2) no loss of precision when drawing the first data point. */ - uint newSampleNum = static_cast( ( ( width() - 2 ) / - mHorizontalScale ) + 2.5 ); - - // overlap between the old and the new buffers. - int overlap = kMin( mSamples, newSampleNum ); - - for ( uint i = 0; i < mBeamData.count(); ++i ) { - double* nd = new double[ newSampleNum ]; - - // initialize new part of the new buffer - if ( newSampleNum > (uint)overlap ) - memset( nd, 0, sizeof( double ) * ( newSampleNum - overlap ) ); - - // copy overlap from old buffer to new buffer - memcpy( nd + ( newSampleNum - overlap ), mBeamData.at( i ) + - ( mSamples - overlap ), overlap * sizeof( double ) ); - - double *p = mBeamData.take( i ); - delete [] p; - mBeamData.insert( i, nd ); - } - - mSamples = newSampleNum; -} - -void SignalPlotter::paintEvent( TQPaintEvent* ) -{ - uint w = width(); - uint h = height(); - - /* Do not do repaints when the widget is not yet setup properly. */ - if ( w <= 2 ) - return; - - TQPixmap pm( w, h ); - TQPainter p; - p.begin( &pm, this ); - - pm.fill( mBackgroundColor ); - /* Draw white line along the bottom and the right side of the - * widget to create a 3D like look. */ - p.setPen( TQColor( colorGroup().light() ) ); - if(mShowThinFrame) { - p.drawLine( 0, h - 1, w - 1, h - 1 ); - p.drawLine( w - 1, 0, w - 1, h - 1 ); - - h--; - w--; - p.setClipRect( 0, 0, w, h ); - } - double range = mMaxValue - mMinValue; - - /* If the range is too small we will force it to 1.0 since it - * looks a lot nicer. */ - if ( range < 0.000001 ) - range = 1.0; - - double minValue = mMinValue; - if ( mUseAutoRange ) { - if ( mMinValue != 0.0 ) { - double dim = pow( 10, floor( log10( fabs( mMinValue ) ) ) ) / 2; - if ( mMinValue < 0.0 ) - minValue = dim * floor( mMinValue / dim ); - else - minValue = dim * ceil( mMinValue / dim ); - range = mMaxValue - minValue; - if ( range < 0.000001 ) - range = 1.0; - } - // Massage the range so that the grid shows some nice values. - double step = range / (mHorizontalLinesCount+1); - double dim = pow( 10, floor( log10( step ) ) ) / 2; - range = dim * ceil( step / dim ) * (mHorizontalLinesCount+1); - } - double maxValue = minValue + range; - - int top = 0; - if ( mShowTopBar && h > ( mFontSize/*top bar size*/ + 2/*padding*/ +5/*smallest reasonable size for a graph*/ ) ) { - /* Draw horizontal bar with current sensor values at top of display. */ - p.setPen( mHorizontalLinesColor ); - int x0 = w / 2; - p.setFont( TQFont( p.font().family(), mFontSize ) ); - top = p.fontMetrics().height(); - h -= top; - int h0 = top - 2; // h0 is our new top. It's at least 5 pixels high - p.drawText(0, 0, x0, top - 2, Qt::AlignCenter, mTitle ); - - p.drawLine( x0 - 1, 1, x0 - 1, h0 ); - p.drawLine( 0, top - 1, w - 2, top - 1 ); - - double bias = -minValue; - double scaleFac = ( w - x0 - 2 ) / range; - TQValueList::Iterator col; - col = mBeamColor.begin(); - for ( double* d = mBeamData.first(); d; d = mBeamData.next(), ++col ) { - int start = x0 + (int)( bias * scaleFac ); - int end = x0 + (int)( ( bias += d[ mSamples - 1 ] ) * scaleFac ); - /* If the rect is wider than 2 pixels we draw only the last - * pixels with the bright color. The rest is painted with - * a 50% darker color. */ - if ( end - start > 1 ) { - p.setPen( (*col).dark( 150 ) ); - p.setBrush( (*col).dark( 150 ) ); - p.drawRect( start, 1, end - start, h0 ); - p.setPen( *col ); - p.drawLine( end, 1, end, h0 ); - } else if ( start - end > 1 ) { - p.setPen( (*col).dark( 150 ) ); - p.setBrush( (*col).dark( 150 ) ); - p.drawRect( end, 1, start - end, h0 ); - p.setPen( *col ); - p.drawLine( end, 1, end, h0 ); - } else { - p.setPen( *col ); - p.drawLine( start, 1, start, h0 ); - } - } - } - - /* Draw scope-like grid vertical lines */ - if ( mShowVerticalLines && w > 60 ) { - p.setPen( mVerticalLinesColor ); - for ( uint x = mVerticalLinesOffset; x < ( w - 2 ); x += mVerticalLinesDistance ) - p.drawLine( w - x, top, w - x, h + top - 2 ); - } - - /* In autoRange mode we determine the range and plot the values in - * one go. This is more efficiently than running through the - * buffers twice but we do react on recently discarded samples as - * well as new samples one plot too late. So the range is not - * correct if the recently discarded samples are larger or smaller - * than the current extreme values. But we can probably live with - * this. */ - if ( mUseAutoRange ) - mMinValue = mMaxValue = 0.0; - - /* Plot stacked values */ - double scaleFac = ( h - 2 ) / range; - if ( mGraphStyle == GRAPH_ORIGINAL ) { - int xPos = 0; - for ( int i = 0; i < mSamples; i++, xPos += mHorizontalScale ) { - double bias = -minValue; - TQValueList::Iterator col; - col = mBeamColor.begin(); - double sum = 0.0; - for ( double* d = mBeamData.first(); d; d = mBeamData.next(), ++col ) { - if ( mUseAutoRange ) { - sum += d[ i ]; - if ( sum < mMinValue ) - mMinValue = sum; - if ( sum > mMaxValue ) - mMaxValue = sum; - } - int start = top + h - 2 - (int)( bias * scaleFac ); - int end = top + h - 2 - (int)( ( bias + d[ i ] ) * scaleFac ); - bias += d[ i ]; - /* If the line is longer than 2 pixels we draw only the last - * 2 pixels with the bright color. The rest is painted with - * a 50% darker color. */ - if ( end - start > 2 ) { - p.fillRect( xPos, start, mHorizontalScale, end - start - 1, (*col).dark( 150 ) ); - p.fillRect( xPos, end - 1, mHorizontalScale, 2, *col ); - } else if ( start - end > 2 ) { - p.fillRect( xPos, start, mHorizontalScale, end - start + 1, (*col).dark( 150 ) ); - p.fillRect( xPos, end + 1, mHorizontalScale, 2, *col ); - } else - p.fillRect( xPos, start, mHorizontalScale, end - start, *col ); - - } - } - } else if ( mGraphStyle == GRAPH_POLYGON ) { - int *prevVals = new int[ mBeamData.count() ]; - int hack[ 4 ]; - hack[ 0 ] = hack[ 1 ] = hack[ 2 ] = hack[ 3 ] = 0; - int x1 = w - ( ( mSamples + 1 ) * mHorizontalScale ); - - for ( int i = 0; i < mSamples; i++ ) { - TQValueList::Iterator col; - col = mBeamColor.begin(); - double sum = 0.0; - int y = top + h - 2; - int oldY = top + h; - int oldPrevY = oldY; - int height = 0; - int j = 0; - int jMax = mBeamData.count() - 1; - x1 += mHorizontalScale; - int x2 = x1 + mHorizontalScale; - - for ( double* d = mBeamData.first(); d; d = mBeamData.next(), ++col, j++ ) { - if ( mUseAutoRange ) { - sum += d[ i ]; - if ( sum < mMinValue ) - mMinValue = sum; - if ( sum > mMaxValue ) - mMaxValue = sum; - } - height = (int)( ( d[ i ] - minValue ) * scaleFac ); - y -= height; - - /* If the line is longer than 2 pixels we draw only the last - * 2 pixels with the bright color. The rest is painted with - * a 50% darker color. */ - TQPen lastPen = TQPen( p.pen() ); - p.setPen( (*col).dark( 150 ) ); - p.setBrush( (*col).dark( 150 ) ); - TQPointArray pa( 4 ); - int prevY = ( i == 0 ) ? y : prevVals[ j ]; - pa.putPoints( 0, 1, x1, prevY ); - pa.putPoints( 1, 1, x2, y ); - pa.putPoints( 2, 1, x2, oldY ); - pa.putPoints( 3, 1, x1, oldPrevY ); - p.drawPolygon( pa ); - p.setPen( lastPen ); - if ( jMax == 0 ) { - // draw as normal, no deferred drawing req'd. - p.setPen( *col ); - p.drawLine( x1, prevY, x2, y ); - } else if ( j == jMax ) { - // draw previous values and current values - p.drawLine( hack[ 0 ], hack[ 1 ], hack[ 2 ], hack[ 3 ] ); - p.setPen( *col ); - p.drawLine( x1, prevY, x2, y ); - } else if ( j == 0 ) { - // save values only - hack[ 0 ] = x1; - hack[ 1 ] = prevY; - hack[ 2 ] = x2; - hack[ 3 ] = y; - p.setPen( *col ); - } else { - p.drawLine( hack[ 0 ], hack[ 1 ], hack[ 2 ], hack[ 3 ] ); - hack[ 0 ] = x1; - hack[ 1 ] = prevY; - hack[ 2 ] = x2; - hack[ 3 ] = y; - p.setPen( *col ); - } - - prevVals[ j ] = y; - oldY = y; - oldPrevY = prevY; - } - } - - delete[] prevVals; - } - - /* Draw horizontal lines and values. Lines are always drawn. - * Values are only draw when width is greater than 60 */ - if ( mShowHorizontalLines ) { - p.setPen( mHorizontalLinesColor ); - p.setFont( TQFont( p.font().family(), mFontSize ) ); - TQString val; - - /* top = 0 or font.height depending on whether there's a topbar or not - * h = graphing area.height - i.e. the actual space we have to draw inside - * - * Note we are drawing from 0,0 as the top left corner. So we have to add on top to get to the top of where we are drawing - * so top+h is the height of the widget - */ - for ( uint y = 1; y <= mHorizontalLinesCount; y++ ) { - - int y_coord = top + (y * h) / (mHorizontalLinesCount+1); //Make sure it's y*h first to avoid rounding bugs - p.drawLine( 0, y_coord, w - 2, y_coord ); - - if ( mShowLabels && h > ( mFontSize + 1 ) * ( mHorizontalLinesCount + 1 ) - && w > 60 ) { - val = TQString::number(maxValue - (y * range) / (mHorizontalLinesCount+1 ) ); - p.drawText( 6, y_coord - 1, val ); //draw the text one pixel raised above the line - } - } - - //Draw the bottom most (minimum) number as well - if ( mShowLabels && h > ( mFontSize + 1 ) * ( mHorizontalLinesCount + 1 ) - && w > 60 ) { - val = TQString::number( minValue ); - p.drawText( 6, top + h - 2, val ); - } - } - - p.end(); - bitBlt( this, 0, 0, &pm ); -} - -#include "SignalPlotter.moc" diff --git a/ksysguard/gui/SensorDisplayLib/SignalPlotter.cpp b/ksysguard/gui/SensorDisplayLib/SignalPlotter.cpp new file mode 100644 index 000000000..bcb0b821b --- /dev/null +++ b/ksysguard/gui/SensorDisplayLib/SignalPlotter.cpp @@ -0,0 +1,648 @@ +/* + KSysGuard, the KDE System Guard + + Copyright (c) 1999 - 2002 Chris Schlaeger + + This program is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + KSysGuard is currently maintained by Chris Schlaeger . + Please do not commit any changes without consulting me first. Thanks! + +*/ + +#include +#include + +#include +#include + +#include +#include + +#include + +#include "SignalPlotter.h" + +SignalPlotter::SignalPlotter( TQWidget *parent, const char *name ) + : TQWidget( parent, name ) +{ + // Auto deletion does not work for pointer to arrays. + mBeamData.setAutoDelete( false ); + + setBackgroundMode( NoBackground ); + mShowThinFrame = true; + mSamples = 0; + mMinValue = mMaxValue = 0.0; + mUseAutoRange = true; + + mGraphStyle = GRAPH_POLYGON; + + // Anything smaller than this does not make sense. + setMinimumSize( 16, 16 ); + setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, + TQSizePolicy::Expanding, false ) ); + + mShowVerticalLines = true; + mVerticalLinesColor = KSGRD::Style->firstForegroundColor(); + mVerticalLinesDistance = 30; + mVerticalLinesScroll = true; + mVerticalLinesOffset = 0; + mHorizontalScale = 1; + + mShowHorizontalLines = true; + mHorizontalLinesColor = KSGRD::Style->secondForegroundColor(); + mHorizontalLinesCount = 5; + + mShowLabels = true; + mShowTopBar = false; + mFontSize = KSGRD::Style->fontSize(); + + mBackgroundColor = KSGRD::Style->backgroundColor(); +} + +SignalPlotter::~SignalPlotter() +{ + for ( double* p = mBeamData.first(); p; p = mBeamData.next() ) + delete [] p; +} + +bool SignalPlotter::addBeam( const TQColor &color ) +{ + double* d = new double[ mSamples ]; + memset( d, 0, sizeof(double) * mSamples ); + mBeamData.append( d ); + mBeamColor.append( color ); + + return true; +} + +void SignalPlotter::addSample( const TQValueList& sampleBuf ) +{ + if ( mBeamData.count() != sampleBuf.count() ) + return; + + double* d; + if ( mUseAutoRange ) { + double sum = 0; + for ( d = mBeamData.first(); d; d = mBeamData.next() ) { + sum += d[ 0 ]; + if ( sum < mMinValue ) + mMinValue = sum; + if ( sum > mMaxValue ) + mMaxValue = sum; + } + } + + /* If the vertical lines are scrolling, increment the offset + * so they move with the data. The vOffset / hScale confusion + * is because v refers to Vertical Lines, and h to the horizontal + * distance between the vertical lines. */ + if ( mVerticalLinesScroll ) { + mVerticalLinesOffset = ( mVerticalLinesOffset + mHorizontalScale) + % mVerticalLinesDistance; + } + + // Shift data buffers one sample down and insert new samples. + TQValueList::ConstIterator s; + for ( d = mBeamData.first(), s = sampleBuf.begin(); d; d = mBeamData.next(), ++s ) { + memmove( d, d + 1, ( mSamples - 1 ) * sizeof( double ) ); + d[ mSamples - 1 ] = *s; + } + + update(); +} + +void SignalPlotter::reorderBeams( const TQValueList& newOrder ) +{ + if(newOrder.count() != mBeamData.count()) { + kdDebug() << "Serious problem in move sample" << endl; + return; + } + TQPtrList newBeamData; + TQValueList newBeamColor; + + for(uint i = 0; i < newOrder.count(); i++) { + int newIndex = newOrder[i]; + newBeamData.append(mBeamData.at(newIndex)); + newBeamColor.append(*mBeamColor.at(newIndex)); + } + mBeamData = newBeamData; + mBeamColor = newBeamColor; + +} + +void SignalPlotter::changeRange( int beam, double min, double max ) +{ + // Only the first beam affects range calculation. + if ( beam > 1 ) + return; + + mMinValue = min; + mMaxValue = max; +} + +TQValueList &SignalPlotter::beamColors() +{ + return mBeamColor; +} + +void SignalPlotter::removeBeam( uint pos ) +{ + mBeamColor.remove( mBeamColor.at( pos ) ); + double *p = mBeamData.take( pos ); + delete [] p; +} + +void SignalPlotter::setTitle( const TQString &title ) +{ + mTitle = title; +} + +TQString SignalPlotter::title() const +{ + return mTitle; +} + +void SignalPlotter::setUseAutoRange( bool value ) +{ + mUseAutoRange = value; +} + +bool SignalPlotter::useAutoRange() const +{ + return mUseAutoRange; +} + +void SignalPlotter::setMinValue( double min ) +{ + mMinValue = min; +} + +double SignalPlotter::minValue() const +{ + return ( mUseAutoRange ? 0 : mMinValue ); +} + +void SignalPlotter::setMaxValue( double max ) +{ + mMaxValue = max; +} + +double SignalPlotter::maxValue() const +{ + return ( mUseAutoRange ? 0 : mMaxValue ); +} + +void SignalPlotter::setGraphStyle( uint style ) +{ + mGraphStyle = style; +} + +uint SignalPlotter::graphStyle() const +{ + return mGraphStyle; +} + +void SignalPlotter::setHorizontalScale( uint scale ) +{ + if (scale == mHorizontalScale) + return; + + mHorizontalScale = scale; + if (isVisible()) + updateDataBuffers(); +} + +int SignalPlotter::horizontalScale() const +{ + return mHorizontalScale; +} + +void SignalPlotter::setShowVerticalLines( bool value ) +{ + mShowVerticalLines = value; +} + +bool SignalPlotter::showVerticalLines() const +{ + return mShowVerticalLines; +} + +void SignalPlotter::setVerticalLinesColor( const TQColor &color ) +{ + mVerticalLinesColor = color; +} + +TQColor SignalPlotter::verticalLinesColor() const +{ + return mVerticalLinesColor; +} + +void SignalPlotter::setVerticalLinesDistance( int distance ) +{ + mVerticalLinesDistance = distance; +} + +int SignalPlotter::verticalLinesDistance() const +{ + return mVerticalLinesDistance; +} + +void SignalPlotter::setVerticalLinesScroll( bool value ) +{ + mVerticalLinesScroll = value; +} + +bool SignalPlotter::verticalLinesScroll() const +{ + return mVerticalLinesScroll; +} + +void SignalPlotter::setShowHorizontalLines( bool value ) +{ + mShowHorizontalLines = value; +} + +bool SignalPlotter::showHorizontalLines() const +{ + return mShowHorizontalLines; +} + +void SignalPlotter::setHorizontalLinesColor( const TQColor &color ) +{ + mHorizontalLinesColor = color; +} + +TQColor SignalPlotter::horizontalLinesColor() const +{ + return mHorizontalLinesColor; +} + +void SignalPlotter::setHorizontalLinesCount( int count ) +{ + mHorizontalLinesCount = count; +} + +int SignalPlotter::horizontalLinesCount() const +{ + return mHorizontalLinesCount; +} + +void SignalPlotter::setShowLabels( bool value ) +{ + mShowLabels = value; +} + +bool SignalPlotter::showLabels() const +{ + return mShowLabels; +} + +void SignalPlotter::setShowTopBar( bool value ) +{ + mShowTopBar = value; +} + +bool SignalPlotter::showTopBar() const +{ + return mShowTopBar; +} + +void SignalPlotter::setFontSize( int size ) +{ + mFontSize = size; +} + +int SignalPlotter::fontSize() const +{ + return mFontSize; +} + +void SignalPlotter::setBackgroundColor( const TQColor &color ) +{ + mBackgroundColor = color; +} + +TQColor SignalPlotter::backgroundColor() const +{ + return mBackgroundColor; +} + +void SignalPlotter::resizeEvent( TQResizeEvent* ) +{ + Q_ASSERT( width() > 2 ); + + updateDataBuffers(); +} + +void SignalPlotter::updateDataBuffers() +{ + /* Since the data buffers for the beams are equal in size to the + * width of the widget minus 2 we have to enlarge or shrink the + * buffers accordingly when a resize occures. To have a nicer + * display we try to keep as much data as possible. Data that is + * lost due to shrinking the buffers cannot be recovered on + * enlarging though. */ + + /* Determine new number of samples first. + * +0.5 to ensure rounding up + * +2 for extra data points so there is + * 1) no wasted space and + * 2) no loss of precision when drawing the first data point. */ + uint newSampleNum = static_cast( ( ( width() - 2 ) / + mHorizontalScale ) + 2.5 ); + + // overlap between the old and the new buffers. + int overlap = kMin( mSamples, newSampleNum ); + + for ( uint i = 0; i < mBeamData.count(); ++i ) { + double* nd = new double[ newSampleNum ]; + + // initialize new part of the new buffer + if ( newSampleNum > (uint)overlap ) + memset( nd, 0, sizeof( double ) * ( newSampleNum - overlap ) ); + + // copy overlap from old buffer to new buffer + memcpy( nd + ( newSampleNum - overlap ), mBeamData.at( i ) + + ( mSamples - overlap ), overlap * sizeof( double ) ); + + double *p = mBeamData.take( i ); + delete [] p; + mBeamData.insert( i, nd ); + } + + mSamples = newSampleNum; +} + +void SignalPlotter::paintEvent( TQPaintEvent* ) +{ + uint w = width(); + uint h = height(); + + /* Do not do repaints when the widget is not yet setup properly. */ + if ( w <= 2 ) + return; + + TQPixmap pm( w, h ); + TQPainter p; + p.begin( &pm, this ); + + pm.fill( mBackgroundColor ); + /* Draw white line along the bottom and the right side of the + * widget to create a 3D like look. */ + p.setPen( TQColor( colorGroup().light() ) ); + if(mShowThinFrame) { + p.drawLine( 0, h - 1, w - 1, h - 1 ); + p.drawLine( w - 1, 0, w - 1, h - 1 ); + + h--; + w--; + p.setClipRect( 0, 0, w, h ); + } + double range = mMaxValue - mMinValue; + + /* If the range is too small we will force it to 1.0 since it + * looks a lot nicer. */ + if ( range < 0.000001 ) + range = 1.0; + + double minValue = mMinValue; + if ( mUseAutoRange ) { + if ( mMinValue != 0.0 ) { + double dim = pow( 10, floor( log10( fabs( mMinValue ) ) ) ) / 2; + if ( mMinValue < 0.0 ) + minValue = dim * floor( mMinValue / dim ); + else + minValue = dim * ceil( mMinValue / dim ); + range = mMaxValue - minValue; + if ( range < 0.000001 ) + range = 1.0; + } + // Massage the range so that the grid shows some nice values. + double step = range / (mHorizontalLinesCount+1); + double dim = pow( 10, floor( log10( step ) ) ) / 2; + range = dim * ceil( step / dim ) * (mHorizontalLinesCount+1); + } + double maxValue = minValue + range; + + int top = 0; + if ( mShowTopBar && h > ( mFontSize/*top bar size*/ + 2/*padding*/ +5/*smallest reasonable size for a graph*/ ) ) { + /* Draw horizontal bar with current sensor values at top of display. */ + p.setPen( mHorizontalLinesColor ); + int x0 = w / 2; + p.setFont( TQFont( p.font().family(), mFontSize ) ); + top = p.fontMetrics().height(); + h -= top; + int h0 = top - 2; // h0 is our new top. It's at least 5 pixels high + p.drawText(0, 0, x0, top - 2, Qt::AlignCenter, mTitle ); + + p.drawLine( x0 - 1, 1, x0 - 1, h0 ); + p.drawLine( 0, top - 1, w - 2, top - 1 ); + + double bias = -minValue; + double scaleFac = ( w - x0 - 2 ) / range; + TQValueList::Iterator col; + col = mBeamColor.begin(); + for ( double* d = mBeamData.first(); d; d = mBeamData.next(), ++col ) { + int start = x0 + (int)( bias * scaleFac ); + int end = x0 + (int)( ( bias += d[ mSamples - 1 ] ) * scaleFac ); + /* If the rect is wider than 2 pixels we draw only the last + * pixels with the bright color. The rest is painted with + * a 50% darker color. */ + if ( end - start > 1 ) { + p.setPen( (*col).dark( 150 ) ); + p.setBrush( (*col).dark( 150 ) ); + p.drawRect( start, 1, end - start, h0 ); + p.setPen( *col ); + p.drawLine( end, 1, end, h0 ); + } else if ( start - end > 1 ) { + p.setPen( (*col).dark( 150 ) ); + p.setBrush( (*col).dark( 150 ) ); + p.drawRect( end, 1, start - end, h0 ); + p.setPen( *col ); + p.drawLine( end, 1, end, h0 ); + } else { + p.setPen( *col ); + p.drawLine( start, 1, start, h0 ); + } + } + } + + /* Draw scope-like grid vertical lines */ + if ( mShowVerticalLines && w > 60 ) { + p.setPen( mVerticalLinesColor ); + for ( uint x = mVerticalLinesOffset; x < ( w - 2 ); x += mVerticalLinesDistance ) + p.drawLine( w - x, top, w - x, h + top - 2 ); + } + + /* In autoRange mode we determine the range and plot the values in + * one go. This is more efficiently than running through the + * buffers twice but we do react on recently discarded samples as + * well as new samples one plot too late. So the range is not + * correct if the recently discarded samples are larger or smaller + * than the current extreme values. But we can probably live with + * this. */ + if ( mUseAutoRange ) + mMinValue = mMaxValue = 0.0; + + /* Plot stacked values */ + double scaleFac = ( h - 2 ) / range; + if ( mGraphStyle == GRAPH_ORIGINAL ) { + int xPos = 0; + for ( int i = 0; i < mSamples; i++, xPos += mHorizontalScale ) { + double bias = -minValue; + TQValueList::Iterator col; + col = mBeamColor.begin(); + double sum = 0.0; + for ( double* d = mBeamData.first(); d; d = mBeamData.next(), ++col ) { + if ( mUseAutoRange ) { + sum += d[ i ]; + if ( sum < mMinValue ) + mMinValue = sum; + if ( sum > mMaxValue ) + mMaxValue = sum; + } + int start = top + h - 2 - (int)( bias * scaleFac ); + int end = top + h - 2 - (int)( ( bias + d[ i ] ) * scaleFac ); + bias += d[ i ]; + /* If the line is longer than 2 pixels we draw only the last + * 2 pixels with the bright color. The rest is painted with + * a 50% darker color. */ + if ( end - start > 2 ) { + p.fillRect( xPos, start, mHorizontalScale, end - start - 1, (*col).dark( 150 ) ); + p.fillRect( xPos, end - 1, mHorizontalScale, 2, *col ); + } else if ( start - end > 2 ) { + p.fillRect( xPos, start, mHorizontalScale, end - start + 1, (*col).dark( 150 ) ); + p.fillRect( xPos, end + 1, mHorizontalScale, 2, *col ); + } else + p.fillRect( xPos, start, mHorizontalScale, end - start, *col ); + + } + } + } else if ( mGraphStyle == GRAPH_POLYGON ) { + int *prevVals = new int[ mBeamData.count() ]; + int hack[ 4 ]; + hack[ 0 ] = hack[ 1 ] = hack[ 2 ] = hack[ 3 ] = 0; + int x1 = w - ( ( mSamples + 1 ) * mHorizontalScale ); + + for ( int i = 0; i < mSamples; i++ ) { + TQValueList::Iterator col; + col = mBeamColor.begin(); + double sum = 0.0; + int y = top + h - 2; + int oldY = top + h; + int oldPrevY = oldY; + int height = 0; + int j = 0; + int jMax = mBeamData.count() - 1; + x1 += mHorizontalScale; + int x2 = x1 + mHorizontalScale; + + for ( double* d = mBeamData.first(); d; d = mBeamData.next(), ++col, j++ ) { + if ( mUseAutoRange ) { + sum += d[ i ]; + if ( sum < mMinValue ) + mMinValue = sum; + if ( sum > mMaxValue ) + mMaxValue = sum; + } + height = (int)( ( d[ i ] - minValue ) * scaleFac ); + y -= height; + + /* If the line is longer than 2 pixels we draw only the last + * 2 pixels with the bright color. The rest is painted with + * a 50% darker color. */ + TQPen lastPen = TQPen( p.pen() ); + p.setPen( (*col).dark( 150 ) ); + p.setBrush( (*col).dark( 150 ) ); + TQPointArray pa( 4 ); + int prevY = ( i == 0 ) ? y : prevVals[ j ]; + pa.putPoints( 0, 1, x1, prevY ); + pa.putPoints( 1, 1, x2, y ); + pa.putPoints( 2, 1, x2, oldY ); + pa.putPoints( 3, 1, x1, oldPrevY ); + p.drawPolygon( pa ); + p.setPen( lastPen ); + if ( jMax == 0 ) { + // draw as normal, no deferred drawing req'd. + p.setPen( *col ); + p.drawLine( x1, prevY, x2, y ); + } else if ( j == jMax ) { + // draw previous values and current values + p.drawLine( hack[ 0 ], hack[ 1 ], hack[ 2 ], hack[ 3 ] ); + p.setPen( *col ); + p.drawLine( x1, prevY, x2, y ); + } else if ( j == 0 ) { + // save values only + hack[ 0 ] = x1; + hack[ 1 ] = prevY; + hack[ 2 ] = x2; + hack[ 3 ] = y; + p.setPen( *col ); + } else { + p.drawLine( hack[ 0 ], hack[ 1 ], hack[ 2 ], hack[ 3 ] ); + hack[ 0 ] = x1; + hack[ 1 ] = prevY; + hack[ 2 ] = x2; + hack[ 3 ] = y; + p.setPen( *col ); + } + + prevVals[ j ] = y; + oldY = y; + oldPrevY = prevY; + } + } + + delete[] prevVals; + } + + /* Draw horizontal lines and values. Lines are always drawn. + * Values are only draw when width is greater than 60 */ + if ( mShowHorizontalLines ) { + p.setPen( mHorizontalLinesColor ); + p.setFont( TQFont( p.font().family(), mFontSize ) ); + TQString val; + + /* top = 0 or font.height depending on whether there's a topbar or not + * h = graphing area.height - i.e. the actual space we have to draw inside + * + * Note we are drawing from 0,0 as the top left corner. So we have to add on top to get to the top of where we are drawing + * so top+h is the height of the widget + */ + for ( uint y = 1; y <= mHorizontalLinesCount; y++ ) { + + int y_coord = top + (y * h) / (mHorizontalLinesCount+1); //Make sure it's y*h first to avoid rounding bugs + p.drawLine( 0, y_coord, w - 2, y_coord ); + + if ( mShowLabels && h > ( mFontSize + 1 ) * ( mHorizontalLinesCount + 1 ) + && w > 60 ) { + val = TQString::number(maxValue - (y * range) / (mHorizontalLinesCount+1 ) ); + p.drawText( 6, y_coord - 1, val ); //draw the text one pixel raised above the line + } + } + + //Draw the bottom most (minimum) number as well + if ( mShowLabels && h > ( mFontSize + 1 ) * ( mHorizontalLinesCount + 1 ) + && w > 60 ) { + val = TQString::number( minValue ); + p.drawText( 6, top + h - 2, val ); + } + } + + p.end(); + bitBlt( this, 0, 0, &pm ); +} + +#include "SignalPlotter.moc" -- cgit v1.2.1