1 | /* |
2 | * kPPP: A pppd front end for the KDE project |
3 | * |
4 | * $Id$ |
5 | * |
6 | * Copyright (C) 1997 Bernd Johannes Wuebben |
7 | * wuebben@math.cornell.edu |
8 | * |
9 | * |
10 | * This program is free software; you can redistribute it and/or |
11 | * modify it under the terms of the GNU Library General Public |
12 | * License as published by the Free Software Foundation; either |
13 | * version 2 of the License, or (at your option) any later version. |
14 | * |
15 | * This program is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
18 | * Library General Public License for more details. |
19 | * |
20 | * You should have received a copy of the GNU Library General Public |
21 | * License along with this program; if not, write to the Free |
22 | * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
23 | */ |
24 | |
25 | |
26 | #include <qlayout.h> |
27 | #include <qpainter.h> |
28 | #include <kguiitem.h> |
29 | //Added by qt3to4: |
30 | #include <QPixmap> |
31 | #include <QGridLayout> |
32 | #include <QCloseEvent> |
33 | #include <QEvent> |
34 | #include <QHBoxLayout> |
35 | #include <QVBoxLayout> |
36 | #include <QApplication> |
37 | #include <kwindowsystem.h> |
38 | #include <kiconloader.h> |
39 | #include <klocale.h> |
40 | #include <qlabel.h> |
41 | #include <q3frame.h> |
42 | #include <q3groupbox.h> |
43 | #include <qlineedit.h> |
44 | #include <qtimer.h> |
45 | #include <kpushbutton.h> |
46 | #include <KStandardGuiItem> |
47 | |
48 | #include "pppdata.h" |
49 | #include "pppstatdlg.h" |
50 | #include "iplined.h" |
51 | #include "pppstats.h" |
52 | |
53 | extern PPPData gpppdata; |
54 | |
55 | PPPStatsDlg::PPPStatsDlg(QWidget *parent, const char *name, QWidget *, |
56 | PPPStats *st) |
57 | : QWidget(parent), |
58 | stats(st) |
59 | { |
60 | int i; |
61 | max = 1024; |
62 | |
63 | setObjectName(name); |
64 | |
65 | setWindowTitle(i18n("kppp Statistics" )); |
66 | KWindowSystem::setIcons(winId(), qApp->windowIcon().pixmap(IconSize(KIconLoader::Desktop),IconSize(KIconLoader::Desktop)), qApp->windowIcon().pixmap(IconSize(KIconLoader::Small),IconSize(KIconLoader::Small))); |
67 | |
68 | QVBoxLayout *tl = new QVBoxLayout(this); |
69 | tl->setSpacing(10); |
70 | QGridLayout *l1 = new QGridLayout(); |
71 | tl->addLayout(l1, 1); |
72 | box = new Q3GroupBox(i18n("Statistics" ), this); |
73 | l1->addWidget(box, 0, 0, 4, 4); |
74 | l1->addItem(new QSpacerItem(0, fontMetrics().lineSpacing() - 10), 0, 0); |
75 | l1->setRowStretch(1, 1); |
76 | l1->setColumnStretch(1, 1); |
77 | |
78 | // inner part of the grid |
79 | QVBoxLayout *l11 = new QVBoxLayout; |
80 | l1->addLayout(l11, 1, 1); |
81 | |
82 | // modem pixmap and IP labels |
83 | QHBoxLayout *l111 = new QHBoxLayout; |
84 | l11->addLayout(l111); |
85 | |
86 | big_modem_both_pixmap = UserIcon("modemboth" ); |
87 | big_modem_left_pixmap = UserIcon("modemleft" ); |
88 | big_modem_right_pixmap = UserIcon("modemright" ); |
89 | big_modem_none_pixmap = UserIcon("modemnone" ); |
90 | |
91 | pixmap_l = new QLabel(this); |
92 | pixmap_l->setMinimumSize(big_modem_both_pixmap.size()); |
93 | l111->addWidget(pixmap_l, 1); |
94 | pixmap_l->setAlignment(Qt::AlignVCenter|Qt::AlignLeft); |
95 | |
96 | QGridLayout *l1112 = new QGridLayout(); |
97 | l111->addLayout(l1112); |
98 | |
99 | ip_address_label1 = new QLabel(this); |
100 | ip_address_label1->setText(i18n("Local Addr:" )); |
101 | |
102 | ip_address_label2 = new IPLineEdit(this); |
103 | ip_address_label2->setFocusPolicy(Qt::NoFocus); |
104 | |
105 | ip_address_label3 = new QLabel(this); |
106 | ip_address_label3->setText(i18n("Remote Addr:" )); |
107 | |
108 | ip_address_label4 = new IPLineEdit(this); |
109 | ip_address_label4->setFocusPolicy(Qt::NoFocus); |
110 | |
111 | l1112->addWidget(ip_address_label1, 0, 0); |
112 | l1112->addWidget(ip_address_label2, 0, 1); |
113 | l1112->addWidget(ip_address_label3, 1, 0); |
114 | l1112->addWidget(ip_address_label4, 1, 1); |
115 | |
116 | // consumes space on bottom |
117 | l1112->setRowStretch(2, 1); |
118 | |
119 | QGridLayout *l112 = new QGridLayout(); |
120 | l11->addLayout(l112); |
121 | for(i =0 ; i < 5; i++) { |
122 | labela1[i] = new QLabel(this); |
123 | |
124 | labela2[i] = new QLabel(this); |
125 | labela2[i]->setFrameStyle(QFrame::WinPanel | QFrame::Sunken); |
126 | |
127 | labelb1[i] = new QLabel(this); |
128 | |
129 | labelb2[i] = new QLabel(this); |
130 | labelb2[i]->setFrameStyle(QFrame::WinPanel | QFrame::Sunken); |
131 | } |
132 | |
133 | labela1[0]->setText(i18n("bytes in" )); |
134 | labelb1[0]->setText(i18n("bytes out" )); |
135 | |
136 | labela1[1]->setText(i18n("packets in" )); |
137 | labelb1[1]->setText(i18n("packets out" )); |
138 | |
139 | labela1[2]->setText(i18n("vjcomp in" )); |
140 | labelb1[2]->setText(i18n("vjcomp out" )); |
141 | |
142 | labela1[3]->setText(i18n("vjunc in" )); |
143 | labelb1[3]->setText(i18n("vjunc out" )); |
144 | |
145 | labela1[4]->setText(i18n("vjerr" )); |
146 | labelb1[4]->setText(i18n("non-vj" )); |
147 | |
148 | for(i = 0; i < 5; i++) { |
149 | labela2[i]->setText("888888888" ); // TODO: resize automatically |
150 | labelb2[i]->setText("888888888" ); |
151 | labela2[i]->setAlignment(Qt::AlignRight); |
152 | labelb2[i]->setAlignment(Qt::AlignRight); |
153 | labela2[i]->setFixedSize(labela2[i]->sizeHint()); |
154 | labelb2[i]->setFixedSize(labelb2[i]->sizeHint()); |
155 | labela2[i]->setText("" ); |
156 | labelb2[i]->setText("" ); |
157 | |
158 | // add to layout |
159 | l112->addWidget(labela1[i], i, 0); |
160 | l112->addWidget(labela2[i], i, 1); |
161 | l112->addWidget(labelb1[i], i, 2); |
162 | l112->addWidget(labelb2[i], i, 3); |
163 | } |
164 | |
165 | l112->setColumnStretch(1, 1); |
166 | l112->setColumnStretch(3, 1); |
167 | |
168 | tl->addSpacing(5); |
169 | QHBoxLayout *l12 = new QHBoxLayout; |
170 | tl->addLayout(l12); |
171 | l12->addStretch(1); |
172 | |
173 | if(gpppdata.graphingEnabled()) { |
174 | bool dummy; |
175 | |
176 | gpppdata.graphingOptions(dummy, bg, text, in, out); |
177 | |
178 | graph = new QLabel(this); |
179 | graph->setFrameStyle(QFrame::Box | QFrame::Sunken); |
180 | l1->addWidget(graph, 2, 1, 1, 2); |
181 | graph->setMinimumWidth(300); |
182 | graph->setFixedHeight(76+4); |
183 | |
184 | QPalette palette; |
185 | palette.setColor(graph->backgroundRole(), bg); |
186 | graph->setPalette(palette); |
187 | } |
188 | |
189 | cancelbutton = new KPushButton(KStandardGuiItem::close(),this); |
190 | cancelbutton->setFocus(); |
191 | connect(cancelbutton, SIGNAL(clicked()), this,SLOT(cancel())); |
192 | cancelbutton->setFixedHeight(cancelbutton->sizeHint().height()); |
193 | cancelbutton->setMinimumWidth(qMax(cancelbutton->sizeHint().width(), 70)); |
194 | l12->addWidget(cancelbutton); |
195 | |
196 | if(gpppdata.graphingEnabled()) { |
197 | graphTimer = new QTimer(this); |
198 | connect(graphTimer, SIGNAL(timeout()), SLOT(updateGraph())); |
199 | } |
200 | |
201 | setFixedSize(sizeHint()); |
202 | |
203 | connect(stats, SIGNAL(statsChanged(int)), SLOT(paintIcon(int))); |
204 | |
205 | // read window position from config file |
206 | int p_x, p_y; |
207 | gpppdata.winPosStatWin(p_x, p_y); |
208 | move(p_x, p_y); |
209 | } |
210 | |
211 | |
212 | PPPStatsDlg::~PPPStatsDlg() { |
213 | } |
214 | |
215 | |
216 | // save window position when window was closed |
217 | bool PPPStatsDlg::event(QEvent *e) { |
218 | if (e->type() == QEvent::Hide) |
219 | { |
220 | gpppdata.setWinPosStatWin(x(), y()); |
221 | return true; |
222 | } |
223 | else |
224 | return QWidget::event(e); |
225 | } |
226 | |
227 | void PPPStatsDlg::cancel() { |
228 | hide(); |
229 | } |
230 | |
231 | |
232 | void PPPStatsDlg::take_stats() { |
233 | stats->initStats(); |
234 | bin_last = stats->ibytes; |
235 | bout_last = stats->obytes; |
236 | ringIdx = 0; |
237 | for(int i = 0; i < MAX_GRAPH_WIDTH; i++) { |
238 | bin[i] = -1; |
239 | bout[i] = -1; |
240 | } |
241 | |
242 | update_data(); |
243 | |
244 | stats->start(); |
245 | if(gpppdata.graphingEnabled()) |
246 | graphTimer->start(GRAPH_UPDATE_TIME); |
247 | } |
248 | |
249 | |
250 | void PPPStatsDlg::stop_stats() { |
251 | stats->stop(); |
252 | if(gpppdata.graphingEnabled()) |
253 | graphTimer->stop(); |
254 | } |
255 | |
256 | void PPPStatsDlg::paintGraph() { |
257 | // why draw that stuff if not visible? |
258 | if(!isVisible()) |
259 | return; |
260 | |
261 | QPixmap pm(graph->width() - 4, graph->height() - 4); |
262 | QPainter p; |
263 | pm.fill(graph->palette().color(graph->backgroundRole())); |
264 | p.begin(&pm); |
265 | |
266 | int x; |
267 | int idx = ringIdx - pm.width() + 1; |
268 | if(idx < 0) |
269 | idx += MAX_GRAPH_WIDTH; |
270 | |
271 | // find good scaling factor |
272 | int last_h_in = |
273 | pm.height() - (int)((float)bin[idx]/max * (pm.height() - 8))-1; |
274 | int last_h_out = |
275 | pm.height() - (int)((float)bout[idx]/max * (pm.height() - 8))-1; |
276 | |
277 | // plot data |
278 | int last_idx = 0; |
279 | for(x = 1; x < pm.width(); x++) { |
280 | int h_in, h_out; |
281 | |
282 | h_in = pm.height() - (int)((float)bin[idx]/max * (pm.height() - 8))-1; |
283 | h_out = pm.height() - (int)((float)bout[idx]/max * (pm.height() - 8))-1; |
284 | |
285 | p.setPen(out); |
286 | if(bout[idx]!=-1) |
287 | p.drawLine(x-1, last_h_out, x, h_out); |
288 | p.setPen(in); |
289 | if(bin[idx]!=-1) |
290 | p.drawLine(x-1, last_h_in, x, h_in); |
291 | last_h_in = h_in; |
292 | last_h_out = h_out; |
293 | |
294 | last_idx = idx; |
295 | idx = (idx + 1) % MAX_GRAPH_WIDTH; |
296 | } |
297 | |
298 | // take last value |
299 | int last_max = bin[last_idx]>bout[last_idx] ? bin[last_idx] : bout[last_idx]; |
300 | |
301 | // plot scale line |
302 | p.setPen(text); |
303 | p.setFont(QFont(KGlobalSettings::fixedFont().family(), 8)); |
304 | |
305 | QRect r; |
306 | QString s = i18n("%1 (max. %2) kb/sec" , |
307 | KGlobal::locale()->formatNumber((float)last_max / 1024.0, 1), |
308 | KGlobal::locale()->formatNumber((float)max / 1024.0, 1)); |
309 | p.drawText(0, 0, pm.width(), 2*8, Qt::AlignRight|Qt::AlignVCenter, s, &r); |
310 | p.drawLine(0, 8, r.left() - 8, 8); |
311 | |
312 | p.end(); |
313 | graph->setPixmap(pm); |
314 | } |
315 | |
316 | void PPPStatsDlg::updateGraph() { |
317 | bin[ringIdx] = stats->ibytes - bin_last; |
318 | bout[ringIdx] = stats->obytes - bout_last; |
319 | if(bin[ringIdx] > max) |
320 | max = ((bin[ringIdx] / 1024) + 1) * 1024; |
321 | |
322 | if(bout[ringIdx] > max) |
323 | max = ((bout[ringIdx] / 1024) + 1) * 1024; |
324 | |
325 | bin_last = stats->ibytes; |
326 | bout_last = stats->obytes; |
327 | ringIdx = (ringIdx + 1) % MAX_GRAPH_WIDTH; |
328 | paintGraph(); |
329 | } |
330 | |
331 | void PPPStatsDlg::paintIcon(int status) { |
332 | const QPixmap *pixmap; |
333 | |
334 | switch(status) |
335 | { |
336 | case PPPStats::BytesIn: |
337 | pixmap = &big_modem_left_pixmap; |
338 | break; |
339 | case PPPStats::BytesOut: |
340 | pixmap = &big_modem_right_pixmap; |
341 | break; |
342 | case PPPStats::BytesBoth: |
343 | pixmap = &big_modem_both_pixmap; |
344 | break; |
345 | case PPPStats::BytesNone: |
346 | default: |
347 | pixmap = &big_modem_none_pixmap; |
348 | break; |
349 | } |
350 | |
351 | pixmap_l->setPixmap(*pixmap); |
352 | |
353 | update_data(); |
354 | } |
355 | |
356 | |
357 | void PPPStatsDlg::timeclick() { |
358 | // volume accounting |
359 | switch(gpppdata.VolAcctEnabled()) { |
360 | case 0: // no accounting |
361 | break; |
362 | |
363 | case 1: // bytes in |
364 | stats->totalbytes = gpppdata.totalBytes() + stats->ibytes; |
365 | break; |
366 | |
367 | case 2: |
368 | stats->totalbytes = gpppdata.totalBytes() + stats->obytes; |
369 | break; |
370 | |
371 | case 3: |
372 | stats->totalbytes = gpppdata.totalBytes() + stats->ibytes + stats->obytes; |
373 | break; |
374 | } |
375 | } |
376 | |
377 | |
378 | void PPPStatsDlg::closeEvent(QCloseEvent *) { |
379 | emit cancel(); |
380 | } |
381 | |
382 | |
383 | void PPPStatsDlg::update_data() { |
384 | timeclick(); |
385 | |
386 | ibytes_string = KGlobal::locale()->formatNumber(stats->ibytes, 0); |
387 | ipackets_string.setNum(stats->ipackets); |
388 | compressedin_string.setNum(stats->compressedin); |
389 | uncompressedin_string.setNum(stats->uncompressedin); |
390 | errorin_string.setNum(stats->errorin); |
391 | obytes_string = KGlobal::locale()->formatNumber(stats->obytes, 0); |
392 | opackets_string.setNum(stats->opackets); |
393 | compressed_string.setNum(stats->compressed); |
394 | packetsunc_string.setNum(stats->packetsunc); |
395 | packetsoutunc_string.setNum(stats->packetsoutunc); |
396 | |
397 | labela2[0]->setText(ibytes_string); |
398 | labela2[1]->setText(ipackets_string); |
399 | labela2[2]->setText(compressedin_string); |
400 | labela2[3]->setText(uncompressedin_string); |
401 | labela2[4]->setText(errorin_string); |
402 | |
403 | labelb2[0]->setText(obytes_string); |
404 | labelb2[1]->setText(opackets_string); |
405 | labelb2[2]->setText(compressed_string); |
406 | labelb2[3]->setText(packetsunc_string); |
407 | labelb2[4]->setText(packetsoutunc_string); |
408 | |
409 | // if I don't resort to this trick it is imposible to |
410 | // copy/paste the ip out of the lineedits due to |
411 | // reset of cursor position on setText() |
412 | QString local_addr = ( stats->local_ip_address.isEmpty() ? |
413 | i18n("unavailable" ) : |
414 | stats->local_ip_address ); |
415 | |
416 | if( ip_address_label2->text() != local_addr ) |
417 | ip_address_label2->setText(local_addr); |
418 | |
419 | QString remote_addr = ( stats->remote_ip_address.isEmpty() ? |
420 | i18n("unavailable" ) : |
421 | stats->remote_ip_address ); |
422 | |
423 | if( ip_address_label4->text() != remote_addr ) |
424 | ip_address_label4->setText(remote_addr); |
425 | } |
426 | |
427 | |
428 | void PPPStatsDlg::toCurrentDesktop() { |
429 | KWindowSystem::setOnDesktop(winId(), KWindowSystem::currentDesktop()); |
430 | } |
431 | |
432 | #include "pppstatdlg.moc" |
433 | |
434 | |