00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <unistd.h>
00021
00022 #include <qwidget.h>
00023 #include <qlineedit.h>
00024 #include <qlabel.h>
00025 #include <qlayout.h>
00026 #include <qsize.h>
00027 #include <qevent.h>
00028 #include <qkeycode.h>
00029 #include <qcheckbox.h>
00030
00031 #include <kglobal.h>
00032 #include <kdebug.h>
00033 #include <kapplication.h>
00034 #include <klocale.h>
00035 #include <kiconloader.h>
00036 #include <kmessagebox.h>
00037 #include <kaboutdialog.h>
00038 #include <kconfig.h>
00039 #include <kstandarddirs.h>
00040
00041 #include <sys/time.h>
00042 #include <sys/resource.h>
00043
00044 #include "kpassdlg.h"
00045
00046
00047
00048
00049
00050 class KPasswordDialog::KPasswordDialogPrivate
00051 {
00052 public:
00053 KPasswordDialogPrivate()
00054 : m_MatchLabel( 0 ), iconName( 0 )
00055 {}
00056 QLabel *m_MatchLabel;
00057 QString iconName;
00058 };
00059
00060 const int KPasswordEdit::PassLen = 200;
00061
00062 KPasswordEdit::KPasswordEdit(QWidget *parent, const char *name)
00063 : QLineEdit(parent, name)
00064 {
00065 init();
00066
00067 KConfig *cfg = KGlobal::config();
00068 KConfigGroupSaver saver(cfg, "Passwords");
00069
00070 QString val = cfg->readEntry("EchoMode", "OneStar");
00071 if (val == "ThreeStars")
00072 m_EchoMode = ThreeStars;
00073 else if (val == "NoEcho")
00074 m_EchoMode = NoEcho;
00075 else
00076 m_EchoMode = OneStar;
00077 }
00078
00079 KPasswordEdit::KPasswordEdit(QWidget *parent, const char *name, int echoMode)
00080 : QLineEdit(parent, name), m_EchoMode(echoMode)
00081 {
00082 init();
00083 }
00084
00085 KPasswordEdit::KPasswordEdit(EchoModes echoMode, QWidget *parent, const char *name)
00086 : QLineEdit(parent, name), m_EchoMode(echoMode)
00087 {
00088 init();
00089 }
00090
00091 KPasswordEdit::KPasswordEdit(EchoMode echoMode, QWidget *parent, const char *name)
00092 : QLineEdit(parent, name)
00093 , m_EchoMode( echoMode == QLineEdit::NoEcho ? NoEcho : OneStar )
00094 {
00095 init();
00096 }
00097
00098 void KPasswordEdit::init()
00099 {
00100 setEchoMode(QLineEdit::Password);
00101 setAcceptDrops(false);
00102 m_Password = new char[PassLen];
00103 m_Password[0] = '\000';
00104 m_Length = 0;
00105 }
00106
00107 KPasswordEdit::~KPasswordEdit()
00108 {
00109 for (int i=0; i<PassLen; i++)
00110 m_Password[i] = '\000';
00111 delete[] m_Password;
00112 }
00113
00114 void KPasswordEdit::insert(const QString &txt)
00115 {
00116 QCString localTxt = txt.local8Bit();
00117 for(unsigned int i=0; i < localTxt.length(); i++)
00118 {
00119 unsigned char ke = localTxt[i];
00120 if (m_Length < (PassLen - 1))
00121 {
00122 m_Password[m_Length] = ke;
00123 m_Password[++m_Length] = '\000';
00124 }
00125 }
00126 showPass();
00127 }
00128
00129 void KPasswordEdit::erase()
00130 {
00131 m_Length = 0;
00132 for (int i=0; i<PassLen; i++)
00133 m_Password[i] = '\000';
00134 setText("");
00135 }
00136
00137 void KPasswordEdit::focusInEvent(QFocusEvent *e)
00138 {
00139 QString txt = text();
00140 setUpdatesEnabled(false);
00141 QLineEdit::focusInEvent(e);
00142 setUpdatesEnabled(true);
00143 setText(txt);
00144 }
00145
00146
00147 void KPasswordEdit::keyPressEvent(QKeyEvent *e)
00148 {
00149 switch (e->key()) {
00150 case Key_Return:
00151 case Key_Enter:
00152 case Key_Escape:
00153 e->ignore();
00154 break;
00155 case Key_Backspace:
00156 case Key_Delete:
00157 case 0x7f:
00158 if (e->state() & (ControlButton | AltButton))
00159 e->ignore();
00160 else if (m_Length) {
00161 m_Password[--m_Length] = '\000';
00162 showPass();
00163 }
00164 break;
00165 default:
00166 unsigned char ke = e->text().local8Bit()[0];
00167 if (ke >= 32) {
00168 insert(e->text());
00169 } else
00170 e->ignore();
00171 break;
00172 }
00173 }
00174
00175 bool KPasswordEdit::event(QEvent *e) {
00176 switch(e->type()) {
00177
00178 case QEvent::MouseButtonPress:
00179 case QEvent::MouseButtonRelease:
00180 case QEvent::MouseButtonDblClick:
00181 case QEvent::MouseMove:
00182 case QEvent::IMStart:
00183 case QEvent::IMCompose:
00184 return true;
00185
00186 case QEvent::IMEnd:
00187 {
00188 QIMEvent *ie = (QIMEvent*) e;
00189 insert( ie->text() );
00190 return true;
00191 }
00192
00193 case QEvent::AccelOverride:
00194 {
00195 QKeyEvent *k = (QKeyEvent*) e;
00196 switch (k->key()) {
00197 case Key_U:
00198 if (k->state() & ControlButton) {
00199 m_Length = 0;
00200 m_Password[m_Length] = '\000';
00201 showPass();
00202 }
00203 }
00204 return true;
00205 }
00206
00207 default:
00208
00209 break;
00210 }
00211 return QLineEdit::event(e);
00212 }
00213
00214 void KPasswordEdit::showPass()
00215 {
00216 QString tmp;
00217
00218 switch (m_EchoMode) {
00219 case OneStar:
00220 tmp.fill('*', m_Length);
00221 setText(tmp);
00222 break;
00223 case ThreeStars:
00224 tmp.fill('*', m_Length*3);
00225 setText(tmp);
00226 break;
00227 case NoEcho: default:
00228 emit textChanged(QString::null);
00229 break;
00230 }
00231 }
00232
00233
00234
00235
00236
00237
00238 KPasswordDialog::KPasswordDialog(Types type, bool enableKeep, int extraBttn,
00239 QWidget *parent, const char *name)
00240 : KDialogBase(parent, name, true, "", Ok|Cancel|extraBttn,
00241 Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), d(new KPasswordDialogPrivate)
00242 {
00243 d->iconName = "password";
00244 init();
00245 }
00246
00247 KPasswordDialog::KPasswordDialog(Types type, bool enableKeep, int extraBttn, const QString& icon,
00248 QWidget *parent, const char *name )
00249 : KDialogBase(parent, name, true, "", Ok|Cancel|extraBttn,
00250 Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), d(new KPasswordDialogPrivate)
00251 {
00252 if ( icon.stripWhiteSpace().isEmpty() )
00253 d->iconName = "password";
00254 else
00255 d->iconName = icon;
00256 init();
00257 }
00258
00259 KPasswordDialog::KPasswordDialog(int type, QString prompt, bool enableKeep,
00260 int extraBttn)
00261 : KDialogBase(0L, "Password Dialog", true, "", Ok|Cancel|extraBttn,
00262 Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), d(new KPasswordDialogPrivate)
00263 {
00264 d->iconName = "password";
00265 init();
00266 setPrompt(prompt);
00267 }
00268
00269 void KPasswordDialog::init()
00270 {
00271 m_Row = 0;
00272
00273 KConfig *cfg = KGlobal::config();
00274 KConfigGroupSaver saver(cfg, "Passwords");
00275 if (m_Keep && cfg->readBoolEntry("Keep", false))
00276 m_Keep++;
00277
00278 m_pMain = new QWidget(this);
00279 setMainWidget(m_pMain);
00280 m_pGrid = new QGridLayout(m_pMain, 10, 3, 0, 0);
00281 m_pGrid->addColSpacing(1, 10);
00282
00283
00284 QLabel *lbl;
00285 QPixmap pix( KGlobal::iconLoader()->loadIcon( d->iconName, KIcon::NoGroup, KIcon::SizeHuge, 0, 0, true));
00286 if (!pix.isNull()) {
00287 lbl = new QLabel(m_pMain);
00288 lbl->setPixmap(pix);
00289 lbl->setAlignment(AlignHCenter|AlignVCenter);
00290 lbl->setFixedSize(lbl->sizeHint());
00291 m_pGrid->addWidget(lbl, 0, 0, AlignCenter);
00292 }
00293
00294 m_pHelpLbl = new QLabel(m_pMain);
00295 m_pHelpLbl->setAlignment(AlignLeft|AlignVCenter|WordBreak);
00296 m_pGrid->addWidget(m_pHelpLbl, 0, 2, AlignLeft);
00297 m_pGrid->addRowSpacing(1, 10);
00298 m_pGrid->setRowStretch(1, 12);
00299
00300
00301 m_pGrid->addRowSpacing(6, 5);
00302 m_pGrid->setRowStretch(6, 12);
00303
00304
00305 lbl = new QLabel(m_pMain);
00306 lbl->setAlignment(AlignLeft|AlignVCenter);
00307 lbl->setText(i18n("&Password:"));
00308 lbl->setFixedSize(lbl->sizeHint());
00309 m_pGrid->addWidget(lbl, 7, 0, AlignLeft);
00310
00311 QHBoxLayout *h_lay = new QHBoxLayout();
00312 m_pGrid->addLayout(h_lay, 7, 2);
00313 m_pEdit = new KPasswordEdit(m_pMain);
00314 lbl->setBuddy(m_pEdit);
00315 QSize size = m_pEdit->sizeHint();
00316 m_pEdit->setFixedHeight(size.height());
00317 m_pEdit->setMinimumWidth(size.width());
00318 h_lay->addWidget(m_pEdit);
00319
00320
00321
00322 if ((m_Type == Password) && m_Keep) {
00323 m_pGrid->addRowSpacing(8, 10);
00324 m_pGrid->setRowStretch(8, 12);
00325 QCheckBox *cb = new QCheckBox(i18n("&Keep password"), m_pMain);
00326 cb->setFixedSize(cb->sizeHint());
00327 if (m_Keep > 1)
00328 cb->setChecked(true);
00329 else
00330 m_Keep = 0;
00331 connect(cb, SIGNAL(toggled(bool)), SLOT(slotKeep(bool)));
00332 m_pGrid->addWidget(cb, 9, 2, AlignLeft|AlignVCenter);
00333 } else if (m_Type == NewPassword) {
00334 m_pGrid->addRowSpacing(8, 10);
00335 lbl = new QLabel(m_pMain);
00336 lbl->setAlignment(AlignLeft|AlignVCenter);
00337 lbl->setText(i18n("&Verify:"));
00338 lbl->setFixedSize(lbl->sizeHint());
00339 m_pGrid->addWidget(lbl, 9, 0, AlignLeft);
00340
00341 h_lay = new QHBoxLayout();
00342 m_pGrid->addLayout(h_lay, 9, 2);
00343 m_pEdit2 = new KPasswordEdit(m_pMain);
00344 lbl->setBuddy(m_pEdit2);
00345 size = m_pEdit2->sizeHint();
00346 m_pEdit2->setFixedHeight(size.height());
00347 m_pEdit2->setMinimumWidth(size.width());
00348 h_lay->addWidget(m_pEdit2);
00349
00350
00351 m_pGrid->addRowSpacing(10, 10);
00352 m_pGrid->setRowStretch(10, 12);
00353 d->m_MatchLabel = new QLabel(m_pMain);
00354 d->m_MatchLabel->setAlignment(AlignLeft|AlignVCenter|WordBreak);
00355 m_pGrid->addMultiCellWidget(d->m_MatchLabel, 11, 11, 0, 2);
00356 d->m_MatchLabel->setText(i18n("Passwords do not match"));
00357 connect( m_pEdit, SIGNAL(textChanged(const QString&)), SLOT(enableOkBtn()) );
00358 connect( m_pEdit2, SIGNAL(textChanged(const QString&)), SLOT(enableOkBtn()) );
00359 enableOkBtn();
00360 }
00361
00362 erase();
00363 }
00364
00365
00366 KPasswordDialog::~KPasswordDialog()
00367 {
00368 }
00369
00370
00371 void KPasswordDialog::clearPassword()
00372 {
00373 m_pEdit->erase();
00374 }
00375
00376
00377 void KPasswordDialog::setPrompt(QString prompt)
00378 {
00379 m_pHelpLbl->setText(prompt);
00380 m_pHelpLbl->setFixedSize(275, m_pHelpLbl->heightForWidth(275));
00381 }
00382
00383
00384 QString KPasswordDialog::prompt() const
00385
00386 {
00387 return m_pHelpLbl->text();
00388 }
00389
00390
00391
00392 void KPasswordDialog::addLine(QString key, QString value)
00393 {
00394 if (m_Row > 3)
00395 return;
00396
00397 QLabel *lbl = new QLabel(key, m_pMain);
00398 lbl->setAlignment(AlignLeft|AlignTop);
00399 lbl->setFixedSize(lbl->sizeHint());
00400 m_pGrid->addWidget(lbl, m_Row+2, 0, AlignLeft);
00401
00402 lbl = new QLabel(value, m_pMain);
00403 lbl->setAlignment(AlignTop|WordBreak);
00404 lbl->setFixedSize(275, lbl->heightForWidth(275));
00405 m_pGrid->addWidget(lbl, m_Row+2, 2, AlignLeft);
00406 m_Row++;
00407 }
00408
00409
00410 void KPasswordDialog::erase()
00411 {
00412 m_pEdit->erase();
00413 m_pEdit->setFocus();
00414 if (m_Type == NewPassword)
00415 m_pEdit2->erase();
00416 }
00417
00418
00419 void KPasswordDialog::slotOk()
00420 {
00421 if (m_Type == NewPassword) {
00422 if (strcmp(m_pEdit->password(), m_pEdit2->password())) {
00423 KMessageBox::sorry(this, i18n("You entered two different "
00424 "passwords. Please try again."));
00425 erase();
00426 return;
00427 }
00428 }
00429 if (!checkPassword(m_pEdit->password())) {
00430 erase();
00431 return;
00432 }
00433 accept();
00434 }
00435
00436
00437 void KPasswordDialog::slotCancel()
00438 {
00439 reject();
00440 }
00441
00442
00443 void KPasswordDialog::slotKeep(bool keep)
00444 {
00445 m_Keep = keep;
00446 }
00447
00448
00449
00450 int KPasswordDialog::getPassword(QCString &password, QString prompt,
00451 int *keep)
00452 {
00453 bool enableKeep = keep && *keep;
00454 KPasswordDialog *dlg = new KPasswordDialog(int(Password), prompt, enableKeep);
00455 int ret = dlg->exec();
00456 if (ret == Accepted) {
00457 password = dlg->password();
00458 if (enableKeep)
00459 *keep = dlg->keep();
00460 }
00461 delete dlg;
00462 return ret;
00463 }
00464
00465
00466
00467 int KPasswordDialog::getNewPassword(QCString &password, QString prompt)
00468 {
00469 KPasswordDialog *dlg = new KPasswordDialog(NewPassword, prompt);
00470 int ret = dlg->exec();
00471 if (ret == Accepted)
00472 password = dlg->password();
00473 delete dlg;
00474 return ret;
00475 }
00476
00477
00478
00479 void KPasswordDialog::disableCoreDumps()
00480 {
00481 struct rlimit rlim;
00482 rlim.rlim_cur = rlim.rlim_max = 0;
00483 setrlimit(RLIMIT_CORE, &rlim);
00484 }
00485
00486 void KPasswordDialog::virtual_hook( int id, void* data )
00487 { KDialogBase::virtual_hook( id, data ); }
00488
00489 void KPasswordDialog::enableOkBtn()
00490 {
00491 if (m_Type == NewPassword) {
00492 bool match = ((strcmp(m_pEdit->password(), m_pEdit2->password()))==0)
00493 && (strcmp(m_pEdit->password(), "") != 0);
00494 enableButtonOK( match );
00495 d->m_MatchLabel->setText( match? i18n("Passwords match")
00496 :i18n("Passwords do not match") );
00497 }
00498 }
00499
00500 #include "kpassdlg.moc"