~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to ksysguard/gui/SensorDisplayLib/DancingBars.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    KSysGuard, the KDE System Guard
 
3
   
 
4
    Copyright (c) 1999, 2000, 2001 Chris Schlaeger <cs@kde.org>
 
5
    
 
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.
 
10
 
 
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.
 
15
 
 
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.
 
19
 
 
20
*/
 
21
 
 
22
#include <QCheckBox>
 
23
#include <QtXml/qdom.h>
 
24
#include <QLineEdit>
 
25
#include <QPushButton>
 
26
#include <QSpinBox>
 
27
#include <QHBoxLayout>
 
28
 
 
29
#include <kdebug.h>
 
30
#include <klocale.h>
 
31
#include <knumvalidator.h>
 
32
#include <ksgrd/SensorManager.h>
 
33
#include "StyleEngine.h"
 
34
 
 
35
#include "BarGraph.h"
 
36
#include "DancingBarsSettings.h"
 
37
 
 
38
#include "DancingBars.h"
 
39
 
 
40
DancingBars::DancingBars( QWidget *parent, const QString &title, SharedSettings *workSheetSettings)
 
41
  : KSGRD::SensorDisplay( parent, title, workSheetSettings)
 
42
{
 
43
  mBars = 0;
 
44
  mFlags = QBitArray( 100 );
 
45
  mFlags.fill( false );
 
46
 
 
47
  QLayout *layout = new QHBoxLayout(this);
 
48
  mPlotter = new BarGraph( this );
 
49
  layout->addWidget(mPlotter);
 
50
 
 
51
  setMinimumSize( sizeHint() );
 
52
 
 
53
  /* All RMB clicks to the mPlotter widget will be handled by 
 
54
   * SensorDisplay::eventFilter. */
 
55
  mPlotter->installEventFilter( this );
 
56
 
 
57
  setPlotterWidget( mPlotter );
 
58
 
 
59
}
 
60
 
 
61
DancingBars::~DancingBars()
 
62
{
 
63
}
 
64
 
 
65
void DancingBars::configureSettings()
 
66
{
 
67
  DancingBarsSettings dlg( this );
 
68
 
 
69
  dlg.setTitle( title() );
 
70
  dlg.setMinValue( mPlotter->getMin() );
 
71
  dlg.setMaxValue( mPlotter->getMax() );
 
72
 
 
73
  double l, u;
 
74
  bool la, ua;
 
75
  mPlotter->getLimits( l, la, u, ua );
 
76
 
 
77
  dlg.setUseUpperLimit( ua );
 
78
  dlg.setUpperLimit( u );
 
79
 
 
80
  dlg.setUseLowerLimit( la );
 
81
  dlg.setLowerLimit( l );
 
82
 
 
83
  dlg.setForegroundColor( mPlotter->normalColor );
 
84
  dlg.setAlarmColor( mPlotter->alarmColor );
 
85
  dlg.setBackgroundColor( mPlotter->mBackgroundColor );
 
86
  dlg.setFontSize( mPlotter->fontSize );
 
87
 
 
88
  SensorModelEntry::List list;
 
89
  for ( uint i = mBars - 1; i < mBars; i-- ) {
 
90
    SensorModelEntry entry;
 
91
    entry.setId( i );
 
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" ) );
 
97
 
 
98
    list.append( entry );
 
99
  }
 
100
  dlg.setSensors( list );
 
101
 
 
102
  if ( !dlg.exec() )
 
103
    return;
 
104
 
 
105
  setTitle( dlg.title() );
 
106
  mPlotter->changeRange( dlg.minValue(), dlg.maxValue() );
 
107
  mPlotter->setLimits( dlg.useLowerLimit() ?
 
108
                       dlg.lowerLimit() : 0,
 
109
                       dlg.useLowerLimit(),
 
110
                       dlg.useUpperLimit() ?
 
111
                       dlg.upperLimit() : 0,
 
112
                       dlg.useUpperLimit() );
 
113
 
 
114
  mPlotter->normalColor = dlg.foregroundColor();
 
115
  mPlotter->alarmColor = dlg.alarmColor();
 
116
  mPlotter->mBackgroundColor = dlg.backgroundColor();
 
117
  mPlotter->fontSize = dlg.fontSize();
 
118
 
 
119
  uint delCount = 0;
 
120
 
 
121
  list = dlg.sensors();
 
122
 
 
123
  for ( int i = 0; i < sensors().count(); ++i ) {
 
124
    bool found = false;
 
125
    for ( int j = 0; j < list.count(); ++j ) {
 
126
      if ( list[ j ].id() == (int)( i + delCount ) ) {
 
127
        mPlotter->footers[ i ] = list[ j ].label();
 
128
        found = true;
 
129
        if ( delCount > 0 )
 
130
          list[ j ].setId( i );
 
131
 
 
132
        continue;
 
133
      }
 
134
    }
 
135
 
 
136
    if ( !found ) {
 
137
      if ( removeSensor(i) ) {
 
138
        i--;
 
139
        delCount++;
 
140
      }
 
141
    }
 
142
  }
 
143
 
 
144
  repaint();
 
145
}
 
146
 
 
147
void DancingBars::applyStyle()
 
148
{
 
149
  mPlotter->normalColor = KSGRD::Style->firstForegroundColor();
 
150
  mPlotter->alarmColor = KSGRD::Style->alarmColor();
 
151
  mPlotter->mBackgroundColor = KSGRD::Style->backgroundColor();
 
152
  mPlotter->fontSize = KSGRD::Style->fontSize();
 
153
 
 
154
  repaint();
 
155
}
 
156
 
 
157
bool DancingBars::addSensor( const QString &hostName, const QString &name,
 
158
                             const QString &type, const QString &title )
 
159
{
 
160
  if ( type != "integer" && type != "float" )
 
161
    return false;
 
162
 
 
163
  if ( mBars >= 32 )
 
164
    return false;
 
165
 
 
166
  if ( !mPlotter->addBar( title ) )
 
167
    return false;
 
168
 
 
169
  registerSensor( new KSGRD::SensorProperties( hostName, name, type, title ) );
 
170
 
 
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 );
 
174
  ++mBars;
 
175
  mSampleBuffer.resize( mBars );
 
176
 
 
177
  QString tooltip;
 
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() );
 
182
  }
 
183
  mPlotter->setToolTip( tooltip );
 
184
 
 
185
  return true;
 
186
}
 
187
 
 
188
bool DancingBars::removeSensor( uint pos )
 
189
{
 
190
  if ( pos >= mBars ) {
 
191
    kDebug(1215) << "DancingBars::removeSensor: idx out of range ("
 
192
                  << pos << ")" << endl;
 
193
    return false;
 
194
  }
 
195
 
 
196
  mPlotter->removeBar( pos );
 
197
  mBars--;
 
198
  KSGRD::SensorDisplay::removeSensor( pos );
 
199
 
 
200
  QString tooltip;
 
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() );
 
205
  }
 
206
  mPlotter->setToolTip( tooltip );
 
207
 
 
208
  return true;
 
209
}
 
210
 
 
211
void DancingBars::updateSamples( const QVector<double> &samples )
 
212
{
 
213
  mPlotter->updateSamples( samples );
 
214
}
 
215
 
 
216
void DancingBars::answerReceived( int id, const QList<QByteArray> &answerlist )
 
217
{
 
218
  /* We received something, so the sensor is probably ok. */
 
219
  sensorError( id, false );
 
220
  QByteArray answer;
 
221
  if(!answerlist.isEmpty()) answer = answerlist[0];
 
222
  if ( id < 100 ) {
 
223
    if(id >= mSampleBuffer.count()) {
 
224
      kDebug(1215) << "ERROR: DancingBars received invalid data";
 
225
      sensorError(id, true);
 
226
      return;
 
227
    }
 
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 );
 
233
      return;
 
234
    }
 
235
    mFlags.setBit( id, true );
 
236
 
 
237
    bool allBitsAvailable = true;
 
238
    for ( uint i = 0; i < mBars; ++i )
 
239
      allBitsAvailable &= mFlags.testBit( i );
 
240
 
 
241
    if ( allBitsAvailable ) {
 
242
      mPlotter->updateSamples( mSampleBuffer );
 
243
      mFlags.fill( false );
 
244
    }
 
245
  } else if ( id >= 100 ) {
 
246
    KSGRD::SensorIntegerInfo info( answer );
 
247
    if ( id == 100 )
 
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
 
252
         * values. */
 
253
        mPlotter->changeRange( info.min(), info.max() );
 
254
      }
 
255
 
 
256
    sensors().at( id - 100 )->setUnit( info.unit() );
 
257
  }
 
258
}
 
259
 
 
260
bool DancingBars::restoreSettings( QDomElement &element )
 
261
{
 
262
  SensorDisplay::restoreSettings( element );
 
263
 
 
264
  mPlotter->changeRange( element.attribute( "min", "0" ).toDouble(),
 
265
                         element.attribute( "max", "0" ).toDouble() );
 
266
 
 
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() );
 
271
 
 
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();
 
280
 
 
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" ) );
 
287
  }
 
288
 
 
289
 
 
290
  return true;
 
291
}
 
292
 
 
293
bool DancingBars::saveSettings( QDomDocument &doc, QDomElement &element)
 
294
{
 
295
  element.setAttribute( "min", mPlotter->getMin() );
 
296
  element.setAttribute( "max", mPlotter->getMax() );
 
297
  double l, u;
 
298
  bool la, ua;
 
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 );
 
304
 
 
305
  saveColor( element, "normalColor", mPlotter->normalColor );
 
306
  saveColor( element, "alarmColor", mPlotter->alarmColor );
 
307
        saveColor( element, "backgroundColor", mPlotter->mBackgroundColor );
 
308
  element.setAttribute( "fontSize", mPlotter->fontSize );
 
309
 
 
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 ] );
 
317
  }
 
318
 
 
319
  SensorDisplay::saveSettings( doc, element );
 
320
 
 
321
  return true;
 
322
}
 
323
 
 
324
bool DancingBars::hasSettingsDialog() const
 
325
{
 
326
  return true;
 
327
}
 
328
 
 
329
#include "DancingBars.moc"