fixed some compiler-warnings
[opensuse:qinternet.git] / src / datarateview.cpp
1
2 /***************************************************************************
3  *                                                                         *
4  *   Copyright: SuSE Linux AG, Nuernberg                                   *
5  *                                                                         *
6  *   Author: Arvin Schnell <arvin@suse.de>                                 *
7  *                                                                         *
8  ***************************************************************************/
9
10 /***************************************************************************
11  *                                                                         *
12  *   This program is free software; you can redistribute it and/or modify  *
13  *   it under the terms of the GNU General Public License as published by  *
14  *   the Free Software Foundation; either version 2 of the License, or     *
15  *   (at your option) any later version.                                   *
16  *                                                                         *
17  ***************************************************************************/
18
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <math.h>
23
24 #include <QLayout>
25 #include <q3hbox.h>
26 #include <qtimer.h>
27 #include <qpainter.h>
28 #include <qpixmap.h>
29 #include <qsizepolicy.h>
30 //Added by qt3to4:
31 #include <QCloseEvent>
32 #include <QPaintEvent>
33 #include <QLabel>
34
35 #include "main.h"
36 #include "datarateview.h"
37 #include "utils.h"
38 #include "debug.h"
39
40
41 static QString
42 format_bytes (Data::bytes_t bytes, int suffix)
43 {
44     static bool did_init = false;
45     static QString prefixes[5];
46     static QString suffixes[2];
47
48     if (!did_init)
49     {
50         did_init = true;
51
52         //desc: B/s means bytes per second
53         prefixes[0] = i18n ("%1 B/s");
54         //desc: kB/s means kilo bytes per second
55         prefixes[1] = i18n ("%1 kB/s");
56         //desc: MB/s means mega bytes per second
57         prefixes[2] = i18n ("%1 MB/s");
58         //desc: GB/s means giga bytes per second
59         prefixes[3] = i18n ("%1 GB/s");
60         //desc: TB/s means tera bytes per second
61         prefixes[4] = i18n ("%1 TB/s");
62
63         //desc: rx is abbrev. of receive and appended to xB/s
64         suffixes[0] = "rx";
65         //desc: tx is abbrev. of transmit and appended to xB/s
66         suffixes[1] = "tx";
67     }
68
69     double f = (double)(bytes);
70     int prefix = 0;
71
72     while (f >= 1024.0 && prefix < (5-1))
73     {
74         f /= 1024.0;
75         prefix++;
76     }
77
78     QString ret = prefixes[prefix];
79     if (f > 100.0 || prefix == 0)
80         ret = ret.arg ((unsigned long) (f));
81     else
82         ret = ret.arg (f, 0, 'f', 1);
83
84     if (suffix == 0 || suffix == 1)
85         ret += " " + suffixes[suffix];
86
87     return ret;
88 }
89
90
91 DatarateviewDlg::DatarateviewDlg (QWidget* parent, const char* name)
92     : MyDialog (parent, name)
93 {
94     //desc: dialog title
95     setCaption (mycaption (i18n ("Data Rate")));
96
97     Q3HBox* hbox = new Q3HBox (this);
98     this->layout()->addWidget(hbox);
99
100     label = new QLabel (hbox);
101     label->setText (i18n ("Data rate:"));
102     label->setAlignment (Qt::AlignLeft);
103
104     rate_rx = new QLabel (hbox);
105     rate_rx->setAlignment (Qt::AlignRight);
106     rate_rx->setPaletteForegroundColor (QColor (0, 170, 0));
107     rate_rx->setText (format_bytes (0, 0));
108
109     rate_tx = new QLabel (hbox);
110     rate_tx->setAlignment (Qt::AlignRight);
111     rate_tx->setPaletteForegroundColor (QColor (200, 0, 0));
112     rate_tx->setText (format_bytes (0, 1));
113
114     plot = new Plot (this);
115     plot->set_data (this);
116     this->layout()->addWidget(plot);
117
118     close_button = new QPushButton (i18n ("Close"), this);
119     connect (close_button, SIGNAL (clicked ()), this, SLOT (closed ()));
120     this->layout()->addWidget(close_button);
121
122     timer = new QTimer (this);
123     connect (timer, SIGNAL (timeout ()), this, SLOT (timer_doit ()));
124
125     reconfig ();
126
127     switch (plot->get_chart_type ())
128     {
129         case Plot::ChartSep:
130             resize (320, 280);
131             break;
132
133         case Plot::ChartSum:
134             resize (320, 240);
135             break;
136     }
137 }
138
139
140 DatarateviewDlg::~DatarateviewDlg ()
141 {
142     debug(3, "");
143
144     emit deleted ();
145 }
146
147
148 void
149 DatarateviewDlg::reconfig ()
150 {
151     QString tmp = myconfig->readString ("Datarate", "chart-type", "separate");
152     Plot::ChartType chart_type = tmp == "separate" ? Plot::ChartSep :
153         Plot::ChartSum;
154
155     switch (chart_type)
156     {
157         case Plot::ChartSep:
158             plot->setMinimumSize (200, 160);
159             break;
160
161         case Plot::ChartSum:
162             plot->setMinimumSize (200, 100);
163             break;
164     }
165
166     plot->set_chart_type (chart_type);
167
168     update_interval = myconfig->readNum ("Datarate", "update-interval", 1);
169     if (update_interval < 1)
170         update_interval = 1;
171     timer->start (1000 * update_interval);
172
173     plot->repaint (FALSE);
174 }
175
176
177 void
178 DatarateviewDlg::reset ()
179 {
180     Data::reset ();
181
182     calc_rate ();
183
184     rate_rx->setText (format_bytes (rate.rx, 0));
185     rate_tx->setText (format_bytes (rate.tx, 1));
186
187     plot->repaint (FALSE);
188 }
189
190
191 void
192 DatarateviewDlg::closed ()
193 {
194     delete this;
195 }
196
197
198 void
199 DatarateviewDlg::closeEvent (QCloseEvent* event)
200 {
201     event->ignore ();
202     delete this;
203 }
204
205
206 void
207 DatarateviewDlg::timer_doit ()
208 {
209     debug(3, "");
210
211     calc_rate ();
212     shrink_history (plot->width () - 2);
213
214     rate_rx->setText (format_bytes (rate.rx, 0));
215     rate_tx->setText (format_bytes (rate.tx, 1));
216
217     plot->repaint (FALSE);
218 }
219
220
221 Data::Data ()
222 {
223     reset ();
224 }
225
226
227 void
228 Data::reset ()
229 {
230     startup = true;
231
232     bytes.rx = bytes.tx = 0;
233     last_bytes = bytes;
234
235     rate.rx = rate.tx = 0;
236
237     rates.clear ();
238     max_rate = 0;
239 }
240
241
242 void
243 Data::set_rxtx_bytes (bytes_t rx_bytes, bytes_t tx_bytes)
244 {
245     bytes.rx = rx_bytes;
246     bytes.tx = tx_bytes;
247
248     if (startup)
249     {
250         last_bytes = bytes;
251         startup = false;
252     }
253 }
254
255
256 void
257 Data::calc_rate ()
258 {
259     if (!startup)
260     {
261         if (bytes.rx > last_bytes.rx)
262             rate.rx = (bytes_t)((bytes.rx - last_bytes.rx) / (update_interval));
263         else
264             rate.rx = 0;
265
266         if (bytes.tx > last_bytes.tx)
267             rate.tx = (bytes_t)((bytes.tx - last_bytes.tx) / (update_interval));
268         else
269             rate.tx = 0;
270     }
271
272 #ifndef NDEBUG
273 #  if 0
274     rate.rx = random () % 10000;
275     rate.tx = random () % 10000;
276 #  endif
277 #  if 0
278     static double t = 1000.0;
279     rate.rx = rate.tx = (bytes_t)(t);
280     t *= 1.01;
281 #  endif
282 #endif
283
284     last_bytes = bytes;
285
286     debug(3, "total: %llu %llu\nrate: %llu %llu\n", bytes.rx, bytes.tx,rate.rx, rate.tx);
287
288     rates.append (rate);
289 }
290
291
292 void
293 Data::shrink_history (unsigned int max_length)
294 {
295     while (static_cast<uint>( rates.count () ) > max_length)
296         rates.pop_front ();
297 }
298
299
300 Plot::Plot (QWidget* parent, const char* name)
301     : QWidget (parent, name)
302 {
303     painter = new QPainter ();
304 }
305
306
307 Plot::~Plot ()
308 {
309     debug(3, "");
310
311     if (painter)
312         delete painter;
313 }
314
315
316 QSizePolicy
317 Plot::sizePolicy () const
318 {
319     return QSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding);
320 }
321
322
323 Data::bytes_t
324 Plot::calc_separation (Data::bytes_t max_rate) const
325 {
326     Data::bytes_t x = max_rate;
327
328     x |= 2048;
329
330     x |= x >> 1;
331     x |= x >> 2;
332     x |= x >> 4;
333     x |= x >> 8;
334     x |= x >> 16;
335     x |= x >> 32;
336
337     x = x ^ (x >> 1);
338
339     return x >> ((x == max_rate) ? 2 : 1);
340 }
341
342
343 Data::bytes_t
344 Plot::f (What what, int i) const
345 {
346     switch (what)
347     {
348         case RX:
349             return data->rates[i].rx;
350         case TX:
351             return data->rates[i].tx;
352         case SUM:
353             return data->rates[i].rx + data->rates[i].tx;
354     }
355
356     return 0;
357 }
358
359
360 void
361 Plot::draw_pixmap (QPixmap* pix, What what) const
362 {
363     const int w = pix->width ();
364     const int h = pix->height ();
365
366     QPainter p (pix);
367
368     p.setBackgroundColor (Qt::white);
369     p.eraseRect (0, 0, w, h);
370
371     Data::bytes_t max_rate = 5000;
372     for (int i = 0; i < data->rates.count (); i++) {
373         Data::bytes_t t = f (what, i);
374         if (max_rate < t) max_rate = t;
375     }
376
377     switch (what)
378     {
379         case RX:
380             p.setPen (QColor (110, 225, 110));
381             break;
382         case TX:
383             p.setPen (QColor (255, 150, 150));
384             break;
385         case SUM:
386             p.setPen (QColor (200, 200, 0));
387             break;
388     }
389
390     double c = (double)(h - 11) / (double)(max_rate);
391     for (int i = 0; i < data->rates.count (); i++) {
392         int r = (int) (f (what, i) * c);
393         p.drawLine (i, h - 1, i, h - r);
394     }
395
396     Data::bytes_t separation = calc_separation (max_rate);
397     for (Data::bytes_t ry = separation; ry < max_rate; ry += separation)
398     {
399         int sy = (int) (ry * c);
400
401         p.setPen (Qt::black);
402         p.drawText (3, h - sy - 1, format_bytes (ry, 2));
403
404         p.setPen (Qt::DotLine);
405         p.drawLine (0, h - sy, w - 1, h - sy);
406     }
407
408     p.end ();
409 }
410
411
412 void
413 Plot::paintEvent (QPaintEvent* pevent)
414 {
415     debug(3, "");
416
417     if(!painter->begin(this)) {
418         qWarning("painting failed\n");
419     }
420
421     const int w = width ();
422     const int h = height ();
423
424     painter->setClipRect (pevent->rect ());
425
426     data->shrink_history (w - 2);
427
428     switch (chart_type)
429     {
430         case ChartSep: {
431             painter->setPen (Qt::black);
432             painter->drawRect (0, 0, w, h/2 + 1);
433             painter->drawRect (0, h/2 - 1 + 1, w, h - h/2);
434
435             QPixmap pix1 (w - 2, h/2 - 1);
436             draw_pixmap (&pix1, Plot::RX);
437             painter->drawPixmap (1, 1, pix1);
438
439             QPixmap pix2 (w - 2, h - h/2 - 2);
440             draw_pixmap (&pix2, Plot::TX);
441             painter->drawPixmap (1, h/2 + 1, pix2);
442         } break;
443
444         case ChartSum: {
445             painter->setPen (Qt::black);
446             painter->drawRect (0, 0, w, h);
447
448             QPixmap pix (w - 2, h - 2);
449             draw_pixmap (&pix, Plot::SUM);
450             painter->drawPixmap (1, 1, pix);
451         } break;
452     }
453     painter->end();
454 }
455
456
457 #include "datarateview.moc"