/* KSysGuard, the KDE System Guard Copyright (c) 1999, 2000, 2001 Chris Schlaeger <cs@kde.org> 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 <cs@kde.org>. Please do not commit any changes without consulting me first. Thanks! */ #include <tqcheckbox.h> #include <tqdom.h> #include <tqlineedit.h> #include <tqlistview.h> #include <tqpushbutton.h> #include <tqspinbox.h> #include <tqtooltip.h> #include <kdebug.h> #include <tdelocale.h> #include <knumvalidator.h> #include <ksgrd/SensorManager.h> #include <ksgrd/StyleEngine.h> #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<double> &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"