2 KSysGuard, the KDE System Guard
4 Copyright (c) 1999 - 2002 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.
22 #include <QtXml/qdom.h>
23 #include <QtGui/QImage>
24 #include <QtGui/QToolTip>
25 #include <QtGui/QVBoxLayout>
26 #include <QtGui/QHBoxLayout>
27 #include <QtGui/QLabel>
28 #include <QtGui/QFontInfo>
33 #include <kmessagebox.h>
34 #include <kapplication.h>
35 #include <kstandarddirs.h>
37 #include <ksgrd/SensorManager.h>
38 #include "StyleEngine.h"
40 #include "FancyPlotterSettings.h"
42 #include "FancyPlotter.h"
50 QString summationName
;
53 class FancyPlotterLabel
: public QWidget
{
55 FancyPlotterLabel(QWidget
*parent
) : QWidget(parent
) {
56 QBoxLayout
*layout
= new QHBoxLayout(this);
57 label
= new QLabel(this);
58 layout
->addWidget(label
);
59 value
= new QLabel(this);
60 layout
->addWidget(value
);
61 layout
->addStretch(1);
63 void setLabel(const QString
&name
, const QColor
&color
, const QChar
&indicatorSymbol
) {
64 if ( kapp
->layoutDirection() == Qt::RightToLeft
)
65 label
->setText(QString("<qt>: ") + name
+ " <font color=\"" + color
.name() + "\">" + indicatorSymbol
+ "</font>");
67 label
->setText(QString("<qt><font color=\"") + color
.name() + "\">" + indicatorSymbol
+ "</font> " + name
+ " :");
73 FancyPlotter::FancyPlotter( QWidget
* parent
,
75 SharedSettings
*workSheetSettings
)
76 : KSGRD::SensorDisplay( parent
, title
, workSheetSettings
)
82 //The unicode character 0x25CF is a big filled in circle. We would prefer to use this in the tooltip.
83 //However it's maybe possible that the font used to draw the tooltip won't have it. So we fall back to a
85 mIndicatorSymbol
= '#';
86 QFontMetrics
fm(QToolTip::font());
87 if(fm
.inFont(QChar(0x25CF)))
88 mIndicatorSymbol
= QChar(0x25CF);
90 QBoxLayout
*layout
= new QVBoxLayout(this);
91 layout
->setSpacing(0);
92 mPlotter
= new KSignalPlotter( this );
93 int axisTextWidth
= fontMetrics().width(i18nc("Largest axis title", "99999 XXXX"));
94 mPlotter
->setMaxAxisTextWidth( axisTextWidth
);
95 mHeading
= new QLabel(translatedTitle(), this);
97 headingFont
.setFamily("Sans Serif");
98 headingFont
.setWeight(QFont::Bold
);
99 headingFont
.setPointSize(11);
100 mHeading
->setFont(headingFont
);
101 layout
->addWidget(mHeading
);
102 layout
->addWidget(mPlotter
);
104 /* Create a set of labels underneath the graph. */
105 QBoxLayout
*outerLabelLayout
= new QHBoxLayout
;
106 outerLabelLayout
->setSpacing(0);
107 layout
->addLayout(outerLabelLayout
);
109 /* create a spacer to fill up the space up to the start of the graph */
110 outerLabelLayout
->addItem(new QSpacerItem(axisTextWidth
, 0, QSizePolicy::Preferred
));
112 mLabelLayout
= new QHBoxLayout
;
113 outerLabelLayout
->addLayout(mLabelLayout
);
115 font
.setPointSize( KSGRD::Style
->fontSize() );
116 mPlotter
->setAxisFont( font
);
117 mPlotter
->setAxisFontColor( Qt::black
);
119 mPlotter
->setThinFrame(!(workSheetSettings
&& workSheetSettings
->isApplet
));
121 /* All RMB clicks to the mPlotter widget will be handled by
122 * SensorDisplay::eventFilter. */
123 mPlotter
->installEventFilter( this );
125 setPlotterWidget( mPlotter
);
126 connect(mPlotter
, SIGNAL(axisScaleChanged()), this, SLOT(plotterAxisScaleChanged()));
129 FancyPlotter::~FancyPlotter()
133 void FancyPlotter::setTitle( const QString
&title
) { //virtual
134 KSGRD::SensorDisplay::setTitle( title
);
136 mHeading
->setText(translatedTitle());
140 bool FancyPlotter::eventFilter( QObject
* object
, QEvent
* event
) { //virtual
141 if(event
->type() == QEvent::ToolTip
)
145 return SensorDisplay::eventFilter(object
, event
);
148 void FancyPlotter::configureSettings()
152 mSettingsDialog
= new FancyPlotterSettings( this, mSharedSettings
->locked
);
154 mSettingsDialog
->setTitle( title() );
155 mSettingsDialog
->setUseAutoRange( mPlotter
->useAutoRange() );
156 mSettingsDialog
->setMinValue( mPlotter
->minValue() );
157 mSettingsDialog
->setMaxValue( mPlotter
->maxValue() );
159 mSettingsDialog
->setHorizontalScale( mPlotter
->horizontalScale() );
161 mSettingsDialog
->setShowVerticalLines( mPlotter
->showVerticalLines() );
162 mSettingsDialog
->setGridLinesColor( mPlotter
->verticalLinesColor() );
163 mSettingsDialog
->setVerticalLinesDistance( mPlotter
->verticalLinesDistance() );
164 mSettingsDialog
->setVerticalLinesScroll( mPlotter
->verticalLinesScroll() );
166 mSettingsDialog
->setShowHorizontalLines( mPlotter
->showHorizontalLines() );
168 mSettingsDialog
->setShowAxis( mPlotter
->showAxis() );
170 mSettingsDialog
->setFontSize( mPlotter
->axisFont().pointSize() );
171 mSettingsDialog
->setFontColor( mPlotter
->axisFontColor() );
173 mSettingsDialog
->setBackgroundColor( mPlotter
->backgroundColor() );
175 SensorModelEntry::List list
;
176 for ( uint i
= 0; i
< mBeams
; ++i
) {
177 SensorModelEntry entry
;
179 entry
.setHostName( sensors().at( i
)->hostName() );
180 entry
.setSensorName( sensors().at( i
)->name() );
181 entry
.setUnit( KSGRD::SensorMgr
->translateUnit( sensors().at( i
)->unit() ) );
182 entry
.setStatus( sensors().at( i
)->isOk() ? i18n( "OK" ) : i18n( "Error" ) );
183 entry
.setColor( mPlotter
->beamColor( i
) );
185 list
.append( entry
);
187 mSettingsDialog
->setSensors( list
);
189 connect( mSettingsDialog
, SIGNAL( applyClicked() ), this, SLOT( applySettings() ) );
190 connect( mSettingsDialog
, SIGNAL( okClicked() ), this, SLOT( applySettings() ) );
191 connect( mSettingsDialog
, SIGNAL( finished() ), this, SLOT( settingsFinished() ) );
193 mSettingsDialog
->show();
196 void FancyPlotter::settingsFinished()
198 mSettingsDialog
->delayedDestruct();
202 void FancyPlotter::applySettings() {
203 setTitle( mSettingsDialog
->title() );
205 if ( mSettingsDialog
->useAutoRange() )
206 mPlotter
->setUseAutoRange( true );
208 mPlotter
->setUseAutoRange( false );
209 mPlotter
->changeRange( mSettingsDialog
->minValue(),
210 mSettingsDialog
->maxValue() );
213 if ( mPlotter
->horizontalScale() != mSettingsDialog
->horizontalScale() ) {
214 mPlotter
->setHorizontalScale( mSettingsDialog
->horizontalScale() );
217 mPlotter
->setShowVerticalLines( mSettingsDialog
->showVerticalLines() );
218 mPlotter
->setVerticalLinesColor( mSettingsDialog
->gridLinesColor() );
219 mPlotter
->setVerticalLinesDistance( mSettingsDialog
->verticalLinesDistance() );
220 mPlotter
->setVerticalLinesScroll( mSettingsDialog
->verticalLinesScroll() );
222 mPlotter
->setShowHorizontalLines( mSettingsDialog
->showHorizontalLines() );
223 mPlotter
->setHorizontalLinesColor( mSettingsDialog
->gridLinesColor() );
225 mPlotter
->setShowAxis( mSettingsDialog
->showAxis() );
228 font
.setPointSize( mSettingsDialog
->fontSize() );
229 mPlotter
->setAxisFont( font
);
230 mPlotter
->setAxisFontColor( mSettingsDialog
->fontColor() );
232 mPlotter
->setBackgroundColor( mSettingsDialog
->backgroundColor() );
234 QList
<int> deletedSensors
= mSettingsDialog
->deleted();
235 for ( int i
=0; i
< deletedSensors
.count(); ++i
) {
236 removeSensor(deletedSensors
[i
]);
238 mSettingsDialog
->clearDeleted(); //We have deleted them, so clear the deleted
240 QList
<int> orderOfSensors
= mSettingsDialog
->order();
241 mPlotter
->reorderBeams(orderOfSensors
);
242 reorderSensors(orderOfSensors
);
243 mSettingsDialog
->resetOrder(); //We have now reordered the sensors, so reset the order
245 SensorModelEntry::List list
= mSettingsDialog
->sensors();
247 for ( int i
= 0; i
< sensors().count(); ++i
) {
248 mPlotter
->setBeamColor( i
, list
[ i
].color() );
250 kDebug() << "Settings changed";
254 void FancyPlotter::applyStyle()
256 mPlotter
->setVerticalLinesColor( KSGRD::Style
->firstForegroundColor() );
257 mPlotter
->setHorizontalLinesColor( KSGRD::Style
->secondForegroundColor() );
258 mPlotter
->setBackgroundColor( KSGRD::Style
->backgroundColor() );
259 QFont font
= mPlotter
->axisFont();
260 font
.setPointSize(KSGRD::Style
->fontSize() );
261 mPlotter
->setAxisFont( font
);
262 for ( int i
= 0; i
< mPlotter
->numBeams() &&
263 (unsigned int)i
< KSGRD::Style
->numSensorColors(); ++i
)
264 mPlotter
->setBeamColor( i
, KSGRD::Style
->sensorColor( i
) );
266 kDebug() << "Style changed";
270 bool FancyPlotter::addSensor( const QString
&hostName
, const QString
&name
,
271 const QString
&type
, const QString
&title
)
273 return addSensor( hostName
, name
, type
, title
,
274 KSGRD::Style
->sensorColor( mBeams
), QString(), mBeams
);
277 bool FancyPlotter::addSensor( const QString
&hostName
, const QString
&name
,
278 const QString
&type
, const QString
&title
,
279 const QColor
&color
, const QString
®expName
,
280 int beamId
, const QString
& summationName
)
282 if ( type
!= "integer" && type
!= "float" )
286 registerSensor( new FPSensorProperties( hostName
, name
, type
, title
, color
, regexpName
, beamId
, summationName
) );
288 /* To differentiate between answers from value requests and info
289 * requests we add 100 to the beam index for info requests. */
290 sendRequest( hostName
, name
+ '?', sensors().size() - 1 + 100 );
292 if((int)mBeams
== beamId
) {
293 mPlotter
->addBeam( color
);
294 /* Add a label for this beam */
295 FancyPlotterLabel
*label
= new FancyPlotterLabel(this);
296 mLabelLayout
->addWidget(label
);
297 if(!summationName
.isEmpty()) {
298 label
->setLabel(summationName
, mPlotter
->beamColor(mBeams
), mIndicatorSymbol
);
306 bool FancyPlotter::removeSensor( uint pos
)
308 if ( pos
>= mBeams
) {
309 kDebug(1215) << "FancyPlotter::removeSensor: idx out of range ("
310 << pos
<< ")" << endl
;
314 mPlotter
->removeBeam( pos
);
316 KSGRD::SensorDisplay::removeSensor( pos
);
317 QWidget
*label
= (static_cast<QWidgetItem
*>(mLabelLayout
->takeAt( pos
)))->widget();
318 mLabelLayout
->removeWidget(label
);
324 void FancyPlotter::setTooltip()
326 QString tooltip
= "<qt><p style='white-space:pre'>";
330 bool neednewline
= false;
332 for ( int i
= 0; i
< sensors().count(); ++i
) {
333 FPSensorProperties
*sensor
= static_cast<FPSensorProperties
*>(sensors().at(i
));
334 description
= sensor
->description();
335 if(description
.isEmpty()) {
336 description
= sensor
->name();
339 lastValue
= mPlotter
->valueAsString(sensor
->lastValue
);
341 lastValue
= i18n("Error");
343 if(beamId
!= sensor
->beamId
&& !sensor
->summationName
.isEmpty()) {
344 tooltip
+= i18nc("%1 is what is being shown statistics for, like 'Memory', 'Swap', etc.", "<p><b>%1:</b><br>", sensor
->summationName
);
347 beamId
= sensor
->beamId
;
349 if(sensor
->isLocalhost()) {
350 tooltip
+= QString( "%1%2 %3 (%4)" ).arg( neednewline
? "<br>" : "")
351 .arg("<font color=\"" + mPlotter
->beamColor( beamId
).name() + "\">"+mIndicatorSymbol
+"</font>")
352 .arg( i18n(description
.toLatin1()) )
356 tooltip
+= QString( "%1%2 %3:%4 (%5)" ).arg( neednewline
? "<br>" : "" )
357 .arg("<font color=\"" + mPlotter
->beamColor( beamId
).name() + "\">"+mIndicatorSymbol
+"</font>")
358 .arg( sensor
->hostName() )
359 .arg( i18n(description
.toLatin1()) )
364 // tooltip += "</td></tr></table>";
365 mPlotter
->setToolTip( tooltip
);
368 void FancyPlotter::timerTick( ) //virtual
370 if(!mSampleBuf
.isEmpty() && mBeams
!= 0) {
371 while((uint
)mSampleBuf
.count() < mBeams
)
372 mSampleBuf
.append(mPlotter
->lastValue(mSampleBuf
.count())); //we might have sensors missing so set their values to the previously known value
373 mPlotter
->addSample( mSampleBuf
);
374 if(QToolTip::isVisible()) {
380 for ( int i
= 0; i
< sensors().size(); ++i
) {
381 FPSensorProperties
*sensor
= static_cast<FPSensorProperties
*>(sensors().at(i
));
382 if(sensor
->beamId
== beamId
)
384 beamId
= sensor
->beamId
;
385 if(sensor
->isOk() && mPlotter
->numBeams() > beamId
) {
386 lastValue
= mPlotter
->lastValueAsString(beamId
);
388 lastValue
= i18n("Error");
390 if(sensor
->maxValue
!= 0 && mUnit
!= "%")
391 lastValue
= i18nc("%1 and %2 are sensor's last and maximum value", "%1 of %2", lastValue
, mPlotter
->valueAsString(sensor
->maxValue
) );
393 static_cast<FancyPlotterLabel
*>((static_cast<QWidgetItem
*>(mLabelLayout
->itemAt(beamId
)))->widget())->value
->setText(lastValue
);
400 SensorDisplay::timerTick();
402 void FancyPlotter::plotterAxisScaleChanged()
404 QString unit
= mUnit
.toUpper();
405 double value
= mPlotter
->maxValue();
406 if(unit
== "KB" || unit
== "KIB") {
407 if(value
>= 1024*1024*0.7) { //If it's over 0.7GiB, then set the scale to gigabytes
408 mPlotter
->setScaleDownBy(1024*1024);
410 } else if(value
> 1024) {
411 mPlotter
->setScaleDownBy(1024);
414 } else if(unit
== "KB/S" || unit
== "KIB/S") {
415 if(value
>= 1024*1024*0.7) { //If it's over 0.7GiB, then set the scale to gigabytes
416 mPlotter
->setScaleDownBy(1024*1024);
418 } else if(value
> 1024) {
419 mPlotter
->setScaleDownBy(1024);
423 mPlotter
->setUnit(mUnit
);
427 void FancyPlotter::answerReceived( int id
, const QList
<QByteArray
> &answerlist
)
431 if(!answerlist
.isEmpty()) answer
= answerlist
[0];
432 if ( (uint
)id
< 100 ) {
433 //Make sure that we put the answer in the correct place. It's index in the list should be equal to the sensor index. This in turn will contain the beamId
435 FPSensorProperties
*sensor
= static_cast<FPSensorProperties
*>(sensors().at(id
));
436 int beamId
= sensor
->beamId
;
437 double value
= answer
.toDouble();
438 while(beamId
> mSampleBuf
.count())
439 mSampleBuf
.append(0); //we might have sensors missing so set their values to zero
441 if(beamId
== mSampleBuf
.count()) {
442 mSampleBuf
.append( value
);
444 mSampleBuf
[beamId
] += value
; //If we get two answers for the same beamid, we should add them together. That's how the summation works
446 sensor
->lastValue
= value
;
447 /* We received something, so the sensor is probably ok. */
448 sensorError( id
, false );
449 } else if ( id
>= 100 && id
< 200 ) {
450 KSGRD::SensorFloatInfo
info( answer
);
452 mSensorReportedMax
= info
.max();
453 mSensorReportedMin
= info
.min();
455 if ( !mPlotter
->useAutoRange()) {
456 mPlotter
->changeRange( info
.min(), info
.max() );
457 if ( info
.min() == 0.0 && info
.max() == 0.0 )
458 mPlotter
->setUseAutoRange( true );
459 plotterAxisScaleChanged();
461 FPSensorProperties
*sensor
= static_cast<FPSensorProperties
*>(sensors().at(id
- 100));
462 sensor
->maxValue
= info
.max();
463 sensor
->setUnit( info
.unit() );
465 mPlotter
->setUnit( KSGRD::SensorMgr
->translateUnit( mUnit
) );
466 sensor
->setDescription( info
.name() );
468 QString summationName
= sensor
->summationName
;
469 int beamId
= sensor
->beamId
;
471 if(summationName
.isEmpty())
472 static_cast<FancyPlotterLabel
*>((static_cast<QWidgetItem
*>(mLabelLayout
->itemAt(beamId
)))->widget())->setLabel(info
.name(), mPlotter
->beamColor(id
-100), mIndicatorSymbol
);
474 } else if( id
== 200) {
475 /* FIXME This doesn't check the host! */
476 if(!mSensorsToAdd
.isEmpty()) {
477 foreach(SensorToAdd
*sensor
, mSensorsToAdd
) {
478 int beamId
= mBeams
; //Assign the next sensor to the next available beamId
479 for ( int i
= 0; i
< answerlist
.count(); ++i
) {
480 if ( answerlist
[ i
].isEmpty() )
482 QString sensorName
= QString::fromUtf8(answerlist
[ i
].split('\t')[0]);
483 if(sensor
->name
.exactMatch(sensorName
)) {
484 if(sensor
->summationName
.isEmpty())
485 beamId
= mBeams
; //If summationName is not empty then reuse the previous beamId. In this way we can have multiple sensors with the same beamId, which can then be summed together
486 addSensor( sensor
->hostname
, sensorName
,
487 (sensor
->type
.isEmpty()) ? "integer" : sensor
->type
488 , "", (sensor
->colors
.isEmpty()) ? QColor() : sensor
->colors
.takeFirst(), sensor
->name
.pattern(), beamId
, sensor
->summationName
);
492 foreach(SensorToAdd
*sensor
, mSensorsToAdd
) {
495 mSensorsToAdd
.clear();
500 bool FancyPlotter::restoreSettings( QDomElement
&element
)
502 /* autoRange was added after KDE 2.x and was brokenly emulated by
503 * min == 0.0 and max == 0.0. Since we have to be able to read old
504 * files as well we have to emulate the old behaviour as well. */
505 double min
= element
.attribute( "min", "0.0" ).toDouble();
506 double max
= element
.attribute( "max", "0.0" ).toDouble();
507 if ( element
.attribute( "autoRange", min
== 0.0 && max
== 0.0 ? "1" : "0" ).toInt() )
508 mPlotter
->setUseAutoRange( true );
510 mPlotter
->setUseAutoRange( false );
511 mPlotter
->changeRange( element
.attribute( "min" ).toDouble(),
512 element
.attribute( "max" ).toDouble() );
515 mPlotter
->setShowVerticalLines( element
.attribute( "vLines", "1" ).toUInt() );
516 QColor vcolor
= restoreColor( element
, "vColor", mPlotter
->verticalLinesColor() );
517 mPlotter
->setVerticalLinesColor( vcolor
);
518 mPlotter
->setVerticalLinesDistance( element
.attribute( "vDistance", "30" ).toUInt() );
519 mPlotter
->setVerticalLinesScroll( element
.attribute( "vScroll", "1" ).toUInt() );
520 mPlotter
->setHorizontalScale( element
.attribute( "hScale", "6" ).toUInt() );
522 mPlotter
->setShowHorizontalLines( element
.attribute( "hLines", "1" ).toUInt() );
523 mPlotter
->setHorizontalLinesColor( restoreColor( element
, "hColor",
524 mPlotter
->horizontalLinesColor() ) );
526 QString filename
= element
.attribute( "svgBackground");
527 if (!filename
.isEmpty() && filename
[0] == '/') {
528 KStandardDirs
* kstd
= KGlobal::dirs();
529 filename
= kstd
->findResource( "data", "ksysguard/" + filename
);
531 mPlotter
->setSvgBackground( filename
);
533 mPlotter
->setShowAxis( element
.attribute( "labels", "1" ).toUInt() );
534 uint fontsize
= element
.attribute( "fontSize", "0").toUInt();
535 if(fontsize
== 0) fontsize
= KSGRD::Style
->fontSize();
537 font
.setPointSize( fontsize
);
539 mPlotter
->setAxisFont( font
);
541 mPlotter
->setAxisFontColor( restoreColor( element
, "fontColor", Qt::black
) ); //make the default to be the same as the vertical line color
543 mPlotter
->setBackgroundColor( restoreColor( element
, "bColor",
544 KSGRD::Style
->backgroundColor() ) );
546 QDomNodeList dnList
= element
.elementsByTagName( "beam" );
547 for ( int i
= 0; i
< dnList
.count(); ++i
) {
548 QDomElement el
= dnList
.item( i
).toElement();
549 if(el
.hasAttribute("regexpSensorName")) {
550 SensorToAdd
*sensor
= new SensorToAdd();
551 sensor
->name
= QRegExp(el
.attribute("regexpSensorName"));
552 sensor
->hostname
= el
.attribute( "hostName" );
553 sensor
->type
= el
.attribute( "sensorType" );
554 sensor
->summationName
= el
.attribute("summationName");
555 QStringList colors
= el
.attribute("color").split(',');
557 foreach(QString color
, colors
) {
558 int c
= color
.toUInt( &ok
, 0 );
560 QColor
col( (c
& 0xff0000) >> 16, (c
& 0xff00) >> 8, (c
& 0xff), (c
& 0xff000000) >> 24);
562 if(col
.alpha() == 0) col
.setAlpha(255);
563 sensor
->colors
<< col
;
566 sensor
->colors
<< KSGRD::Style
->sensorColor( i
);
569 sensor
->colors
<< KSGRD::Style
->sensorColor( i
);
571 mSensorsToAdd
.append(sensor
);
572 sendRequest( sensor
->hostname
, "monitors", 200 );
575 addSensor( el
.attribute( "hostName" ), el
.attribute( "sensorName" ),
576 ( el
.attribute( "sensorType" ).isEmpty() ? "integer" :
577 el
.attribute( "sensorType" ) ), "", restoreColor( el
, "color",
578 KSGRD::Style
->sensorColor( i
) ), QString(), mBeams
, el
.attribute("summationName") );
581 SensorDisplay::restoreSettings( element
);
586 bool FancyPlotter::saveSettings( QDomDocument
&doc
, QDomElement
&element
)
588 element
.setAttribute( "min", mPlotter
->minValue() );
589 element
.setAttribute( "max", mPlotter
->maxValue() );
590 element
.setAttribute( "autoRange", mPlotter
->useAutoRange() );
591 element
.setAttribute( "vLines", mPlotter
->showVerticalLines() );
592 saveColor( element
, "vColor", mPlotter
->verticalLinesColor() );
593 element
.setAttribute( "vDistance", mPlotter
->verticalLinesDistance() );
594 element
.setAttribute( "vScroll", mPlotter
->verticalLinesScroll() );
596 element
.setAttribute( "hScale", mPlotter
->horizontalScale() );
598 element
.setAttribute( "hLines", mPlotter
->showHorizontalLines() );
599 saveColor( element
, "hColor", mPlotter
->horizontalLinesColor() );
601 element
.setAttribute( "svgBackground", mPlotter
->svgBackground() );
603 element
.setAttribute( "labels", mPlotter
->showAxis() );
604 element
.setAttribute( "fontSize", mPlotter
->axisFont().pointSize() );
605 saveColor ( element
, "fontColor", mPlotter
->axisFontColor());
607 saveColor( element
, "bColor", mPlotter
->backgroundColor() );
609 QHash
<QString
,QDomElement
> hash
;
611 for ( int i
= 0; i
< sensors().size(); ++i
) {
612 FPSensorProperties
*sensor
= static_cast<FPSensorProperties
*>(sensors().at(i
));
613 if(sensor
->beamId
== beamId
)
615 beamId
= sensor
->beamId
;
617 QString regExpName
= sensor
->regExpName();
618 if(!regExpName
.isEmpty() && hash
.contains( regExpName
)) {
619 QDomElement oldBeam
= hash
.value(regExpName
);
620 saveColorAppend( oldBeam
, "color", mPlotter
->beamColor( beamId
) );
622 QDomElement beam
= doc
.createElement( "beam" );
623 element
.appendChild( beam
);
624 beam
.setAttribute( "hostName", sensor
->hostName() );
625 if(regExpName
.isEmpty())
626 beam
.setAttribute( "sensorName", sensor
->name() );
628 beam
.setAttribute( "regexpSensorName", sensor
->regExpName() );
629 hash
[regExpName
] = beam
;
631 if(!sensor
->summationName
.isEmpty())
632 beam
.setAttribute( "summationName", sensor
->summationName
);
633 beam
.setAttribute( "sensorType", sensor
->type() );
634 saveColor( beam
, "color", mPlotter
->beamColor( beamId
) );
637 SensorDisplay::saveSettings( doc
, element
);
642 bool FancyPlotter::hasSettingsDialog() const
647 FPSensorProperties::FPSensorProperties()
651 FPSensorProperties::FPSensorProperties( const QString
&hostName
,
654 const QString
&description
,
656 const QString
®expName
,
658 const QString
&summationName_
)
659 : KSGRD::SensorProperties( hostName
, name
, type
, description
),
662 setRegExpName(regexpName
);
664 summationName
= summationName_
;
669 FPSensorProperties::~FPSensorProperties()
673 void FPSensorProperties::setColor( const QColor
&color
)
678 QColor
FPSensorProperties::color() const
684 #include "FancyPlotter.moc"