2 * kPPP: A pppd front end for the KDE project
5 * Copyright (C) 1997 Bernd Johannes Wuebben
6 * wuebben@math.cornell.edu
8 * Copyright (C) 1998-2002 Harri Porten <porten@kde.org>
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.
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.
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.
25 #include "kpppwidget.h"
26 #include <qapplication.h>
27 #include <qcombobox.h>
32 #include <qpushbutton.h>
35 #include <QGridLayout>
37 #include <QHBoxLayout>
38 #include <QVBoxLayout>
39 #include <kpagedialog.h>
42 #include <kaboutdata.h>
43 #include <kglobalsettings.h>
44 #include <kcmdlineargs.h>
47 #include <kiconloader.h> // For BarIcon
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>
57 #include <KStandardGuiItem>
61 #include <ktoolinvocation.h>
70 #include "requester.h"
76 #include "kpppadaptor.h"
78 // delay disconnection for a second
79 #define DISCONNECT_DELAY 1000
81 extern KPPPWidget
*p_kppp
;
83 KPPPWidget::KPPPWidget( QWidget
*parent
, const char *name
)
86 , m_bCmdlAccount (false)
87 , m_bCmdlModem (false)
89 KpppAdaptor
*kpppAdaptor
= new KpppAdaptor(this);
90 QDBusConnection::sessionBus().registerObject("/Kppp", this);
92 setObjectName( name
);
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()) );
102 // before doing anything else, run a few tests
104 int result
= runTests();
105 if(result
== TEST_CRITICAL
)
108 installEventFilter(this);
110 QVBoxLayout
*tl
= new QVBoxLayout(this);
114 l1
= new QGridLayout();
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);
121 label1
= new QLabel(i18n("C&onnect to: "), this);
122 l1
->addWidget(label1
, 0, 1);
124 connectto_c
= new QComboBox(this);
125 connectto_c
->setEditable( false );
126 label1
->setBuddy(connectto_c
);
128 connect(connectto_c
, SIGNAL(activated(int)),
129 SLOT(newdefaultaccount(int)));
130 l1
->addWidget(connectto_c
, 0, 2);
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;
139 connect(modem_c
, SIGNAL(activated(int)),
140 SLOT(newdefaultmodem(int)));
141 // l1->addWidget(modem_c, 1, 2); (done in resetmodems())
143 ID_Label
= new QLabel(i18n("&Login ID:"), this);
144 l1
->addWidget(ID_Label
, 2, 1);
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"
157 "<b>Important</b>: case is important here:\n"
158 "<i>myusername</i> is not the same as <i>MyUserName</i>.");
160 ID_Label
->setWhatsThis(tmp
);
161 ID_Edit
->setWhatsThis(tmp
);
163 PW_Label
= new QLabel(i18n("&Password:"), this);
164 l1
->addWidget(PW_Label
, 3, 1);
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()));
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"
178 "<b>Important</b>: case is important here:\n"
179 "<i>mypassword</i> is not the same as <i>MyPassword</i>.");
181 PW_Label
->setWhatsThis(tmp
);
182 PW_Edit
->setWhatsThis(tmp
);
184 QHBoxLayout
*l3
= new QHBoxLayout
;
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());
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"
201 "Turn it off if <i>kppp</i> routinely connects without\n"
204 fline
= new KSeparator( Qt::Horizontal
, this);
205 tl
->addWidget(fline
);
207 QHBoxLayout
*l2
= new QHBoxLayout
;
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();
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();
221 if(gpppdata
.access() != KConfig::ReadWrite
)
222 setup_b
->setEnabled(false);
224 help_b
= new KPushButton(KStandardGuiItem::help(), this);
225 connect( help_b
, SIGNAL(clicked()), SLOT(helpbutton()));
227 KHelpMenu
*helpMenu
= 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();
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();
239 quit_b
->setFixedWidth(minw
);
240 setup_b
->setFixedWidth(minw
);
241 help_b
->setFixedWidth(help_b
->sizeHint().width());
242 connect_b
->setFixedWidth(minw
);
244 l2
->addWidget(quit_b
);
245 l2
->addWidget(setup_b
);
246 l2
->addWidget(help_b
);
248 l2
->addWidget(connect_b
);
250 setFixedSize(sizeHint());
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()));
258 stats
= new PPPStats
;
260 KWindowSystem::setIcons(winId(), qApp
->windowIcon().pixmap(IconSize(KIconLoader::Desktop
),IconSize(KIconLoader::Desktop
)), qApp
->windowIcon().pixmap(IconSize(KIconLoader::Small
),IconSize(KIconLoader::Small
)));
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
)));
266 statdlg
= new PPPStatsDlg(0, "stats", this, stats
);
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
)));
273 // load up the accounts combo box
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()));
281 QRect desk
= KGlobalSettings::desktopGeometry(topLevelWidget());
282 con
->setGeometry(desk
.center().x()-175, desk
.center().y()-55, 350,110);
284 // connect the ConnectWidgets various signals
285 connect(con
, SIGNAL(closeDebugWindow()),
286 debugwindow
, SLOT(hide()));
287 connect(con
, SIGNAL(debugMessage(const QString
&)),
288 debugwindow
, SLOT(statusLabel(const 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()));
304 debugwindow
->setGeometry(desk
.center().x()+190, desk
.center().y()-55,
305 debugwindow
->width(),debugwindow
->height());
307 move(desk
.center().x()-width()/2, desk
.center().y()-height()/2);
310 KCmdLineArgs
*args
= KCmdLineArgs::parsedArgs();
312 m_strCmdlAccount
= args
->getOption("c");
313 m_strCmdlModem
= args
->getOption("m");
314 m_bQuitOnDisconnect
= args
->isSet("q");
316 if(!m_strCmdlAccount
.isEmpty()) {
317 m_bCmdlAccount
= true;
318 kDebug(5002) << "cmdl_account: " << m_bCmdlAccount
;
321 if(!m_strCmdlModem
.isEmpty()) {
323 kDebug(5002) << "cmdl_modem: " << m_bCmdlModem
;
327 bool result
= gpppdata
.setModem(m_strCmdlModem
);
330 string
= i18n("No such Modem:\n%1\nFalling back to default", m_strCmdlModem
);
331 KMessageBox::error(this, string
);
332 m_bCmdlModem
= false;
337 bool result
= gpppdata
.setAccount(m_strCmdlAccount
);
340 string
= i18n("No such Account:\n%1", m_strCmdlAccount
);
341 KMessageBox::error(this, string
);
342 m_bCmdlAccount
= false;
351 //#define KPPP_SHOW_NEWS
352 #ifdef KPPP_SHOW_NEWS
353 // keep user informed about recent changes
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()));
363 KPPPWidget::~KPPPWidget()
368 bool KPPPWidget::eventFilter(QObject
*o
, QEvent
*e
) {
369 if(e
->type() == QEvent::User
) {
370 switch(((SignalEvent
*)e
)->sigType()) {
372 kDebug(5002) << "Received a SIGINT";
373 interruptConnection();
386 if(e
->type() == QEvent::KeyPress
) {
387 if(connect_b
->hasFocus() && ((QKeyEvent
*)e
)->key() == Qt::Key_Return
) {
397 void KPPPWidget::prepareSetupDialog() {
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 );
406 KWindowSystem::setIcons(tabWindow
->winId(), qApp
->windowIcon().pixmap(IconSize(KIconLoader::Desktop
),IconSize(KIconLoader::Desktop
)), qApp
->windowIcon().pixmap(IconSize(KIconLoader::Small
),IconSize(KIconLoader::Small
)));
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(const QString
&)),
417 this, SLOT(resetCosts(const QString
&)));
418 connect(accounts
, SIGNAL(resetVolume(const QString
&)),
419 this, SLOT(resetVolume(const QString
&)));
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()));
430 frame
= new QFrame();
431 pageItem
= new KPageWidgetItem( frame
, i18n("&Graph") );
432 pageItem
->setHeader( i18n("Throughput Graph") );
433 tabWindow
->addPage( pageItem
);
435 graph
= new GraphSetup( frame
);
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
);
446 void KPPPWidget::enterPressedInID() {
451 void KPPPWidget::enterPressedInPW() {
452 connect_b
->setFocus();
455 // triggered by the session manager
456 void KPPPWidget::saveMyself() {
460 void KPPPWidget::shutDown() {
461 interruptConnection();
465 void KPPPWidget::log_window_toggled(bool on
) {
466 gpppdata
.set_show_log_window(on
);
470 void KPPPWidget::setup() {
471 prepareSetupDialog();
473 if(tabWindow
->exec())
480 void KPPPWidget::resetaccounts() {
481 connectto_c
->clear();
483 int count
= gpppdata
.accountCount();
485 // enable/disable controls
486 connectto_c
->setEnabled(count
> 0);
490 for(int i
=0; i
< count
; i
++) {
491 gpppdata
.setAccountByIndex(i
);
492 connectto_c
->addItem(gpppdata
.accname());
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
);
502 ID_Edit
->setText(gpppdata
.storedUsername());
503 PW_Edit
->setText(gpppdata
.storedPassword());
508 gpppdata
.setDefaultAccount(connectto_c
->itemText(0));
510 ID_Edit
->setText(gpppdata
.storedUsername());
511 PW_Edit
->setText(gpppdata
.storedPassword());
514 connect(ID_Edit
, SIGNAL(textChanged(const QString
&)),
515 this, SLOT(usernameChanged(const QString
&)));
517 connect(PW_Edit
, SIGNAL(textChanged(const QString
&)),
518 this, SLOT(passwordChanged(const QString
&)));
520 if (ID_Edit
->text().isEmpty())
522 else if (PW_Edit
->text().isEmpty())
527 void KPPPWidget::resetmodems() {
530 int count
= gpppdata
.modemCount();
532 // enable/disable controls
533 modem_c
->setEnabled(count
> 0);
537 for(int i
=0; i
< count
; i
++) {
538 gpppdata
.setModemByIndex(i
);
539 modem_c
->addItem(gpppdata
.modname());
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;
551 label7
->setVisible(m_bModemCShown
);
552 modem_c
->setVisible(m_bModemCShown
);
553 layout()->invalidate();
554 setFixedSize(sizeHint());
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
);
567 gpppdata
.setDefaultModem(modem_c
->itemText(0));
572 void KPPPWidget::setButtons()
574 int acccount
= gpppdata
.accountCount();
575 int modcount
= gpppdata
.modemCount();
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);
586 void KPPPWidget::interruptConnection() {
588 if (con
->isVisible())
589 emit con
->cancelbutton();
591 // disconnect if online
592 if (gpppdata
.pppdRunning())
593 emit
disconnect(); /* FIXME: are we emitting a slot here!!!??? */
596 void KPPPWidget::sigPPPDDied() {
597 kDebug(5002) << "Received a SIGUSR1";
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";
605 // when we killpppd() on Cancel in ConnectWidget
606 // we set pppid to -1 so we won't
610 Requester::rq
->removeSecret(AUTH_PAP
);
611 Requester::rq
->removeSecret(AUTH_CHAP
);
613 gpppdata
.setpppdRunning(false);
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());
625 con_win
->stopClock();
626 DockWidget::dock_widget
->stop_stats();
627 DockWidget::dock_widget
->hide();
629 if(!gpppdata
.pppdError())
630 gpppdata
.setpppdError(E_PPPD_DIED
);
632 Modem::modem
->unlockdevice();
635 Requester::rq
->pppdExitStatus();
636 gpppdata
.setWaitCallback(gpppdata
.callbackType() && Requester::rq
->lastStatus
== E_CBCP_WAIT
);
638 if(!gpppdata
.automatic_redial() && !gpppdata
.waitCallback()) {
641 con_win
->stopClock();
646 gpppdata
.setpppdRunning(false);
647 // // not in a signal handler !!! KNotifyClient::beep();
649 if (gpppdata
.pppdError() == E_IF_TIMEOUT
)
650 msg
= i18n("Timeout expired while waiting for the PPP interface "
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"));
664 if(KMessageBox::warningYesNo(0, msg
, i18n("Error"), KStandardGuiItem::ok(), KGuiItem(i18n("&Details"))) == KMessageBox::No
)
666 } else { /* reconnect on disconnect */
667 if(gpppdata
.waitCallback())
668 kDebug(5002) << "Waiting for callback... ";
670 kDebug(5002) << "Trying to reconnect... ";
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()));
680 con_win
->stopClock();
682 gpppdata
.setpppdRunning(false);
683 // not in a signal handler !!! KNotifyClient::beep();
687 gpppdata
.setpppdError(0);
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";
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
);
707 void KPPPWidget::newdefaultaccount(int i
) {
708 gpppdata
.setDefaultAccount(connectto_c
->itemText(i
));
710 ID_Edit
->setText(gpppdata
.storedUsername());
711 PW_Edit
->setText(gpppdata
.storedPassword());
714 void KPPPWidget::newdefaultmodem(int i
) {
715 gpppdata
.setDefaultModem(modem_c
->itemText(i
));
721 void KPPPWidget::expandbutton() {
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());
733 gpppdata
.setPassword(gpppdata
.storedPassword());
736 QFileInfo
info(pppdPath());
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."));
745 if(!info
.isExecutable()){
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
);
758 KCmdLineArgs
*args
= KCmdLineArgs::parsedArgs();
760 if (args
->isSet("dev"))
761 device
= args
->getOption("dev");
763 device
= gpppdata
.modemDevice();
765 QFileInfo
info2(device
);
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 "
773 "the setup dialog.", device
);
774 KMessageBox::error(this, string
);
778 // if this is a PAP or CHAP account, ensure that username is
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,
786 "You have selected the authentication "
787 "method PAP or CHAP. This requires that you "
788 "supply a username and a password."));
791 if(!Requester::rq
->setSecret(gpppdata
.authMethod(),
792 encodeWord(gpppdata
.storedUsername()),
793 encodeWord(gpppdata
.password()))) {
795 s
= i18n("Cannot create PAP/CHAP authentication\n"
796 "file \"%1\"", QString(PAP_AUTH_FILE
));
797 KMessageBox::error(this, s
);
803 if (gpppdata
.phonenumber().isEmpty()) {
804 QString s
= i18n("You must specify a telephone number.");
805 KMessageBox::error(this, s
);
811 QString tit
= i18n("Connecting to: %1", gpppdata
.accname());
812 con
->setWindowTitle(tit
);
813 con
->enableButtons();
816 bool show_debug
= gpppdata
.get_show_log_window();
817 con
->debug
->setChecked(show_debug
); // toggle button
818 debugwindow
->clear();
826 emit
begin_connect();
829 void KPPPWidget::disconnect() {
830 if (disconnectTimer
->isActive()) return; // you had already pressed disconnect before
832 // signal other applications that we are about to go offline now
833 emit
sig_aboutToDisconnect();
837 con
->disableButtons(); // will reenable them later in delayedDisconnect()
838 con
->setWindowTitle(i18n("Disconnecting..."));
840 if (!gpppdata
.command_before_disconnect().isEmpty()) {
841 con
->setMsg(i18n("Executing command before disconnection."));
843 qApp
->processEvents();
844 QApplication::flush();
845 pid_t id
= execute_command(gpppdata
.command_before_disconnect());
849 qApp
->processEvents();
850 i
= waitpid(id
, &status
, WNOHANG
);
852 } while (i
== 0 && errno
== 0);
855 con
->setMsg(i18n("Announcing disconnection."));
857 // this is no longer necessary since I'm delaying disconnection usign a QTimer
858 // qApp->processEvents();
860 // set the timer to call delayedDisconnect() in DISCONNECT_DELAY ms
861 disconnectTimer
->setSingleShot(true);
862 disconnectTimer
->start(DISCONNECT_DELAY
);
865 void KPPPWidget::delayedDisconnect() {
866 // this is where the actual disconnection takes place
869 statdlg
->stop_stats();
870 Requester::rq
->killPPPDaemon();
872 // signal other applications that we are disconnected now
873 emit
sig_disconnected();
874 QApplication::flush();
875 execute_command(gpppdata
.command_on_disconnect());
877 Requester::rq
->removeSecret(AUTH_PAP
);
878 Requester::rq
->removeSecret(AUTH_CHAP
);
881 Modem::modem
->unlockdevice();
883 con_win
->stopClock();
884 p_kppp
->stopAccounting();
887 DockWidget::dock_widget
->stop_stats();
888 DockWidget::dock_widget
->hide();
890 if(m_bQuitOnDisconnect
)
899 void KPPPWidget::helpbutton() {
900 KToolInvocation::invokeHelp();
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();
912 // stop the disconnect delay timer
913 disconnectTimer
->stop();
915 // signal other applications that we are disconnected now
916 emit
sig_disconnected();
917 QApplication::flush();
918 execute_command(gpppdata
.command_on_disconnect());
920 Modem::modem
->unlockdevice();
923 if (!gpppdata
.accname().isEmpty() && !gpppdata
.storePassword())
924 gpppdata
.setStoredPassword("");
931 void KPPPWidget::rulesetLoadError() {
932 KMessageBox::error(this, ruleset_load_errmsg
);
936 void KPPPWidget::startAccounting() {
938 stats
->totalbytes
= 0;
940 kDebug(5002) << "AcctEnabled: " << gpppdata
.AcctEnabled();
943 if(!gpppdata
.AcctEnabled())
946 QString d
= AccountingBase::getAccountingFile(gpppdata
.accountingFile());
947 // if(::access(d.data(), X_OK) != 0)
948 acct
= new Accounting(this, stats
);
950 // acct = new ExecutableAccounting(this);
952 // connect to the accounting object
953 connect(acct
, SIGNAL(changed(QString
, QString
)),
954 con_win
, SLOT(slotAccounting(QString
, QString
)));
956 if(!acct
->loadRuleSet(gpppdata
.accountingFile())) {
957 QString s
= i18n("Can not load the accounting "
958 "ruleset \"%1\".", gpppdata
.accountingFile());
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()));
969 void KPPPWidget::stopAccounting() {
970 // store volume accounting
971 if(stats
->totalbytes
!= 0)
972 gpppdata
.setTotalBytes(stats
->totalbytes
);
974 if(!gpppdata
.AcctEnabled())
985 void KPPPWidget::showStats() {
987 statdlg
->toCurrentDesktop();
994 void KPPPWidget::usernameChanged(const QString
&) {
995 // store username for later use
996 gpppdata
.setStoredUsername(ID_Edit
->text());
1000 void KPPPWidget::passwordChanged(const QString
&) {
1001 // store the password if so requested
1002 if(gpppdata
.storePassword())
1003 gpppdata
.setStoredPassword(PW_Edit
->text());
1005 gpppdata
.setStoredPassword("");
1009 void KPPPWidget::setPW_Edit(const QString
&pw
) {
1010 PW_Edit
->setText(pw
);
1014 void KPPPWidget::resetCosts(const QString
&s
) {
1015 AccountingBase::resetCosts(s
);
1019 void KPPPWidget::resetVolume(const QString
&s
) {
1020 AccountingBase::resetVolume(s
);
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.
1028 QString
KPPPWidget::encodeWord(const QString
&s
) {
1030 r
.replace(QRegExp("\\"), "\\\\");
1034 void KPPPWidget::setQuitOnDisconnect (bool b
)
1036 m_bQuitOnDisconnect
= b
;
1039 void KPPPWidget::showNews() {
1040 #ifdef KPPP_SHOW_NEWS
1042 * Introduce the QuickHelp feature to new users of this version
1044 #define QUICKHELP_HINT "Hint_QuickHelp"
1045 if(gpppdata
.readNumConfig(GENERAL_GRP
, QUICKHELP_HINT
, 0) == 0) {
1047 dlg
.setCaption(i18n("Recent Changes in KPPP"));
1049 QVBoxLayout
*tl
= new QVBoxLayout(&dlg
);
1052 QHBoxLayout
*l1
= new QHBoxLayout(10);
1053 QVBoxLayout
*l2
= new QVBoxLayout(10);
1056 QLabel
*icon
= new QLabel(&dlg
);
1057 icon
->setPixmap(BarIcon("exclamation"));
1058 icon
->setFixedSize(icon
->sizeHint());
1059 l1
->addWidget(icon
);
1062 QLabel
*l
= new QLabel(i18n("From version 1.4.8 on, kppp has a new feature\n"
1063 "called \"Quickhelp\". It's similar to a tooltip,\n"
1064 "but you can activate it whenever you want.\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"
1071 "To test it, right-click somewhere in this text."),
1074 QCheckBox
*cb
= new QCheckBox(i18n("Do not show this hint again"), &dlg
);
1075 cb
->setFixedSize(cb
->sizeHint());
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");
1086 cb
->setWhatsThis(tmp
);
1087 l
->setWhatsThis( tmp
);
1090 if(cb
->isChecked()) {
1091 gpppdata
.writeConfig(GENERAL_GRP
, QUICKHELP_HINT
, 1);
1099 #include "kpppwidget.moc"