1 | /* |
2 | * kPPP: A pppd front end for the KDE project |
3 | * |
4 | * |
5 | * Copyright (C) 1997 Bernd Johannes Wuebben |
6 | * wuebben@math.cornell.edu |
7 | * |
8 | * Copyright (C) 1998-2002 Harri Porten <porten@kde.org> |
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 | #include "kpppwidget.h" |
26 | #include <qapplication.h> |
27 | #include <qcombobox.h> |
28 | #include <qdir.h> |
29 | #include <qevent.h> |
30 | #include <qdialog.h> |
31 | #include <qlabel.h> |
32 | #include <qpushbutton.h> |
33 | #include <qregexp.h> |
34 | //Added by qt3to4: |
35 | #include <QGridLayout> |
36 | #include <QKeyEvent> |
37 | #include <QHBoxLayout> |
38 | #include <QVBoxLayout> |
39 | #include <kpagedialog.h> |
40 | |
41 | #include <QMenu> |
42 | #include <kaboutdata.h> |
43 | #include <kglobalsettings.h> |
44 | #include <kcmdlineargs.h> |
45 | #include <kconfig.h> |
46 | #include <kdebug.h> |
47 | #include <kiconloader.h> // For BarIcon |
48 | #include <klocale.h> |
49 | #include <kmessagebox.h> |
50 | #include <kseparator.h> |
51 | #include <kstandarddirs.h> |
52 | #include <kapplication.h> |
53 | #include <kwindowsystem.h> |
54 | #include <khelpmenu.h> |
55 | #include <kpushbutton.h> |
56 | #include <kguiitem.h> |
57 | #include <KStandardGuiItem> |
58 | |
59 | #include <stdlib.h> |
60 | #include <errno.h> |
61 | #include <ktoolinvocation.h> |
62 | |
63 | #include "runtests.h" |
64 | |
65 | #include "main.h" |
66 | #include "auth.h" |
67 | #include "modem.h" |
68 | #include "ppplog.h" |
69 | #include "opener.h" |
70 | #include "requester.h" |
71 | #include "pppstats.h" |
72 | #include "pppdata.h" |
73 | #include "general.h" |
74 | #include "modems.h" |
75 | |
76 | #include "kpppadaptor.h" |
77 | |
78 | // delay disconnection for a second |
79 | #define DISCONNECT_DELAY 1000 |
80 | |
81 | extern KPPPWidget *p_kppp; |
82 | |
83 | KPPPWidget::KPPPWidget( QWidget *parent, const char *name ) |
84 | : QWidget(parent) |
85 | , acct(0) |
86 | , m_bCmdlAccount (false) |
87 | , m_bCmdlModem (false) |
88 | { |
89 | KpppAdaptor *kpppAdaptor = new KpppAdaptor(this); |
90 | QDBusConnection::sessionBus().registerObject("/Kppp" , this); |
91 | |
92 | setObjectName( name ); |
93 | |
94 | connect( this, SIGNAL(sig_aboutToConnect()), kpppAdaptor, SIGNAL(aboutToConnect()) ); |
95 | connect( this, SIGNAL(sig_aboutToDisconnect()), kpppAdaptor, SIGNAL(aboutToDisconnect()) ); |
96 | connect( this, SIGNAL(sig_connected()), kpppAdaptor, SIGNAL(connected()) ); |
97 | connect( this, SIGNAL(sig_disconnected()), kpppAdaptor, SIGNAL(disconnected()) ); |
98 | |
99 | |
100 | tabWindow = 0; |
101 | |
102 | // before doing anything else, run a few tests |
103 | |
104 | int result = runTests(); |
105 | if(result == TEST_CRITICAL) |
106 | exit(4); |
107 | |
108 | installEventFilter(this); |
109 | |
110 | QVBoxLayout *tl = new QVBoxLayout(this); |
111 | tl->setSpacing(10); |
112 | tl->setMargin(10); |
113 | |
114 | l1 = new QGridLayout(); |
115 | tl->addLayout(l1); |
116 | l1->addItem(new QSpacerItem(10, 0), 0, 0); |
117 | l1->addItem(new QSpacerItem(10, 0), 0, 3); |
118 | l1->setColumnStretch(1, 3); |
119 | l1->setColumnStretch(2, 4); |
120 | |
121 | label1 = new QLabel(i18n("C&onnect to: " ), this); |
122 | l1->addWidget(label1, 0, 1); |
123 | |
124 | connectto_c = new QComboBox(this); |
125 | connectto_c->setEditable( false ); |
126 | label1->setBuddy(connectto_c); |
127 | |
128 | connect(connectto_c, SIGNAL(activated(int)), |
129 | SLOT(newdefaultaccount(int))); |
130 | l1->addWidget(connectto_c, 0, 2); |
131 | |
132 | label7 = new QLabel(i18n("Use &modem: " ), this); |
133 | // l1->addWidget(label7, 1, 1); (done in resetmodems()) |
134 | modem_c = new QComboBox(this); |
135 | modem_c->setEditable( false ); |
136 | label7->setBuddy(connectto_c); |
137 | m_bModemCShown = false; |
138 | |
139 | connect(modem_c, SIGNAL(activated(int)), |
140 | SLOT(newdefaultmodem(int))); |
141 | // l1->addWidget(modem_c, 1, 2); (done in resetmodems()) |
142 | |
143 | ID_Label = new QLabel(i18n("&Login ID:" ), this); |
144 | l1->addWidget(ID_Label, 2, 1); |
145 | |
146 | // the entry line for usernames |
147 | ID_Edit = new QLineEdit(this); |
148 | ID_Label->setBuddy(ID_Edit); |
149 | l1->addWidget(ID_Edit, 2, 2); |
150 | connect(ID_Edit, SIGNAL(returnPressed()), |
151 | this, SLOT(enterPressedInID())); |
152 | QString tmp = i18n("<p>Type in the username that you got from your\n" |
153 | "ISP. This is especially important for PAP\n" |
154 | "and CHAP. You may omit this when you use\n" |
155 | "terminal-based or script-based authentication.\n" |
156 | "\n" |
157 | "<b>Important</b>: case is important here:\n" |
158 | "<i>myusername</i> is not the same as <i>MyUserName</i>." ); |
159 | |
160 | ID_Label->setWhatsThis(tmp); |
161 | ID_Edit->setWhatsThis(tmp); |
162 | |
163 | PW_Label = new QLabel(i18n("&Password:" ), this); |
164 | l1->addWidget(PW_Label, 3, 1); |
165 | |
166 | PW_Edit= new QLineEdit(this); |
167 | PW_Label->setBuddy(PW_Edit); |
168 | PW_Edit->setEchoMode(QLineEdit::Password); |
169 | l1->addWidget(PW_Edit, 3, 2); |
170 | connect(PW_Edit, SIGNAL(returnPressed()), |
171 | this, SLOT(enterPressedInPW())); |
172 | |
173 | tmp = i18n("<p>Type in the password that you got from your\n" |
174 | "ISP. This is especially important for PAP\n" |
175 | "and CHAP. You may omit this when you use\n" |
176 | "terminal-based or script-based authentication.\n" |
177 | "\n" |
178 | "<b>Important</b>: case is important here:\n" |
179 | "<i>mypassword</i> is not the same as <i>MyPassword</i>." ); |
180 | |
181 | PW_Label->setWhatsThis(tmp); |
182 | PW_Edit->setWhatsThis(tmp); |
183 | |
184 | QHBoxLayout *l3 = new QHBoxLayout; |
185 | tl->addSpacing(5); |
186 | tl->addLayout(l3); |
187 | tl->addSpacing(5); |
188 | l3->addSpacing(10); |
189 | log = new QCheckBox(i18n("Show lo&g window" ), this); |
190 | connect(log, SIGNAL(toggled(bool)), |
191 | this, SLOT(log_window_toggled(bool))); |
192 | log->setChecked(gpppdata.get_show_log_window()); |
193 | l3->addWidget(log); |
194 | |
195 | log->setWhatsThis( |
196 | i18n("<p>This controls whether a log window is shown.\n" |
197 | "A log window shows the communication between\n" |
198 | "<i>kppp</i> and your modem. This will help you\n" |
199 | "in tracking down problems.\n" |
200 | "\n" |
201 | "Turn it off if <i>kppp</i> routinely connects without\n" |
202 | "problems" )); |
203 | |
204 | fline = new KSeparator( Qt::Horizontal, this); |
205 | tl->addWidget(fline); |
206 | |
207 | QHBoxLayout *l2 = new QHBoxLayout; |
208 | tl->addLayout(l2); |
209 | |
210 | int minw = 0; |
211 | quit_b = new KPushButton(KStandardGuiItem::quit(), this); |
212 | connect( quit_b, SIGNAL(clicked()), SLOT(quitbutton())); |
213 | if(quit_b->sizeHint().width() > minw) |
214 | minw = quit_b->sizeHint().width(); |
215 | |
216 | setup_b = new KPushButton(KGuiItem(i18n("Co&nfigure..." ), "configure" ), this); |
217 | connect( setup_b, SIGNAL(clicked()), SLOT(expandbutton())); |
218 | if(setup_b->sizeHint().width() > minw) |
219 | minw = setup_b->sizeHint().width(); |
220 | |
221 | if(gpppdata.access() != KConfig::ReadWrite) |
222 | setup_b->setEnabled(false); |
223 | |
224 | help_b = new KPushButton(KStandardGuiItem::help(), this); |
225 | connect( help_b, SIGNAL(clicked()), SLOT(helpbutton())); |
226 | |
227 | KHelpMenu * = new KHelpMenu(this, KGlobal::mainComponent().aboutData(), true); |
228 | help_b->setMenu((QMenu*)helpMenu->menu()); |
229 | if(help_b->sizeHint().width() > minw) |
230 | minw = help_b->sizeHint().width(); |
231 | |
232 | connect_b = new QPushButton(i18n("&Connect" ), this); |
233 | connect_b->setDefault(true); |
234 | connect_b->setFocus(); |
235 | connect(connect_b, SIGNAL(clicked()), SLOT(beginConnect())); |
236 | if(connect_b->sizeHint().width() > minw) |
237 | minw = connect_b->sizeHint().width(); |
238 | |
239 | quit_b->setFixedWidth(minw); |
240 | setup_b->setFixedWidth(minw); |
241 | help_b->setFixedWidth(help_b->sizeHint().width()); |
242 | connect_b->setFixedWidth(minw); |
243 | |
244 | l2->addWidget(quit_b); |
245 | l2->addWidget(setup_b); |
246 | l2->addWidget(help_b); |
247 | l2->addSpacing(20); |
248 | l2->addWidget(connect_b); |
249 | |
250 | setFixedSize(sizeHint()); |
251 | |
252 | (void)new Modem; |
253 | |
254 | // we also connect cmld_start to the beginConnect so that I can run |
255 | // the dialer through a command line argument |
256 | connect(this,SIGNAL(cmdl_start()),this,SLOT(beginConnect())); |
257 | |
258 | stats = new PPPStats; |
259 | |
260 | KWindowSystem::setIcons(winId(), qApp->windowIcon().pixmap(IconSize(KIconLoader::Desktop),IconSize(KIconLoader::Desktop)), qApp->windowIcon().pixmap(IconSize(KIconLoader::Small),IconSize(KIconLoader::Small))); |
261 | |
262 | // constructor of con_win reads position from config file |
263 | con_win = new ConWindow(0, "conw" , this, stats); |
264 | KWindowSystem::setIcons(con_win->winId(), qApp->windowIcon().pixmap(IconSize(KIconLoader::Desktop),IconSize(KIconLoader::Desktop)), qApp->windowIcon().pixmap(IconSize(KIconLoader::Small),IconSize(KIconLoader::Small))); |
265 | |
266 | statdlg = new PPPStatsDlg(0, "stats" , this, stats); |
267 | statdlg->hide(); |
268 | |
269 | debugwindow = new DebugWidget(0); |
270 | debugwindow->setObjectName( "debugwindow" ); |
271 | KWindowSystem::setIcons(debugwindow->winId(), qApp->windowIcon().pixmap(IconSize(KIconLoader::Desktop),IconSize(KIconLoader::Desktop)), qApp->windowIcon().pixmap(IconSize(KIconLoader::Small),IconSize(KIconLoader::Small))); |
272 | |
273 | // load up the accounts combo box |
274 | |
275 | resetaccounts(); |
276 | resetmodems(); |
277 | con = new ConnectWidget(0, "con" , stats); |
278 | KWindowSystem::setIcons(con->winId(), qApp->windowIcon().pixmap(IconSize(KIconLoader::Desktop),IconSize(KIconLoader::Desktop)), qApp->windowIcon().pixmap(IconSize(KIconLoader::Small),IconSize(KIconLoader::Small)) ); |
279 | connect(this, SIGNAL(begin_connect()),con, SLOT(preinit())); |
280 | |
281 | QRect desk = KGlobalSettings::desktopGeometry(topLevelWidget()); |
282 | con->setGeometry(desk.center().x()-175, desk.center().y()-55, 350,110); |
283 | |
284 | // connect the ConnectWidgets various signals |
285 | connect(con, SIGNAL(closeDebugWindow()), |
286 | debugwindow, SLOT(hide())); |
287 | connect(con, SIGNAL(debugMessage(QString)), |
288 | debugwindow, SLOT(statusLabel(QString))); |
289 | connect(con, SIGNAL(toggleDebugWindow()), |
290 | debugwindow, SLOT(toggleVisibility())); |
291 | connect(con, SIGNAL(debugPutChar(unsigned char)), |
292 | debugwindow, SLOT(addChar(unsigned char))); |
293 | connect(con, SIGNAL(startAccounting()), |
294 | this, SLOT(startAccounting())); |
295 | connect(con, SIGNAL(stopAccounting()), |
296 | this, SLOT(stopAccounting())); |
297 | connect(KApplication::kApplication(), SIGNAL(saveYourself()), |
298 | this, SLOT(saveMyself())); |
299 | connect(KApplication::kApplication(), SIGNAL(aboutToQuit()), |
300 | this, SLOT(shutDown())); |
301 | connect(con, SIGNAL(aboutToConnect()), this, SIGNAL(sig_aboutToConnect())); |
302 | connect(con, SIGNAL(connected()), this, SIGNAL(sig_connected())); |
303 | |
304 | debugwindow->setGeometry(desk.center().x()+190, desk.center().y()-55, |
305 | debugwindow->width(),debugwindow->height()); |
306 | |
307 | move(desk.center().x()-width()/2, desk.center().y()-height()/2); |
308 | |
309 | |
310 | KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); |
311 | |
312 | m_strCmdlAccount = args->getOption("c" ); |
313 | m_strCmdlModem = args->getOption("m" ); |
314 | m_bQuitOnDisconnect = args->isSet("q" ); |
315 | |
316 | if(!m_strCmdlAccount.isEmpty()) { |
317 | m_bCmdlAccount = true; |
318 | kDebug(5002) << "cmdl_account: " << m_bCmdlAccount; |
319 | } |
320 | |
321 | if(!m_strCmdlModem.isEmpty()) { |
322 | m_bCmdlModem = true; |
323 | kDebug(5002) << "cmdl_modem: " << m_bCmdlModem; |
324 | } |
325 | |
326 | if(m_bCmdlModem){ |
327 | bool result = gpppdata.setModem(m_strCmdlModem); |
328 | if (!result){ |
329 | QString string; |
330 | string = i18n("No such Modem:\n%1\nFalling back to default" , m_strCmdlModem); |
331 | KMessageBox::error(this, string); |
332 | m_bCmdlModem = false; |
333 | } |
334 | } |
335 | |
336 | if(m_bCmdlAccount){ |
337 | bool result = gpppdata.setAccount(m_strCmdlAccount); |
338 | if (!result){ |
339 | QString string; |
340 | string = i18n("No such Account:\n%1" , m_strCmdlAccount); |
341 | KMessageBox::error(this, string); |
342 | m_bCmdlAccount = false; |
343 | show(); |
344 | } else { |
345 | beginConnect(); |
346 | } |
347 | } else |
348 | show(); |
349 | |
350 | |
351 | //#define KPPP_SHOW_NEWS |
352 | #ifdef KPPP_SHOW_NEWS |
353 | // keep user informed about recent changes |
354 | if(!m_bCmdlAccount) |
355 | showNews(); |
356 | #endif |
357 | // this timer will delay the actual disconnection DISCONNECTION_DELAY ms |
358 | // to give applications time to shutdown, logout, whatever.. |
359 | disconnectTimer = new QTimer(this); |
360 | connect(disconnectTimer, SIGNAL(timeout()), this, SLOT(delayedDisconnect())); |
361 | } |
362 | |
363 | KPPPWidget::~KPPPWidget() |
364 | { |
365 | delete stats; |
366 | } |
367 | |
368 | bool KPPPWidget::eventFilter(QObject *o, QEvent *e) { |
369 | if(e->type() == QEvent::User) { |
370 | switch(((SignalEvent*)e)->sigType()) { |
371 | case SIGINT: |
372 | kDebug(5002) << "Received a SIGINT" ; |
373 | interruptConnection(); |
374 | break; |
375 | case SIGCHLD: |
376 | sigChld(); |
377 | break; |
378 | case SIGUSR1: |
379 | sigPPPDDied(); |
380 | break; |
381 | } |
382 | return true; |
383 | } |
384 | |
385 | if(o == connect_b) { |
386 | if(e->type() == QEvent::KeyPress) { |
387 | if(connect_b->hasFocus() && ((QKeyEvent *)e)->key() == Qt::Key_Return) { |
388 | beginConnect(); |
389 | return true; |
390 | } |
391 | } |
392 | } |
393 | |
394 | return false; |
395 | } |
396 | |
397 | void KPPPWidget::prepareSetupDialog() { |
398 | if(tabWindow == 0) { |
399 | tabWindow = new KPageDialog( this ); |
400 | tabWindow->setCaption( i18n("KPPP Configuration" ) ); |
401 | tabWindow->setButtons( KDialog::Ok|KDialog::Cancel ); |
402 | tabWindow->setDefaultButton( KDialog::Ok ); |
403 | tabWindow->setFaceType( KPageDialog::Tabbed ); |
404 | tabWindow->setModal( true ); |
405 | |
406 | KWindowSystem::setIcons(tabWindow->winId(), qApp->windowIcon().pixmap(IconSize(KIconLoader::Desktop),IconSize(KIconLoader::Desktop)), qApp->windowIcon().pixmap(IconSize(KIconLoader::Small),IconSize(KIconLoader::Small))); |
407 | |
408 | // tabWindow->setFixedSize( 365, 375 ); |
409 | QFrame *frame = new QFrame(); |
410 | KPageWidgetItem *pageItem = new KPageWidgetItem( frame, i18n("&Accounts" ) ); |
411 | pageItem->setHeader( i18n("Account Setup" ) ); |
412 | tabWindow->addPage( pageItem ); |
413 | accounts = new AccountWidget(frame); |
414 | connect(accounts, SIGNAL(resetaccounts()), |
415 | this, SLOT(resetaccounts())); |
416 | connect(accounts, SIGNAL(resetCosts(QString)), |
417 | this, SLOT(resetCosts(QString))); |
418 | connect(accounts, SIGNAL(resetVolume(QString)), |
419 | this, SLOT(resetVolume(QString))); |
420 | |
421 | |
422 | frame = new QFrame(); |
423 | pageItem = new KPageWidgetItem( frame, i18n("&Modems" ) ); |
424 | pageItem->setHeader( i18n("Modems Setup" ) ); |
425 | tabWindow->addPage( pageItem ); |
426 | modems = new ModemsWidget(frame); |
427 | connect(modems, SIGNAL(resetmodems()), |
428 | this, SLOT(resetmodems())); |
429 | |
430 | frame = new QFrame(); |
431 | pageItem = new KPageWidgetItem( frame, i18n("&Graph" ) ); |
432 | pageItem->setHeader( i18n("Throughput Graph" ) ); |
433 | tabWindow->addPage( pageItem ); |
434 | |
435 | graph = new GraphSetup( frame ); |
436 | |
437 | frame = new QFrame(); |
438 | pageItem = new KPageWidgetItem( frame, i18n("M&isc" ) ); |
439 | pageItem->setHeader( i18n("Miscellaneous Settings" ) ); |
440 | tabWindow->addPage( pageItem ); |
441 | general = new GeneralWidget( frame ); |
442 | } |
443 | } |
444 | |
445 | |
446 | void KPPPWidget::enterPressedInID() { |
447 | PW_Edit->setFocus(); |
448 | } |
449 | |
450 | |
451 | void KPPPWidget::enterPressedInPW() { |
452 | connect_b->setFocus(); |
453 | } |
454 | |
455 | // triggered by the session manager |
456 | void KPPPWidget::saveMyself() { |
457 | gpppdata.save(); |
458 | } |
459 | |
460 | void KPPPWidget::shutDown() { |
461 | interruptConnection(); |
462 | saveMyself(); |
463 | } |
464 | |
465 | void KPPPWidget::log_window_toggled(bool on) { |
466 | gpppdata.set_show_log_window(on); |
467 | } |
468 | |
469 | |
470 | void KPPPWidget::setup() { |
471 | prepareSetupDialog(); |
472 | |
473 | if(tabWindow->exec()) |
474 | gpppdata.save(); |
475 | else |
476 | gpppdata.cancel(); |
477 | } |
478 | |
479 | |
480 | void KPPPWidget::resetaccounts() { |
481 | connectto_c->clear(); |
482 | |
483 | int count = gpppdata.accountCount(); |
484 | |
485 | // enable/disable controls |
486 | connectto_c->setEnabled(count > 0); |
487 | setButtons(); |
488 | |
489 | //load the accounts |
490 | for(int i=0; i < count; i++) { |
491 | gpppdata.setAccountByIndex(i); |
492 | connectto_c->addItem(gpppdata.accname()); |
493 | } |
494 | |
495 | //set the default account |
496 | if(!gpppdata.defaultAccount().isEmpty()) { |
497 | for(int i=0; i < count; i++) |
498 | if(gpppdata.defaultAccount() == connectto_c->itemText(i)) { |
499 | connectto_c->setCurrentIndex(i); |
500 | gpppdata.setAccountByIndex(i); |
501 | |
502 | ID_Edit->setText(gpppdata.storedUsername()); |
503 | PW_Edit->setText(gpppdata.storedPassword()); |
504 | } |
505 | } |
506 | else |
507 | if(count > 0) { |
508 | gpppdata.setDefaultAccount(connectto_c->itemText(0)); |
509 | gpppdata.save(); |
510 | ID_Edit->setText(gpppdata.storedUsername()); |
511 | PW_Edit->setText(gpppdata.storedPassword()); |
512 | } |
513 | |
514 | connect(ID_Edit, SIGNAL(textChanged(QString)), |
515 | this, SLOT(usernameChanged(QString))); |
516 | |
517 | connect(PW_Edit, SIGNAL(textChanged(QString)), |
518 | this, SLOT(passwordChanged(QString))); |
519 | |
520 | if (ID_Edit->text().isEmpty()) |
521 | ID_Edit->setFocus(); |
522 | else if (PW_Edit->text().isEmpty()) |
523 | PW_Edit->setFocus(); |
524 | |
525 | } |
526 | |
527 | void KPPPWidget::resetmodems() { |
528 | modem_c->clear(); |
529 | |
530 | int count = gpppdata.modemCount(); |
531 | |
532 | // enable/disable controls |
533 | modem_c->setEnabled(count > 0); |
534 | setButtons(); |
535 | |
536 | //load the modems |
537 | for(int i=0; i < count; i++) { |
538 | gpppdata.setModemByIndex(i); |
539 | modem_c->addItem(gpppdata.modname()); |
540 | } |
541 | |
542 | if (count > 1 && !m_bModemCShown) { |
543 | l1->addWidget(label7, 1, 1); |
544 | l1->addWidget(modem_c, 1, 2); |
545 | m_bModemCShown = true; |
546 | } else if (count <= 1 && m_bModemCShown){ |
547 | l1->removeWidget(label7); |
548 | l1->removeWidget(modem_c); |
549 | m_bModemCShown = false; |
550 | } |
551 | label7->setVisible(m_bModemCShown); |
552 | modem_c->setVisible(m_bModemCShown); |
553 | layout()->invalidate(); |
554 | setFixedSize(sizeHint()); |
555 | |
556 | //set the default modem |
557 | if(!gpppdata.defaultModem().isEmpty()) { |
558 | for(int i=0; i < count; i++) |
559 | if(gpppdata.defaultModem() == modem_c->itemText(i)) { |
560 | modem_c->setCurrentIndex(i); |
561 | gpppdata.setModemByIndex(i); |
562 | |
563 | } |
564 | } |
565 | else |
566 | if(count > 0) { |
567 | gpppdata.setDefaultModem(modem_c->itemText(0)); |
568 | gpppdata.save(); |
569 | } |
570 | } |
571 | |
572 | void KPPPWidget::setButtons() |
573 | { |
574 | int acccount = gpppdata.accountCount(); |
575 | int modcount = gpppdata.modemCount(); |
576 | |
577 | // enable/disable controls |
578 | connect_b->setEnabled(acccount > 0 && modcount > 0); |
579 | log->setEnabled(acccount > 0 && modcount > 0); |
580 | ID_Edit->setEnabled(acccount > 0 && modcount > 0); |
581 | PW_Edit->setEnabled(acccount > 0 && modcount > 0); |
582 | |
583 | } |
584 | |
585 | |
586 | void KPPPWidget::interruptConnection() { |
587 | // interrupt dial up |
588 | if (con->isVisible()) |
589 | emit con->cancelbutton(); |
590 | |
591 | // disconnect if online |
592 | if (gpppdata.pppdRunning()) |
593 | emit disconnect(); /* FIXME: are we emitting a slot here!!!??? */ |
594 | } |
595 | |
596 | void KPPPWidget::sigPPPDDied() { |
597 | kDebug(5002) << "Received a SIGUSR1" ; |
598 | |
599 | // if we are not connected pppdpid is -1 so have have to check for that |
600 | // in the followin line to make sure that we don't raise a false alarm |
601 | // such as would be the case when the log file viewer exits. |
602 | if(gpppdata.pppdRunning() || gpppdata.pppdError()) { |
603 | kDebug(5002) << "It was pppd that died" ; |
604 | |
605 | // when we killpppd() on Cancel in ConnectWidget |
606 | // we set pppid to -1 so we won't |
607 | // enter this block |
608 | |
609 | // just to be sure |
610 | Requester::rq->removeSecret(AUTH_PAP); |
611 | Requester::rq->removeSecret(AUTH_CHAP); |
612 | |
613 | gpppdata.setpppdRunning(false); |
614 | |
615 | // stop the disconnect timer (just in case) |
616 | disconnectTimer->stop(); |
617 | // signal other applications that we are disconnected now |
618 | emit sig_disconnected(); |
619 | kDebug(5002) << "Executing command on disconnect since pppd has died." ; |
620 | QApplication::flush(); |
621 | execute_command(gpppdata.command_on_disconnect()); |
622 | |
623 | stopAccounting(); |
624 | |
625 | con_win->stopClock(); |
626 | DockWidget::dock_widget->stop_stats(); |
627 | DockWidget::dock_widget->hide(); |
628 | |
629 | if(!gpppdata.pppdError()) |
630 | gpppdata.setpppdError(E_PPPD_DIED); |
631 | removedns(); |
632 | Modem::modem->unlockdevice(); |
633 | con->pppdDied(); |
634 | |
635 | Requester::rq->pppdExitStatus(); |
636 | gpppdata.setWaitCallback(gpppdata.callbackType() && Requester::rq->lastStatus == E_CBCP_WAIT); |
637 | |
638 | if(!gpppdata.automatic_redial() && !gpppdata.waitCallback()) { |
639 | quit_b->setFocus(); |
640 | show(); |
641 | con_win->stopClock(); |
642 | stopAccounting(); |
643 | con_win->hide(); |
644 | con->hide(); |
645 | |
646 | gpppdata.setpppdRunning(false); |
647 | // // not in a signal handler !!! KNotifyClient::beep(); |
648 | QString msg; |
649 | if (gpppdata.pppdError() == E_IF_TIMEOUT) |
650 | msg = i18n("Timeout expired while waiting for the PPP interface " |
651 | "to come up." ); |
652 | else { |
653 | msg = i18n("<p>The pppd daemon died unexpectedly!</p>" ); |
654 | Requester::rq->pppdExitStatus(); |
655 | if (Requester::rq->lastStatus != 99) { // more recent pppds only |
656 | msg += i18n("<p>Exit status: %1" , Requester::rq->lastStatus); |
657 | msg += i18n("</p><p>See 'man pppd' for an explanation of the error " |
658 | "codes or take a look at the kppp FAQ on " |
659 | " <a href=\"%1\">%1</a></p>" , |
660 | QString("http://developer.kde.org/~kppp/index.html" )); |
661 | } |
662 | } |
663 | |
664 | if(KMessageBox::warningYesNo(0, msg, i18n("Error" ), KStandardGuiItem::ok(), KGuiItem(i18n("&Details" ))) == KMessageBox::No) |
665 | PPPL_ShowLog(); |
666 | } else { /* reconnect on disconnect */ |
667 | if(gpppdata.waitCallback()) |
668 | kDebug(5002) << "Waiting for callback... " ; |
669 | else |
670 | kDebug(5002) << "Trying to reconnect... " ; |
671 | |
672 | if(gpppdata.authMethod() == AUTH_PAP || |
673 | gpppdata.authMethod() == AUTH_CHAP || |
674 | gpppdata.authMethod() == AUTH_PAPCHAP) |
675 | Requester::rq->setSecret(gpppdata.authMethod(), |
676 | encodeWord(gpppdata.storedUsername()), |
677 | encodeWord(gpppdata.password())); |
678 | |
679 | con_win->hide(); |
680 | con_win->stopClock(); |
681 | stopAccounting(); |
682 | gpppdata.setpppdRunning(false); |
683 | // not in a signal handler !!! KNotifyClient::beep(); |
684 | emit cmdl_start(); |
685 | } |
686 | } |
687 | gpppdata.setpppdError(0); |
688 | } |
689 | |
690 | |
691 | void KPPPWidget::sigChld() { |
692 | kDebug(5002) << "sigchld()" ; |
693 | // pid_t id = wait(0L); |
694 | // if(id == helperPid && helperPid != -1) { |
695 | // kDebug(5002) << "It was the setuid child that died"; |
696 | // helperPid = -1; |
697 | QString msg = i18n("kppp's helper process just died.\n" |
698 | "Since further execution would be pointless, " |
699 | "kppp will shut down now." ); |
700 | KMessageBox::error(0L, msg); |
701 | remove_pidfile(); |
702 | exit(1); |
703 | // } |
704 | } |
705 | |
706 | |
707 | void KPPPWidget::newdefaultaccount(int i) { |
708 | gpppdata.setDefaultAccount(connectto_c->itemText(i)); |
709 | gpppdata.save(); |
710 | ID_Edit->setText(gpppdata.storedUsername()); |
711 | PW_Edit->setText(gpppdata.storedPassword()); |
712 | } |
713 | |
714 | void KPPPWidget::newdefaultmodem(int i) { |
715 | gpppdata.setDefaultModem(modem_c->itemText(i)); |
716 | gpppdata.save(); |
717 | } |
718 | |
719 | |
720 | |
721 | void KPPPWidget::expandbutton() { |
722 | setup(); |
723 | } |
724 | |
725 | |
726 | void KPPPWidget::beginConnect() { |
727 | // make sure to connect to the account that is selected in the combo box |
728 | // (exeption: an account given by a command line argument) |
729 | if(!m_bCmdlAccount) { |
730 | gpppdata.setAccount(connectto_c->currentText()); |
731 | gpppdata.setPassword(PW_Edit->text()); |
732 | } else { |
733 | gpppdata.setPassword(gpppdata.storedPassword()); |
734 | } |
735 | |
736 | QFileInfo info(pppdPath()); |
737 | |
738 | if(!info.exists()){ |
739 | KMessageBox::error(this, i18n("Cannot find the PPP daemon!\n" |
740 | "Make sure that pppd is installed and " |
741 | "that you have entered the correct path." )); |
742 | return; |
743 | } |
744 | #if 0 |
745 | if(!info.isExecutable()){ |
746 | |
747 | QString string; |
748 | string = i18n("kppp cannot execute:\n %1\n" |
749 | "Please make sure that you have given kppp " |
750 | "setuid permission and that " |
751 | "pppd is executable." , gpppdata.pppdPath()); |
752 | KMessageBox::error(this, string); |
753 | return; |
754 | |
755 | } |
756 | #endif |
757 | |
758 | KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); |
759 | QString device = "" ; |
760 | if (args->isSet("dev" )) |
761 | device = args->getOption("dev" ); |
762 | else |
763 | device = gpppdata.modemDevice(); |
764 | |
765 | QFileInfo info2(device); |
766 | |
767 | if(!info2.exists()){ |
768 | QString string; |
769 | string = i18n("kppp can not find:\n %1\nPlease make sure you have setup " |
770 | "your modem device properly " |
771 | "and/or adjust the location of the modem device on " |
772 | "the modem tab of " |
773 | "the setup dialog." , device); |
774 | KMessageBox::error(this, string); |
775 | return; |
776 | } |
777 | |
778 | // if this is a PAP or CHAP account, ensure that username is |
779 | // supplied |
780 | if(gpppdata.authMethod() == AUTH_PAP || |
781 | gpppdata.authMethod() == AUTH_CHAP || |
782 | gpppdata.authMethod() == AUTH_PAPCHAP ) { |
783 | if(ID_Edit->text().isEmpty()) { |
784 | KMessageBox::error(this, |
785 | i18n( |
786 | "You have selected the authentication " |
787 | "method PAP or CHAP. This requires that you " |
788 | "supply a username and a password." )); |
789 | return; |
790 | } else { |
791 | if(!Requester::rq->setSecret(gpppdata.authMethod(), |
792 | encodeWord(gpppdata.storedUsername()), |
793 | encodeWord(gpppdata.password()))) { |
794 | QString s; |
795 | s = i18n("Cannot create PAP/CHAP authentication\n" |
796 | "file \"%1\"" , QString(PAP_AUTH_FILE)); |
797 | KMessageBox::error(this, s); |
798 | return; |
799 | } |
800 | } |
801 | } |
802 | |
803 | if (gpppdata.phonenumber().isEmpty()) { |
804 | QString s = i18n("You must specify a telephone number." ); |
805 | KMessageBox::error(this, s); |
806 | return; |
807 | } |
808 | |
809 | hide(); |
810 | |
811 | QString tit = i18n("Connecting to: %1" , gpppdata.accname()); |
812 | con->setWindowTitle(tit); |
813 | con->enableButtons(); |
814 | con->show(); |
815 | |
816 | bool show_debug = gpppdata.get_show_log_window(); |
817 | con->debug->setChecked(show_debug); // toggle button |
818 | debugwindow->clear(); |
819 | if (!show_debug) |
820 | debugwindow->hide(); |
821 | else { |
822 | debugwindow->show(); |
823 | con->raise(); |
824 | } |
825 | |
826 | emit begin_connect(); |
827 | } |
828 | |
829 | void KPPPWidget::disconnect() { |
830 | if (disconnectTimer->isActive()) return; // you had already pressed disconnect before |
831 | |
832 | // signal other applications that we are about to go offline now |
833 | emit sig_aboutToDisconnect(); |
834 | |
835 | con_win->hide(); |
836 | con->show(); |
837 | con->disableButtons(); // will reenable them later in delayedDisconnect() |
838 | con->setWindowTitle(i18n("Disconnecting..." )); |
839 | |
840 | if (!gpppdata.command_before_disconnect().isEmpty()) { |
841 | con->setMsg(i18n("Executing command before disconnection." )); |
842 | |
843 | qApp->processEvents(); |
844 | QApplication::flush(); |
845 | pid_t id = execute_command(gpppdata.command_before_disconnect()); |
846 | int i, status; |
847 | |
848 | do { |
849 | qApp->processEvents(); |
850 | i = waitpid(id, &status, WNOHANG); |
851 | usleep(500000); |
852 | } while (i == 0 && errno == 0); |
853 | } |
854 | |
855 | con->setMsg(i18n("Announcing disconnection." )); |
856 | |
857 | // this is no longer necessary since I'm delaying disconnection usign a QTimer |
858 | // qApp->processEvents(); |
859 | |
860 | // set the timer to call delayedDisconnect() in DISCONNECT_DELAY ms |
861 | disconnectTimer->setSingleShot(true); |
862 | disconnectTimer->start(DISCONNECT_DELAY); |
863 | } |
864 | |
865 | void KPPPWidget::delayedDisconnect() { |
866 | // this is where the actual disconnection takes place |
867 | con->hide(); |
868 | |
869 | statdlg->stop_stats(); |
870 | Requester::rq->killPPPDaemon(); |
871 | |
872 | // signal other applications that we are disconnected now |
873 | emit sig_disconnected(); |
874 | QApplication::flush(); |
875 | execute_command(gpppdata.command_on_disconnect()); |
876 | |
877 | Requester::rq->removeSecret(AUTH_PAP); |
878 | Requester::rq->removeSecret(AUTH_CHAP); |
879 | |
880 | removedns(); |
881 | Modem::modem->unlockdevice(); |
882 | |
883 | con_win->stopClock(); |
884 | p_kppp->stopAccounting(); |
885 | con_win->hide(); |
886 | |
887 | DockWidget::dock_widget->stop_stats(); |
888 | DockWidget::dock_widget->hide(); |
889 | |
890 | if(m_bQuitOnDisconnect) |
891 | kapp->exit(0); |
892 | else { |
893 | quit_b->setFocus(); |
894 | show(); |
895 | } |
896 | } |
897 | |
898 | |
899 | void KPPPWidget::helpbutton() { |
900 | KToolInvocation::invokeHelp(); |
901 | } |
902 | |
903 | |
904 | void KPPPWidget::quitbutton() { |
905 | if(gpppdata.pppdRunning()) { |
906 | int ok = KMessageBox::warningContinueCancel(this, |
907 | i18n("Exiting kPPP will close your PPP Session." ), |
908 | i18n("Quit kPPP?" ), KStandardGuiItem::quit()); |
909 | if(ok == KMessageBox::Continue) { |
910 | Requester::rq->killPPPDaemon(); |
911 | |
912 | // stop the disconnect delay timer |
913 | disconnectTimer->stop(); |
914 | |
915 | // signal other applications that we are disconnected now |
916 | emit sig_disconnected(); |
917 | QApplication::flush(); |
918 | execute_command(gpppdata.command_on_disconnect()); |
919 | removedns(); |
920 | Modem::modem->unlockdevice(); |
921 | } |
922 | } else { |
923 | if (!gpppdata.accname().isEmpty() && !gpppdata.storePassword()) |
924 | gpppdata.setStoredPassword("" ); |
925 | } |
926 | gpppdata.save(); |
927 | qApp->quit(); |
928 | } |
929 | |
930 | |
931 | void KPPPWidget::rulesetLoadError() { |
932 | KMessageBox::error(this, ruleset_load_errmsg); |
933 | } |
934 | |
935 | |
936 | void KPPPWidget::startAccounting() { |
937 | // volume accounting |
938 | stats->totalbytes = 0; |
939 | |
940 | kDebug(5002) << "AcctEnabled: " << gpppdata.AcctEnabled(); |
941 | |
942 | // load the ruleset |
943 | if(!gpppdata.AcctEnabled()) |
944 | return; |
945 | |
946 | QString d = AccountingBase::getAccountingFile(gpppdata.accountingFile()); |
947 | // if(::access(d.data(), X_OK) != 0) |
948 | acct = new Accounting(this, stats); |
949 | // else |
950 | // acct = new ExecutableAccounting(this); |
951 | |
952 | // connect to the accounting object |
953 | connect(acct, SIGNAL(changed(QString,QString)), |
954 | con_win, SLOT(slotAccounting(QString,QString))); |
955 | |
956 | if(!acct->loadRuleSet(gpppdata.accountingFile())) { |
957 | QString s= i18n("Can not load the accounting " |
958 | "ruleset \"%1\"." , gpppdata.accountingFile()); |
959 | |
960 | // starting the messagebox with a timer will prevent us |
961 | // from blocking the calling function ConnectWidget::timerEvent |
962 | ruleset_load_errmsg = s; |
963 | QTimer::singleShot(0, this, SLOT(rulesetLoadError())); |
964 | return; |
965 | } else |
966 | acct->slotStart(); |
967 | } |
968 | |
969 | void KPPPWidget::stopAccounting() { |
970 | // store volume accounting |
971 | if(stats->totalbytes != 0) |
972 | gpppdata.setTotalBytes(stats->totalbytes); |
973 | |
974 | if(!gpppdata.AcctEnabled()) |
975 | return; |
976 | |
977 | if(acct != 0) { |
978 | acct->slotStop(); |
979 | delete acct; |
980 | acct = 0; |
981 | } |
982 | } |
983 | |
984 | |
985 | void KPPPWidget::showStats() { |
986 | if(statdlg) { |
987 | statdlg->toCurrentDesktop(); |
988 | statdlg->show(); |
989 | statdlg->raise(); |
990 | } |
991 | } |
992 | |
993 | |
994 | void KPPPWidget::usernameChanged(const QString &) { |
995 | // store username for later use |
996 | gpppdata.setStoredUsername(ID_Edit->text()); |
997 | } |
998 | |
999 | |
1000 | void KPPPWidget::passwordChanged(const QString &) { |
1001 | // store the password if so requested |
1002 | if(gpppdata.storePassword()) |
1003 | gpppdata.setStoredPassword(PW_Edit->text()); |
1004 | else |
1005 | gpppdata.setStoredPassword("" ); |
1006 | } |
1007 | |
1008 | |
1009 | void KPPPWidget::setPW_Edit(const QString &pw) { |
1010 | PW_Edit->setText(pw); |
1011 | } |
1012 | |
1013 | |
1014 | void KPPPWidget::resetCosts(const QString &s) { |
1015 | AccountingBase::resetCosts(s); |
1016 | } |
1017 | |
1018 | |
1019 | void KPPPWidget::resetVolume(const QString &s) { |
1020 | AccountingBase::resetVolume(s); |
1021 | } |
1022 | |
1023 | /** |
1024 | * pppd's getword() function knows about escape characters. |
1025 | * If we write the username and password to the secrets file |
1026 | * we'll therefore have to escape back slashes. |
1027 | */ |
1028 | QString KPPPWidget::encodeWord(const QString &s) { |
1029 | QString r = s; |
1030 | r.replace(QRegExp("\\" ), "\\\\" ); |
1031 | return r; |
1032 | } |
1033 | |
1034 | void KPPPWidget::setQuitOnDisconnect (bool b) |
1035 | { |
1036 | m_bQuitOnDisconnect = b; |
1037 | } |
1038 | |
1039 | void KPPPWidget::showNews() { |
1040 | #ifdef KPPP_SHOW_NEWS |
1041 | /* |
1042 | * Introduce the QuickHelp feature to new users of this version |
1043 | */ |
1044 | #define QUICKHELP_HINT "Hint_QuickHelp" |
1045 | if(gpppdata.readNumConfig(GENERAL_GRP, QUICKHELP_HINT, 0) == 0) { |
1046 | KDialog dlg(); |
1047 | dlg.setCaption(i18n("Recent Changes in KPPP" )); |
1048 | |
1049 | QVBoxLayout *tl = new QVBoxLayout(&dlg); |
1050 | tl->setSpacing(10); |
1051 | tl->setMargin(10); |
1052 | QHBoxLayout *l1 = new QHBoxLayout(10); |
1053 | QVBoxLayout *l2 = new QVBoxLayout(10); |
1054 | tl->addLayout(l1); |
1055 | |
1056 | QLabel *icon = new QLabel(&dlg); |
1057 | icon->setPixmap(BarIcon("exclamation" )); |
1058 | icon->setFixedSize(icon->sizeHint()); |
1059 | l1->addWidget(icon); |
1060 | l1->addLayout(l2); |
1061 | |
1062 | QLabel *l = new QLabel(i18n("From version 1.4.8 on, kppp has a new feature\n" |
1063 | "called \"Quickhelp\". It is similar to a tooltip,\n" |
1064 | "but you can activate it whenever you want.\n" |
1065 | "\n" |
1066 | "To activate it, simply click on a control (like\n" |
1067 | "a button or a label) with the right mouse button.\n" |
1068 | "If the item supports Quickhelp, a popup menu\n" |
1069 | "will appear leading to Quickhelp.\n" |
1070 | "\n" |
1071 | "To test it, right-click somewhere in this text." ), |
1072 | &dlg); |
1073 | |
1074 | QCheckBox *cb = new QCheckBox(i18n("Do not show this hint again" ), &dlg); |
1075 | cb->setFixedSize(cb->sizeHint()); |
1076 | |
1077 | dlg.setButtons(Ok) |
1078 | |
1079 | l2->addWidget(l); |
1080 | l2->addWidget(cb); |
1081 | |
1082 | QString tmp = i18n("This is an example of <b>QuickHelp</b>.\n" |
1083 | "This window will stay open until you\n" |
1084 | "click a mouse button or a press a key.\n" ); |
1085 | |
1086 | cb->setWhatsThis(tmp); |
1087 | l->setWhatsThis( tmp); |
1088 | |
1089 | dlg.exec(); |
1090 | if(cb->isChecked()) { |
1091 | gpppdata.writeConfig(GENERAL_GRP, QUICKHELP_HINT, 1); |
1092 | gpppdata.save(); |
1093 | } |
1094 | } |
1095 | #endif |
1096 | } |
1097 | |
1098 | |
1099 | #include "kpppwidget.moc" |
1100 | |
1101 | |