add more spacing
[personal-kdebase.git] / workspace / ksysguard / gui / SensorDisplayLib / FancyPlotter.cc
blob3bf5b091a7748f3ca60079bed8011dfc8799c8f3
1 /*
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>
31 #include <kdebug.h>
32 #include <klocale.h>
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"
44 class SensorToAdd {
45 public:
46 QRegExp name;
47 QString hostname;
48 QString type;
49 QList<QColor> colors;
50 QString summationName;
53 class FancyPlotterLabel : public QWidget {
54 public:
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>");
66 else
67 label->setText(QString("<qt><font color=\"") + color.name() + "\">" + indicatorSymbol + "</font> " + name + " :");
69 QLabel *label;
70 QLabel *value;
73 FancyPlotter::FancyPlotter( QWidget* parent,
74 const QString &title,
75 SharedSettings *workSheetSettings)
76 : KSGRD::SensorDisplay( parent, title, workSheetSettings )
78 mBeams = 0;
79 mNumAccountedFor = 0;
80 mSettingsDialog = 0;
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
84 //"#" instead.
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);
96 QFont headingFont;
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);
114 QFont font;
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 );
135 if(mHeading) {
136 mHeading->setText(translatedTitle());
140 bool FancyPlotter::eventFilter( QObject* object, QEvent* event ) { //virtual
141 if(event->type() == QEvent::ToolTip)
143 setTooltip();
145 return SensorDisplay::eventFilter(object, event);
148 void FancyPlotter::configureSettings()
150 if(mSettingsDialog)
151 return;
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;
178 entry.setId( i );
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();
199 mSettingsDialog = 0;
202 void FancyPlotter::applySettings() {
203 setTitle( mSettingsDialog->title() );
205 if ( mSettingsDialog->useAutoRange() )
206 mPlotter->setUseAutoRange( true );
207 else {
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() );
227 QFont font;
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";
251 mPlotter->update();
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";
267 mPlotter->update();
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 &regexpName,
280 int beamId, const QString & summationName)
282 if ( type != "integer" && type != "float" )
283 return false;
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);
300 ++mBeams;
303 return true;
306 bool FancyPlotter::removeSensor( uint pos )
308 if ( pos >= mBeams ) {
309 kDebug(1215) << "FancyPlotter::removeSensor: idx out of range ("
310 << pos << ")" << endl;
311 return false;
314 mPlotter->removeBeam( pos );
315 --mBeams;
316 KSGRD::SensorDisplay::removeSensor( pos );
317 QWidget *label = (static_cast<QWidgetItem *>(mLabelLayout->takeAt( pos )))->widget();
318 mLabelLayout->removeWidget(label);
319 delete label;
321 return true;
324 void FancyPlotter::setTooltip()
326 QString tooltip = "<qt><p style='white-space:pre'>";
328 QString description;
329 QString lastValue;
330 bool neednewline = false;
331 int beamId = -1;
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();
338 if(sensor->isOk()) {
339 lastValue = mPlotter->valueAsString(sensor->lastValue);
340 } else {
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);
345 neednewline = false;
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()) )
353 .arg( lastValue );
355 } else {
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()) )
360 .arg( lastValue );
362 neednewline = true;
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()) {
375 setTooltip();
377 if(isVisible()) {
378 QString lastValue;
379 int beamId = -1;
380 for ( int i = 0; i < sensors().size(); ++i ) {
381 FPSensorProperties *sensor = static_cast<FPSensorProperties *>(sensors().at(i));
382 if(sensor->beamId == beamId)
383 continue;
384 beamId = sensor->beamId;
385 if(sensor->isOk() && mPlotter->numBeams() > beamId) {
386 lastValue = mPlotter->lastValueAsString(beamId);
387 } else {
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);
398 mSampleBuf.clear();
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);
409 mUnit = "GiB";
410 } else if(value > 1024) {
411 mPlotter->setScaleDownBy(1024);
412 mUnit = "MiB";
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);
417 mUnit = "GiB/s";
418 } else if(value > 1024) {
419 mPlotter->setScaleDownBy(1024);
420 mUnit = "MiB/s";
423 mPlotter->setUnit(mUnit);
427 void FancyPlotter::answerReceived( int id, const QList<QByteArray> &answerlist )
429 QByteArray answer;
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 );
443 } else {
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 );
451 mUnit = info.unit();
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() )
481 continue;
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) {
493 delete sensor;
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 );
509 else {
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();
536 QFont font;
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(',');
556 bool ok;
557 foreach(QString color, colors) {
558 int c = color.toUInt( &ok, 0 );
559 if(ok) {
560 QColor col( (c & 0xff0000) >> 16, (c & 0xff00) >> 8, (c & 0xff), (c & 0xff000000) >> 24);
561 if(col.isValid()) {
562 if(col.alpha() == 0) col.setAlpha(255);
563 sensor->colors << col;
565 else
566 sensor->colors << KSGRD::Style->sensorColor( i );
568 else
569 sensor->colors << KSGRD::Style->sensorColor( i );
571 mSensorsToAdd.append(sensor);
572 sendRequest( sensor->hostname, "monitors", 200 );
574 } else
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 );
583 return true;
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;
610 int beamId = -1;
611 for ( int i = 0; i < sensors().size(); ++i ) {
612 FPSensorProperties *sensor = static_cast<FPSensorProperties *>(sensors().at(i));
613 if(sensor->beamId == beamId)
614 continue;
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 ) );
621 } else {
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() );
627 else {
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 );
639 return true;
642 bool FancyPlotter::hasSettingsDialog() const
644 return true;
647 FPSensorProperties::FPSensorProperties()
651 FPSensorProperties::FPSensorProperties( const QString &hostName,
652 const QString &name,
653 const QString &type,
654 const QString &description,
655 const QColor &color,
656 const QString &regexpName,
657 int beamId_,
658 const QString &summationName_ )
659 : KSGRD::SensorProperties( hostName, name, type, description),
660 mColor( color )
662 setRegExpName(regexpName);
663 beamId = beamId_;
664 summationName = summationName_;
665 maxValue = 0;
666 lastValue = 0;
669 FPSensorProperties::~FPSensorProperties()
673 void FPSensorProperties::setColor( const QColor &color )
675 mColor = color;
678 QColor FPSensorProperties::color() const
680 return mColor;
684 #include "FancyPlotter.moc"