2 KSysGuard, the KDE System Guard
4 Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include <QtCore/QAbstractTableModel>
23 #include <QtCore/QDate>
24 #include <QtCore/QFile>
25 #include <QtCore/QTextStream>
26 #include <QtGui/QContextMenuEvent>
27 #include <QtGui/QHeaderView>
28 #include <QtGui/QMenu>
29 #include <QtGui/QTreeView>
30 #include <QtGui/QHBoxLayout>
31 #include <QtXml/QDomNodeList>
32 #include <QtXml/QDomDocument>
33 #include <QtXml/QDomElement>
35 #include <kapplication.h>
36 #include <kiconloader.h>
38 #include <knotification.h>
39 #include <ksgrd/SensorManager.h>
41 #include "StyleEngine.h"
43 #include "SensorLoggerDlg.h"
44 #include "SensorLoggerSettings.h"
45 #include "SensorLogger.h"
49 LogSensorView::LogSensorView( QWidget
*parent
)
54 void LogSensorView::contextMenuEvent( QContextMenuEvent
*event
)
56 const QModelIndex index
= indexAt( event
->pos() );
58 emit
contextMenuRequest( index
, viewport()->mapToGlobal( event
->pos() ) );
61 class LogSensorModel
: public QAbstractTableModel
64 LogSensorModel( QObject
*parent
= 0 )
65 : QAbstractTableModel( parent
)
69 virtual int columnCount( const QModelIndex
&parent
= QModelIndex() ) const
76 virtual int rowCount( const QModelIndex
&parent
= QModelIndex() ) const
80 return mSensors
.count();
83 virtual QVariant
data( const QModelIndex
&index
, int role
= Qt::DisplayRole
) const
85 if ( !index
.isValid() )
88 if ( index
.row() >= mSensors
.count() || index
.row() < 0 )
91 LogSensor
*sensor
= mSensors
[ index
.row() ];
93 if ( role
== Qt::DisplayRole
) {
94 switch ( index
.column() ) {
96 return sensor
->timerInterval();
99 return sensor
->sensorName();
102 return sensor
->hostName();
105 return sensor
->fileName();
108 } else if ( role
== Qt::DecorationRole
) {
109 static QPixmap runningPixmap
= KIconLoader::global()->loadIcon( "running", KIconLoader::Small
, KIconLoader::SizeSmall
);
110 static QPixmap waitingPixmap
= KIconLoader::global()->loadIcon( "waiting", KIconLoader::Small
, KIconLoader::SizeSmall
);
112 if ( index
.column() == 0 ) {
113 if ( sensor
->isLogging() )
114 return runningPixmap
;
116 return waitingPixmap
;
118 } else if ( role
== Qt::ForegroundRole
) {
119 if ( sensor
->limitReached() )
122 return mForegroundColor
;
123 } else if ( role
== Qt::BackgroundRole
) {
124 return mBackgroundColor
;
130 virtual QVariant
headerData( int section
, Qt::Orientation orientation
, int role
= Qt::DisplayRole
) const
132 if ( orientation
== Qt::Vertical
)
135 if ( role
== Qt::DisplayRole
) {
138 return i18n("Logging");
141 return i18n("Timer Interval");
144 return i18n("Sensor Name");
147 return i18n("Host Name");
150 return i18n("Log File");
160 void addSensor( LogSensor
*sensor
)
162 mSensors
.append( sensor
);
164 connect( sensor
, SIGNAL( changed() ), this, SIGNAL( layoutChanged() ) );
166 emit
layoutChanged();
169 void removeSensor( LogSensor
*sensor
)
171 delete mSensors
.takeAt( mSensors
.indexOf( sensor
) );
173 emit
layoutChanged();
176 LogSensor
* sensor( const QModelIndex
&index
) const
178 if ( !index
.isValid() || index
.row() >= mSensors
.count() || index
.row() < 0 )
181 return mSensors
[ index
.row() ];
186 qDeleteAll( mSensors
);
190 const QList
<LogSensor
*> sensors() const
195 void setForegroundColor( const QColor
&color
) { mForegroundColor
= color
; }
196 QColor
foregroundColor() const { return mForegroundColor
; }
198 void setBackgroundColor( const QColor
&color
) { mBackgroundColor
= color
; }
199 QColor
backgroundColor() const { return mBackgroundColor
; }
201 void setAlarmColor( const QColor
&color
) { mAlarmColor
= color
; }
202 QColor
alarmColor() const { return mAlarmColor
; }
206 QColor mForegroundColor
;
207 QColor mBackgroundColor
;
210 QList
<LogSensor
*> mSensors
;
213 LogSensor::LogSensor( QObject
*parent
)
216 mLowerLimitActive( false ),
217 mUpperLimitActive( 0 ),
220 mLimitReached( false )
224 LogSensor::~LogSensor()
228 void LogSensor::setHostName( const QString
& name
)
233 QString
LogSensor::hostName() const
238 void LogSensor::setSensorName( const QString
& name
)
243 QString
LogSensor::sensorName() const
248 void LogSensor::setFileName( const QString
& name
)
253 QString
LogSensor::fileName() const
258 void LogSensor::setUpperLimitActive( bool value
)
260 mUpperLimitActive
= value
;
263 bool LogSensor::upperLimitActive() const
265 return mUpperLimitActive
;
268 void LogSensor::setLowerLimitActive( bool value
)
270 mLowerLimitActive
= value
;
273 bool LogSensor::lowerLimitActive() const
275 return mLowerLimitActive
;
278 void LogSensor::setUpperLimit( double value
)
283 double LogSensor::upperLimit() const
288 void LogSensor::setLowerLimit( double value
)
293 double LogSensor::lowerLimit() const
298 void LogSensor::setTimerInterval( int interval
)
300 mTimerInterval
= interval
;
302 if ( mTimerID
!= NONE
) {
308 int LogSensor::timerInterval() const
310 return mTimerInterval
;
313 bool LogSensor::isLogging() const
315 return mTimerID
!= NONE
;
318 bool LogSensor::limitReached() const
320 return mLimitReached
;
323 void LogSensor::timerOff()
326 killTimer( mTimerID
);
330 void LogSensor::timerOn()
332 mTimerID
= startTimer( mTimerInterval
* 1000 );
335 void LogSensor::startLogging()
340 void LogSensor::stopLogging()
345 void LogSensor::timerTick( )
347 KSGRD::SensorMgr
->sendRequest( mHostName
, mSensorName
, (KSGRD::SensorClient
*) this, 42 );
350 void LogSensor::answerReceived( int id
, const QList
<QByteArray
>& answer
) //virtual
352 QFile
mLogFile( mFileName
);
354 if ( !mLogFile
.open( QIODevice::ReadWrite
| QIODevice::Append
) ) {
361 QTextStream
stream( &mLogFile
);
363 if ( !answer
.isEmpty() )
364 value
= answer
[ 0 ].toDouble();
366 if ( mLowerLimitActive
&& value
< mLowerLimit
) {
368 mLimitReached
= true;
371 KNotification::event( "sensor_alarm", QString( "sensor '%1' at '%2' reached lower limit" )
372 .arg( mSensorName
).arg( mHostName
), QPixmap(), 0 );
375 } else if ( mUpperLimitActive
&& value
> mUpperLimit
) {
377 mLimitReached
= true;
380 KNotification::event( "sensor_alarm", QString( "sensor '%1' at '%2' reached upper limit" )
381 .arg( mSensorName
).arg( mHostName
), QPixmap(), 0 );
385 mLimitReached
= false;
388 const QDate date
= QDateTime::currentDateTime().date();
389 const QTime time
= QDateTime::currentDateTime().time();
391 stream
<< QString( "%1 %2 %3 %4 %5: %6\n" ).arg( date
.shortMonthName( date
.month() ) )
392 .arg( date
.day() ).arg( time
.toString() )
393 .arg( mHostName
).arg( mSensorName
).arg( value
);
402 SensorLogger::SensorLogger( QWidget
*parent
, const QString
& title
, SharedSettings
*workSheetSettings
)
403 : KSGRD::SensorDisplay( parent
, title
, workSheetSettings
)
405 mModel
= new LogSensorModel( this );
406 mModel
->setForegroundColor( KSGRD::Style
->firstForegroundColor() );
407 mModel
->setBackgroundColor( KSGRD::Style
->backgroundColor() );
408 mModel
->setAlarmColor( KSGRD::Style
->alarmColor() );
410 QLayout
*layout
= new QHBoxLayout(this);
411 mView
= new LogSensorView( this );
412 layout
->addWidget(mView
);
415 mView
->setContextMenuPolicy( Qt::CustomContextMenu
);
416 connect(mView
, SIGNAL(customContextMenuRequested(const QPoint
&)), SLOT(showContextMenu(const QPoint
&)));
418 mView
->header()->setStretchLastSection( true );
419 mView
->setRootIsDecorated( false );
420 mView
->setItemsExpandable( false );
421 mView
->setModel( mModel
);
422 setPlotterWidget( mView
);
424 connect( mView
, SIGNAL( contextMenuRequest( const QModelIndex
&, const QPoint
& ) ),
425 this, SLOT( contextMenuRequest( const QModelIndex
&, const QPoint
& ) ) );
427 QPalette palette
= mView
->palette();
428 palette
.setColor( QPalette::Base
, KSGRD::Style
->backgroundColor() );
429 mView
->setPalette( palette
);
431 setTitle( i18n( "Sensor Logger" ) );
432 setMinimumSize( 50, 25 );
435 SensorLogger::~SensorLogger(void)
439 bool SensorLogger::addSensor( const QString
& hostName
, const QString
& sensorName
, const QString
& sensorType
, const QString
& )
441 if ( sensorType
!= "integer" && sensorType
!= "float" )
444 SensorLoggerDlg
dlg( this );
447 if ( !dlg
.fileName().isEmpty() ) {
448 LogSensor
*sensor
= new LogSensor( mModel
);
450 sensor
->setHostName( hostName
);
451 sensor
->setSensorName( sensorName
);
452 sensor
->setFileName( dlg
.fileName() );
453 sensor
->setTimerInterval( dlg
.timerInterval() );
454 sensor
->setLowerLimitActive( dlg
.lowerLimitActive() );
455 sensor
->setUpperLimitActive( dlg
.upperLimitActive() );
456 sensor
->setLowerLimit( dlg
.lowerLimit() );
457 sensor
->setUpperLimit( dlg
.upperLimit() );
459 mModel
->addSensor( sensor
);
466 bool SensorLogger::editSensor( LogSensor
* sensor
)
468 SensorLoggerDlg
dlg( this );
470 dlg
.setFileName( sensor
->fileName() );
471 dlg
.setTimerInterval( sensor
->timerInterval() );
472 dlg
.setLowerLimitActive( sensor
->lowerLimitActive() );
473 dlg
.setLowerLimit( sensor
->lowerLimit() );
474 dlg
.setUpperLimitActive( sensor
->upperLimitActive() );
475 dlg
.setUpperLimit( sensor
->upperLimit() );
478 if ( !dlg
.fileName().isEmpty() ) {
479 sensor
->setFileName( dlg
.fileName() );
480 sensor
->setTimerInterval( dlg
.timerInterval() );
481 sensor
->setLowerLimitActive( dlg
.lowerLimitActive() );
482 sensor
->setUpperLimitActive( dlg
.upperLimitActive() );
483 sensor
->setLowerLimit( dlg
.lowerLimit() );
484 sensor
->setUpperLimit( dlg
.upperLimit() );
491 void SensorLogger::configureSettings()
493 SensorLoggerSettings
dlg( this );
495 dlg
.setTitle( title() );
496 dlg
.setForegroundColor( mModel
->foregroundColor() );
497 dlg
.setBackgroundColor( mModel
->backgroundColor() );
498 dlg
.setAlarmColor( mModel
->alarmColor() );
501 setTitle( dlg
.title() );
503 mModel
->setForegroundColor( dlg
.foregroundColor() );
504 mModel
->setBackgroundColor( dlg
.backgroundColor() );
505 mModel
->setAlarmColor( dlg
.alarmColor() );
507 QPalette palette
= mView
->palette();
508 palette
.setColor( QPalette::Base
, dlg
.backgroundColor() );
509 mView
->setPalette( palette
);
513 void SensorLogger::applyStyle()
515 mModel
->setForegroundColor( KSGRD::Style
->firstForegroundColor() );
516 mModel
->setBackgroundColor( KSGRD::Style
->backgroundColor() );
517 mModel
->setAlarmColor( KSGRD::Style
->alarmColor() );
519 QPalette palette
= mView
->palette();
520 palette
.setColor( QPalette::Base
, KSGRD::Style
->backgroundColor() );
521 mView
->setPalette( palette
);
524 bool SensorLogger::restoreSettings( QDomElement
& element
)
526 mModel
->setForegroundColor( restoreColor( element
, "textColor", Qt::green
) );
527 mModel
->setBackgroundColor( restoreColor( element
, "backgroundColor", Qt::black
) );
528 mModel
->setAlarmColor( restoreColor( element
, "alarmColor", Qt::red
) );
532 QDomNodeList dnList
= element
.elementsByTagName( "logsensors" );
533 for ( int i
= 0; i
< dnList
.count(); i
++ ) {
534 QDomElement element
= dnList
.item( i
).toElement();
535 LogSensor
* sensor
= new LogSensor( mModel
);
537 sensor
->setHostName( element
.attribute("hostName") );
538 sensor
->setSensorName( element
.attribute("sensorName") );
539 sensor
->setFileName( element
.attribute("fileName") );
540 sensor
->setTimerInterval( element
.attribute("timerInterval").toInt() );
541 sensor
->setLowerLimitActive( element
.attribute("lowerLimitActive").toInt() );
542 sensor
->setLowerLimit( element
.attribute("lowerLimit").toDouble() );
543 sensor
->setUpperLimitActive( element
.attribute("upperLimitActive").toInt() );
544 sensor
->setUpperLimit( element
.attribute("upperLimit").toDouble() );
546 mModel
->addSensor( sensor
);
549 SensorDisplay::restoreSettings( element
);
551 QPalette palette
= mView
->palette();
552 palette
.setColor( QPalette::Base
, mModel
->backgroundColor() );
553 mView
->setPalette( palette
);
558 bool SensorLogger::saveSettings( QDomDocument
& doc
, QDomElement
& element
)
560 saveColor( element
, "textColor", mModel
->foregroundColor() );
561 saveColor( element
, "backgroundColor", mModel
->backgroundColor() );
562 saveColor( element
, "alarmColor", mModel
->alarmColor() );
564 const QList
<LogSensor
*> sensors
= mModel
->sensors();
565 for ( int i
= 0; i
< sensors
.count(); ++i
) {
566 LogSensor
*sensor
= sensors
[ i
];
567 QDomElement log
= doc
.createElement( "logsensors" );
568 log
.setAttribute("sensorName", sensor
->sensorName());
569 log
.setAttribute("hostName", sensor
->hostName());
570 log
.setAttribute("fileName", sensor
->fileName());
571 log
.setAttribute("timerInterval", sensor
->timerInterval());
572 log
.setAttribute("lowerLimitActive", QString("%1").arg(sensor
->lowerLimitActive()));
573 log
.setAttribute("lowerLimit", QString("%1").arg(sensor
->lowerLimit()));
574 log
.setAttribute("upperLimitActive", QString("%1").arg(sensor
->upperLimitActive()));
575 log
.setAttribute("upperLimit", QString("%1").arg(sensor
->upperLimit()));
577 element
.appendChild( log
);
580 SensorDisplay::saveSettings( doc
, element
);
585 void SensorLogger::answerReceived( int, const QList
<QByteArray
>& ) //virtual
587 // we do not use this, since all answers are received by the LogSensors
590 void SensorLogger::contextMenuRequest( const QModelIndex
&index
, const QPoint
&point
)
592 LogSensor
*sensor
= mModel
->sensor( index
);
597 if (hasSettingsDialog()) {
598 action
= pm
.addAction(i18n("&Properties"));
599 action
->setData( 1 );
601 if(!mSharedSettings
->locked
) {
603 action
= pm
.addAction(i18n("&Remove Display"));
604 action
->setData( 2 );
608 action
= pm
.addAction(i18n("&Remove Sensor"));
609 action
->setData( 3 );
611 action
->setEnabled( false );
613 action
= pm
.addAction(i18n("&Edit Sensor..."));
614 action
->setData( 4 );
616 action
->setEnabled( false );
620 if ( sensor
->isLogging() ) {
621 action
= pm
.addAction(i18n("St&op Logging"));
622 action
->setData( 6 );
624 action
= pm
.addAction(i18n("S&tart Logging"));
625 action
->setData( 5 );
629 action
= pm
.exec( point
);
633 switch (action
->data().toInt())
639 KSGRD::SensorDisplay::DeleteEvent
*ev
= new KSGRD::SensorDisplay::DeleteEvent( this );
640 kapp
->postEvent(parent(), ev
);
645 mModel
->removeSensor( sensor
);
649 editSensor( sensor
);
653 sensor
->startLogging();
657 sensor
->stopLogging();
662 #include "SensorLogger.moc"