2 KSysGuard, the KDE System Guard
4 Copyright (c) 1999, 2000, 2001 Chris Schlaeger <cs@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 version 2 or at your option version 3 as published by
9 the Free Software Foundation.
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.
23 #include <QtXml/qdom.h>
25 #include <QPushButton>
27 #include <QHBoxLayout>
31 #include <knumvalidator.h>
32 #include <ksgrd/SensorManager.h>
33 #include "StyleEngine.h"
36 #include "DancingBarsSettings.h"
38 #include "DancingBars.h"
40 DancingBars::DancingBars( QWidget
*parent
, const QString
&title
, SharedSettings
*workSheetSettings
)
41 : KSGRD::SensorDisplay( parent
, title
, workSheetSettings
)
44 mFlags
= QBitArray( 100 );
47 QLayout
*layout
= new QHBoxLayout(this);
48 mPlotter
= new BarGraph( this );
49 layout
->addWidget(mPlotter
);
51 setMinimumSize( sizeHint() );
53 /* All RMB clicks to the mPlotter widget will be handled by
54 * SensorDisplay::eventFilter. */
55 mPlotter
->installEventFilter( this );
57 setPlotterWidget( mPlotter
);
61 DancingBars::~DancingBars()
65 void DancingBars::configureSettings()
67 DancingBarsSettings
dlg( this );
69 dlg
.setTitle( title() );
70 dlg
.setMinValue( mPlotter
->getMin() );
71 dlg
.setMaxValue( mPlotter
->getMax() );
75 mPlotter
->getLimits( l
, la
, u
, ua
);
77 dlg
.setUseUpperLimit( ua
);
78 dlg
.setUpperLimit( u
);
80 dlg
.setUseLowerLimit( la
);
81 dlg
.setLowerLimit( l
);
83 dlg
.setForegroundColor( mPlotter
->normalColor
);
84 dlg
.setAlarmColor( mPlotter
->alarmColor
);
85 dlg
.setBackgroundColor( mPlotter
->mBackgroundColor
);
86 dlg
.setFontSize( mPlotter
->fontSize
);
88 SensorModelEntry::List list
;
89 for ( uint i
= mBars
- 1; i
< mBars
; i
-- ) {
90 SensorModelEntry entry
;
92 entry
.setHostName( sensors().at( i
)->hostName() );
93 entry
.setSensorName( KSGRD::SensorMgr
->translateSensor( sensors().at( i
)->name() ) );
94 entry
.setLabel( mPlotter
->footers
[ i
] );
95 entry
.setUnit( KSGRD::SensorMgr
->translateUnit( sensors().at( i
)->unit() ) );
96 entry
.setStatus( sensors().at( i
)->isOk() ? i18n( "OK" ) : i18n( "Error" ) );
100 dlg
.setSensors( list
);
105 setTitle( dlg
.title() );
106 mPlotter
->changeRange( dlg
.minValue(), dlg
.maxValue() );
107 mPlotter
->setLimits( dlg
.useLowerLimit() ?
108 dlg
.lowerLimit() : 0,
110 dlg
.useUpperLimit() ?
111 dlg
.upperLimit() : 0,
112 dlg
.useUpperLimit() );
114 mPlotter
->normalColor
= dlg
.foregroundColor();
115 mPlotter
->alarmColor
= dlg
.alarmColor();
116 mPlotter
->mBackgroundColor
= dlg
.backgroundColor();
117 mPlotter
->fontSize
= dlg
.fontSize();
121 list
= dlg
.sensors();
123 for ( int i
= 0; i
< sensors().count(); ++i
) {
125 for ( int j
= 0; j
< list
.count(); ++j
) {
126 if ( list
[ j
].id() == (int)( i
+ delCount
) ) {
127 mPlotter
->footers
[ i
] = list
[ j
].label();
130 list
[ j
].setId( i
);
137 if ( removeSensor(i
) ) {
147 void DancingBars::applyStyle()
149 mPlotter
->normalColor
= KSGRD::Style
->firstForegroundColor();
150 mPlotter
->alarmColor
= KSGRD::Style
->alarmColor();
151 mPlotter
->mBackgroundColor
= KSGRD::Style
->backgroundColor();
152 mPlotter
->fontSize
= KSGRD::Style
->fontSize();
157 bool DancingBars::addSensor( const QString
&hostName
, const QString
&name
,
158 const QString
&type
, const QString
&title
)
160 if ( type
!= "integer" && type
!= "float" )
166 if ( !mPlotter
->addBar( title
) )
169 registerSensor( new KSGRD::SensorProperties( hostName
, name
, type
, title
) );
171 /* To differentiate between answers from value requests and info
172 * requests we add 100 to the beam index for info requests. */
173 sendRequest( hostName
, name
+ '?', mBars
+ 100 );
175 mSampleBuffer
.resize( mBars
);
178 for ( uint i
= 0; i
< mBars
; ++i
) {
179 tooltip
+= QString( "%1%2:%3" ).arg( i
!= 0 ? "\n" : "" )
180 .arg( sensors().at( i
)->hostName() )
181 .arg( sensors().at( i
)->name() );
183 mPlotter
->setToolTip( tooltip
);
188 bool DancingBars::removeSensor( uint pos
)
190 if ( pos
>= mBars
) {
191 kDebug(1215) << "DancingBars::removeSensor: idx out of range ("
192 << pos
<< ")" << endl
;
196 mPlotter
->removeBar( pos
);
198 KSGRD::SensorDisplay::removeSensor( pos
);
201 for ( uint i
= 0; i
< mBars
; ++i
) {
202 tooltip
+= QString( "%1%2:%3" ).arg( i
!= 0 ? "\n" : "" )
203 .arg( sensors().at( i
)->hostName() )
204 .arg( sensors().at( i
)->name() );
206 mPlotter
->setToolTip( tooltip
);
211 void DancingBars::updateSamples( const QVector
<double> &samples
)
213 mPlotter
->updateSamples( samples
);
216 void DancingBars::answerReceived( int id
, const QList
<QByteArray
> &answerlist
)
218 /* We received something, so the sensor is probably ok. */
219 sensorError( id
, false );
221 if(!answerlist
.isEmpty()) answer
= answerlist
[0];
223 if(id
>= mSampleBuffer
.count()) {
224 kDebug(1215) << "ERROR: DancingBars received invalid data";
225 sensorError(id
, true);
228 mSampleBuffer
[ id
] = answer
.toDouble();
229 if ( mFlags
.testBit( id
) == true ) {
230 kDebug(1215) << "ERROR: DancingBars lost sample (" << mFlags
231 << ", " << mBars
<< ")" << endl
;
232 sensorError( id
, true );
235 mFlags
.setBit( id
, true );
237 bool allBitsAvailable
= true;
238 for ( uint i
= 0; i
< mBars
; ++i
)
239 allBitsAvailable
&= mFlags
.testBit( i
);
241 if ( allBitsAvailable
) {
242 mPlotter
->updateSamples( mSampleBuffer
);
243 mFlags
.fill( false );
245 } else if ( id
>= 100 ) {
246 KSGRD::SensorIntegerInfo
info( answer
);
248 if ( mPlotter
->getMin() == 0.0 && mPlotter
->getMax() == 0.0 ) {
249 /* We only use this information from the sensor when the
250 * display is still using the default values. If the
251 * sensor has been restored we don't touch the already set
253 mPlotter
->changeRange( info
.min(), info
.max() );
256 sensors().at( id
- 100 )->setUnit( info
.unit() );
260 bool DancingBars::restoreSettings( QDomElement
&element
)
262 SensorDisplay::restoreSettings( element
);
264 mPlotter
->changeRange( element
.attribute( "min", "0" ).toDouble(),
265 element
.attribute( "max", "0" ).toDouble() );
267 mPlotter
->setLimits( element
.attribute( "lowlimit", "0" ).toDouble(),
268 element
.attribute( "lowlimitactive", "0" ).toInt(),
269 element
.attribute( "uplimit", "0" ).toDouble(),
270 element
.attribute( "uplimitactive", "0" ).toInt() );
272 mPlotter
->normalColor
= restoreColor( element
, "normalColor",
273 KSGRD::Style
->firstForegroundColor() );
274 mPlotter
->alarmColor
= restoreColor( element
, "alarmColor",
275 KSGRD::Style
->alarmColor() );
276 mPlotter
->mBackgroundColor
= restoreColor( element
, "backgroundColor",
277 KSGRD::Style
->backgroundColor() );
278 mPlotter
->fontSize
= element
.attribute( "fontSize", QString( "%1" ).arg(
279 KSGRD::Style
->fontSize() ) ).toInt();
281 QDomNodeList dnList
= element
.elementsByTagName( "beam" );
282 for ( int i
= 0; i
< dnList
.count(); ++i
) {
283 QDomElement el
= dnList
.item( i
).toElement();
284 addSensor( el
.attribute( "hostName" ), el
.attribute( "sensorName" ),
285 ( el
.attribute( "sensorType" ).isEmpty() ? "integer" :
286 el
.attribute( "sensorType" ) ), el
.attribute( "sensorDescr" ) );
293 bool DancingBars::saveSettings( QDomDocument
&doc
, QDomElement
&element
)
295 element
.setAttribute( "min", mPlotter
->getMin() );
296 element
.setAttribute( "max", mPlotter
->getMax() );
299 mPlotter
->getLimits( l
, la
, u
, ua
);
300 element
.setAttribute( "lowlimit", l
);
301 element
.setAttribute( "lowlimitactive", la
);
302 element
.setAttribute( "uplimit", u
);
303 element
.setAttribute( "uplimitactive", ua
);
305 saveColor( element
, "normalColor", mPlotter
->normalColor
);
306 saveColor( element
, "alarmColor", mPlotter
->alarmColor
);
307 saveColor( element
, "backgroundColor", mPlotter
->mBackgroundColor
);
308 element
.setAttribute( "fontSize", mPlotter
->fontSize
);
310 for ( uint i
= 0; i
< mBars
; ++i
) {
311 QDomElement beam
= doc
.createElement( "beam" );
312 element
.appendChild( beam
);
313 beam
.setAttribute( "hostName", sensors().at( i
)->hostName() );
314 beam
.setAttribute( "sensorName", sensors().at( i
)->name() );
315 beam
.setAttribute( "sensorType", sensors().at( i
)->type() );
316 beam
.setAttribute( "sensorDescr", mPlotter
->footers
[ i
] );
319 SensorDisplay::saveSettings( doc
, element
);
324 bool DancingBars::hasSettingsDialog() const
329 #include "DancingBars.moc"