00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <unistd.h>
00022
00023 #include <qwidget.h>
00024 #include <qlineedit.h>
00025 #include <qlabel.h>
00026 #include <qlayout.h>
00027 #include <qsize.h>
00028 #include <qevent.h>
00029 #include <qkeycode.h>
00030 #include <qcheckbox.h>
00031 #include <qregexp.h>
00032 #include <qhbox.h>
00033 #include <qwhatsthis.h>
00034 #include <qptrdict.h>
00035
00036 #include <kglobal.h>
00037 #include <kdebug.h>
00038 #include <kapplication.h>
00039 #include <klocale.h>
00040 #include <kiconloader.h>
00041 #include <kmessagebox.h>
00042 #include <kaboutdialog.h>
00043 #include <kconfig.h>
00044 #include <kstandarddirs.h>
00045 #include <kprogress.h>
00046
00047 #include <sys/time.h>
00048 #include <sys/resource.h>
00049
00050 #include "kpassdlg.h"
00051
00052
00053
00054
00055
00056
00057
00058 static QPtrDict<int>* d_ptr = 0;
00059
00060 static void cleanup_d_ptr() {
00061 delete d_ptr;
00062 }
00063
00064 static int * ourMaxLength( const KPasswordEdit* const e ) {
00065 if ( !d_ptr ) {
00066 d_ptr = new QPtrDict<int>;
00067 d_ptr->setAutoDelete(true);
00068 qAddPostRoutine( cleanup_d_ptr );
00069 }
00070 int* ret = d_ptr->find( (void*) e );
00071 if ( ! ret ) {
00072 ret = new int;
00073 d_ptr->replace( (void*) e, ret );
00074 }
00075 return ret;
00076 }
00077
00078 static void delete_d( const KPasswordEdit* const e ) {
00079 if ( d_ptr )
00080 d_ptr->remove( (void*) e );
00081 }
00082
00083 const int KPasswordEdit::PassLen = 200;
00084
00085 class KPasswordDialog::KPasswordDialogPrivate
00086 {
00087 public:
00088 KPasswordDialogPrivate()
00089 : m_MatchLabel( 0 ), iconName( 0 ), allowEmptyPasswords( false ),
00090 minimumPasswordLength(0), maximumPasswordLength(KPasswordEdit::PassLen - 1),
00091 passwordStrengthWarningLevel(1), m_strengthBar(0),
00092 reasonablePasswordLength(8)
00093 {}
00094 QLabel *m_MatchLabel;
00095 QString iconName;
00096 bool allowEmptyPasswords;
00097 int minimumPasswordLength;
00098 int maximumPasswordLength;
00099 int passwordStrengthWarningLevel;
00100 KProgress* m_strengthBar;
00101 int reasonablePasswordLength;
00102 };
00103
00104
00105 KPasswordEdit::KPasswordEdit(QWidget *parent, const char *name)
00106 : QLineEdit(parent, name)
00107 {
00108 init();
00109
00110 KConfig* const cfg = KGlobal::config();
00111 KConfigGroupSaver saver(cfg, "Passwords");
00112
00113 const QString val = cfg->readEntry("EchoMode", "OneStar");
00114 if (val == "ThreeStars")
00115 m_EchoMode = ThreeStars;
00116 else if (val == "NoEcho")
00117 m_EchoMode = NoEcho;
00118 else
00119 m_EchoMode = OneStar;
00120
00121 setInputMethodEnabled( true );
00122 }
00123
00124 KPasswordEdit::KPasswordEdit(QWidget *parent, const char *name, int echoMode)
00125 : QLineEdit(parent, name), m_EchoMode(echoMode)
00126 {
00127 init();
00128 }
00129
00130 KPasswordEdit::KPasswordEdit(EchoModes echoMode, QWidget *parent, const char *name)
00131 : QLineEdit(parent, name), m_EchoMode(echoMode)
00132 {
00133 init();
00134 }
00135
00136 KPasswordEdit::KPasswordEdit(EchoMode echoMode, QWidget *parent, const char *name)
00137 : QLineEdit(parent, name)
00138 , m_EchoMode( echoMode == QLineEdit::NoEcho ? NoEcho : OneStar )
00139 {
00140 init();
00141 }
00142
00143 void KPasswordEdit::init()
00144 {
00145 setEchoMode(QLineEdit::Password);
00146 setAcceptDrops(false);
00147 int* t = ourMaxLength(this);
00148 *t = (PassLen - 1);
00149 m_Password = new char[PassLen];
00150 m_Password[0] = '\000';
00151 m_Length = 0;
00152 }
00153
00154 KPasswordEdit::~KPasswordEdit()
00155 {
00156 memset(m_Password, 0, PassLen * sizeof(char));
00157 delete[] m_Password;
00158 delete_d(this);
00159 }
00160
00161 void KPasswordEdit::insert(const QString &txt)
00162 {
00163 const QCString localTxt = txt.local8Bit();
00164 const unsigned int lim = localTxt.length();
00165 const int m_MaxLength = maxPasswordLength();
00166 for(unsigned int i=0; i < lim; ++i)
00167 {
00168 const unsigned char ke = localTxt[i];
00169 if (m_Length < m_MaxLength)
00170 {
00171 m_Password[m_Length] = ke;
00172 m_Password[++m_Length] = '\000';
00173 }
00174 }
00175 showPass();
00176 }
00177
00178 void KPasswordEdit::erase()
00179 {
00180 m_Length = 0;
00181 memset(m_Password, 0, PassLen * sizeof(char));
00182 setText("");
00183 }
00184
00185 void KPasswordEdit::focusInEvent(QFocusEvent *e)
00186 {
00187 const QString txt = text();
00188 setUpdatesEnabled(false);
00189 QLineEdit::focusInEvent(e);
00190 setUpdatesEnabled(true);
00191 setText(txt);
00192 }
00193
00194
00195 void KPasswordEdit::keyPressEvent(QKeyEvent *e)
00196 {
00197 switch (e->key()) {
00198 case Key_Return:
00199 case Key_Enter:
00200 case Key_Escape:
00201 e->ignore();
00202 break;
00203 case Key_Backspace:
00204 case Key_Delete:
00205 case 0x7f:
00206 if (e->state() & (ControlButton | AltButton))
00207 e->ignore();
00208 else if (m_Length) {
00209 m_Password[--m_Length] = '\000';
00210 showPass();
00211 }
00212 break;
00213 default:
00214 const unsigned char ke = e->text().local8Bit()[0];
00215 if (ke >= 32) {
00216 insert(e->text());
00217 } else
00218 e->ignore();
00219 break;
00220 }
00221 }
00222
00223 bool KPasswordEdit::event(QEvent *e) {
00224 switch(e->type()) {
00225
00226 case QEvent::MouseButtonPress:
00227 case QEvent::MouseButtonRelease:
00228 case QEvent::MouseButtonDblClick:
00229 case QEvent::MouseMove:
00230 case QEvent::IMStart:
00231 case QEvent::IMCompose:
00232 return true;
00233
00234 case QEvent::IMEnd:
00235 {
00236 QIMEvent* const ie = (QIMEvent*) e;
00237 if (!ie->text().isEmpty())
00238 insert( ie->text() );
00239 return true;
00240 }
00241
00242 case QEvent::AccelOverride:
00243 {
00244 QKeyEvent* const k = (QKeyEvent*) e;
00245 switch (k->key()) {
00246 case Key_U:
00247 if (k->state() & ControlButton) {
00248 m_Length = 0;
00249 m_Password[m_Length] = '\000';
00250 showPass();
00251 }
00252 }
00253 return true;
00254 }
00255
00256 default:
00257
00258 break;
00259 }
00260 return QLineEdit::event(e);
00261 }
00262
00263 void KPasswordEdit::showPass()
00264 {
00265 QString tmp;
00266
00267 switch (m_EchoMode) {
00268 case OneStar:
00269 tmp.fill('*', m_Length);
00270 setText(tmp);
00271 break;
00272 case ThreeStars:
00273 tmp.fill('*', m_Length*3);
00274 setText(tmp);
00275 break;
00276 case NoEcho: default:
00277 emit textChanged(QString::null);
00278 break;
00279 }
00280 }
00281
00282 void KPasswordEdit::setMaxPasswordLength(int newLength)
00283 {
00284 if (newLength >= PassLen) newLength = PassLen - 1;
00285 if (newLength < 0) newLength = 0;
00286 int* t = ourMaxLength(this);
00287 *t = newLength;
00288 while (m_Length > newLength) {
00289 m_Password[m_Length] = '\000';
00290 --m_Length;
00291 }
00292 showPass();
00293 }
00294
00295 int KPasswordEdit::maxPasswordLength() const
00296 {
00297 return *(ourMaxLength(this));
00298 }
00299
00300
00301
00302
00303 KPasswordDialog::KPasswordDialog(Types type, bool enableKeep, int extraBttn,
00304 QWidget *parent, const char *name)
00305 : KDialogBase(parent, name, true, "", Ok|Cancel|extraBttn,
00306 Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), d(new KPasswordDialogPrivate)
00307 {
00308 d->iconName = "password";
00309 init();
00310 }
00311
00312 KPasswordDialog::KPasswordDialog(Types type, bool enableKeep, int extraBttn, const QString& icon,
00313 QWidget *parent, const char *name )
00314 : KDialogBase(parent, name, true, "", Ok|Cancel|extraBttn,
00315 Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), d(new KPasswordDialogPrivate)
00316 {
00317 if ( icon.stripWhiteSpace().isEmpty() )
00318 d->iconName = "password";
00319 else
00320 d->iconName = icon;
00321 init();
00322 }
00323
00324 KPasswordDialog::KPasswordDialog(int type, QString prompt, bool enableKeep,
00325 int extraBttn)
00326 : KDialogBase(0L, "Password Dialog", true, "", Ok|Cancel|extraBttn,
00327 Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), d(new KPasswordDialogPrivate)
00328 {
00329 d->iconName = "password";
00330 init();
00331 setPrompt(prompt);
00332 }
00333
00334 void KPasswordDialog::init()
00335 {
00336 m_Row = 0;
00337
00338 KConfig* const cfg = KGlobal::config();
00339 const KConfigGroupSaver saver(cfg, "Passwords");
00340 if (m_Keep && cfg->readBoolEntry("Keep", false))
00341 ++m_Keep;
00342
00343 m_pMain = new QWidget(this);
00344 setMainWidget(m_pMain);
00345 m_pGrid = new QGridLayout(m_pMain, 10, 3, 0, 0);
00346 m_pGrid->addColSpacing(1, 10);
00347
00348
00349 QLabel *lbl;
00350 const QPixmap pix( KGlobal::iconLoader()->loadIcon( d->iconName, KIcon::NoGroup, KIcon::SizeHuge, 0, 0, true));
00351 if (!pix.isNull()) {
00352 lbl = new QLabel(m_pMain);
00353 lbl->setPixmap(pix);
00354 lbl->setAlignment(AlignHCenter|AlignVCenter);
00355 lbl->setFixedSize(lbl->sizeHint());
00356 m_pGrid->addWidget(lbl, 0, 0, AlignCenter);
00357 }
00358
00359 m_pHelpLbl = new QLabel(m_pMain);
00360 m_pHelpLbl->setAlignment(AlignLeft|AlignVCenter|WordBreak);
00361 m_pGrid->addWidget(m_pHelpLbl, 0, 2, AlignLeft);
00362 m_pGrid->addRowSpacing(1, 10);
00363 m_pGrid->setRowStretch(1, 12);
00364
00365
00366 m_pGrid->addRowSpacing(6, 5);
00367 m_pGrid->setRowStretch(6, 12);
00368
00369
00370 lbl = new QLabel(m_pMain);
00371 lbl->setAlignment(AlignLeft|AlignVCenter);
00372 lbl->setText(i18n("&Password:"));
00373 lbl->setFixedSize(lbl->sizeHint());
00374 m_pGrid->addWidget(lbl, 7, 0, AlignLeft);
00375
00376 QHBoxLayout *h_lay = new QHBoxLayout();
00377 m_pGrid->addLayout(h_lay, 7, 2);
00378 m_pEdit = new KPasswordEdit(m_pMain);
00379 m_pEdit2 = 0;
00380 lbl->setBuddy(m_pEdit);
00381 QSize size = m_pEdit->sizeHint();
00382 m_pEdit->setFixedHeight(size.height());
00383 m_pEdit->setMinimumWidth(size.width());
00384 h_lay->addWidget(m_pEdit);
00385
00386
00387
00388 if ((m_Type == Password) && m_Keep) {
00389 m_pGrid->addRowSpacing(8, 10);
00390 m_pGrid->setRowStretch(8, 12);
00391 QCheckBox* const cb = new QCheckBox(i18n("&Keep password"), m_pMain);
00392 cb->setFixedSize(cb->sizeHint());
00393 if (m_Keep > 1)
00394 cb->setChecked(true);
00395 else
00396 m_Keep = 0;
00397 connect(cb, SIGNAL(toggled(bool)), SLOT(slotKeep(bool)));
00398 m_pGrid->addWidget(cb, 9, 2, AlignLeft|AlignVCenter);
00399 } else if (m_Type == NewPassword) {
00400 m_pGrid->addRowSpacing(8, 10);
00401 lbl = new QLabel(m_pMain);
00402 lbl->setAlignment(AlignLeft|AlignVCenter);
00403 lbl->setText(i18n("&Verify:"));
00404 lbl->setFixedSize(lbl->sizeHint());
00405 m_pGrid->addWidget(lbl, 9, 0, AlignLeft);
00406
00407 h_lay = new QHBoxLayout();
00408 m_pGrid->addLayout(h_lay, 9, 2);
00409 m_pEdit2 = new KPasswordEdit(m_pMain);
00410 lbl->setBuddy(m_pEdit2);
00411 size = m_pEdit2->sizeHint();
00412 m_pEdit2->setFixedHeight(size.height());
00413 m_pEdit2->setMinimumWidth(size.width());
00414 h_lay->addWidget(m_pEdit2);
00415
00416
00417 m_pGrid->addRowSpacing(10, 10);
00418 m_pGrid->setRowStretch(10, 12);
00419
00420 QHBox* const strengthBox = new QHBox(m_pMain);
00421 strengthBox->setSpacing(10);
00422 m_pGrid->addMultiCellWidget(strengthBox, 11, 11, 0, 2);
00423 QLabel* const passStrengthLabel = new QLabel(strengthBox);
00424 passStrengthLabel->setAlignment(AlignLeft|AlignVCenter);
00425 passStrengthLabel->setText(i18n("Password strength meter:"));
00426 d->m_strengthBar = new KProgress(100, strengthBox, "PasswordStrengthMeter");
00427 d->m_strengthBar->setPercentageVisible(false);
00428
00429 const QString strengthBarWhatsThis(i18n("The password strength meter gives an indication of the security "
00430 "of the password you have entered. To improve the strength of "
00431 "the password, try:\n"
00432 " - using a longer password;\n"
00433 " - using a mixture of upper- and lower-case letters;\n"
00434 " - using numbers or symbols, such as #, as well as letters."));
00435 QWhatsThis::add(passStrengthLabel, strengthBarWhatsThis);
00436 QWhatsThis::add(d->m_strengthBar, strengthBarWhatsThis);
00437
00438
00439 m_pGrid->addRowSpacing(12, 10);
00440 m_pGrid->setRowStretch(12, 12);
00441
00442 d->m_MatchLabel = new QLabel(m_pMain);
00443 d->m_MatchLabel->setAlignment(AlignLeft|AlignVCenter|WordBreak);
00444 m_pGrid->addMultiCellWidget(d->m_MatchLabel, 13, 13, 0, 2);
00445 d->m_MatchLabel->setText(i18n("Passwords do not match"));
00446
00447
00448 connect( m_pEdit, SIGNAL(textChanged(const QString&)), SLOT(enableOkBtn()) );
00449 connect( m_pEdit2, SIGNAL(textChanged(const QString&)), SLOT(enableOkBtn()) );
00450 enableOkBtn();
00451 }
00452
00453 erase();
00454 }
00455
00456
00457 KPasswordDialog::~KPasswordDialog()
00458 {
00459 delete d;
00460 }
00461
00462
00463 void KPasswordDialog::clearPassword()
00464 {
00465 m_pEdit->erase();
00466 }
00467
00468
00469 void KPasswordDialog::setPrompt(QString prompt)
00470 {
00471 m_pHelpLbl->setText(prompt);
00472 m_pHelpLbl->setFixedSize(275, m_pHelpLbl->heightForWidth(275));
00473 }
00474
00475
00476 QString KPasswordDialog::prompt() const
00477
00478 {
00479 return m_pHelpLbl->text();
00480 }
00481
00482
00483
00484 void KPasswordDialog::addLine(QString key, QString value)
00485 {
00486 if (m_Row > 3)
00487 return;
00488
00489 QLabel *lbl = new QLabel(key, m_pMain);
00490 lbl->setAlignment(AlignLeft|AlignTop);
00491 lbl->setFixedSize(lbl->sizeHint());
00492 m_pGrid->addWidget(lbl, m_Row+2, 0, AlignLeft);
00493
00494 lbl = new QLabel(value, m_pMain);
00495 lbl->setAlignment(AlignTop|WordBreak);
00496 lbl->setFixedSize(275, lbl->heightForWidth(275));
00497 m_pGrid->addWidget(lbl, m_Row+2, 2, AlignLeft);
00498 ++m_Row;
00499 }
00500
00501
00502 void KPasswordDialog::erase()
00503 {
00504 m_pEdit->erase();
00505 m_pEdit->setFocus();
00506 if (m_Type == NewPassword)
00507 m_pEdit2->erase();
00508 }
00509
00510
00511 void KPasswordDialog::slotOk()
00512 {
00513 if (m_Type == NewPassword) {
00514 if (strcmp(m_pEdit->password(), m_pEdit2->password())) {
00515 KMessageBox::sorry(this, i18n("You entered two different "
00516 "passwords. Please try again."));
00517 erase();
00518 return;
00519 }
00520 if (d->m_strengthBar && d->m_strengthBar->progress() < d->passwordStrengthWarningLevel) {
00521 int retVal = KMessageBox::warningContinueCancel(this,
00522 i18n( "The password you have entered has a low strength. "
00523 "To improve the strength of "
00524 "the password, try:\n"
00525 " - using a longer password;\n"
00526 " - using a mixture of upper- and lower-case letters;\n"
00527 " - using numbers or symbols as well as letters.\n"
00528 "\n"
00529 "Would you like to use this password anyway?"),
00530 i18n("Low Password Strength"));
00531 if (retVal == KMessageBox::Cancel) return;
00532 }
00533 }
00534 if (!checkPassword(m_pEdit->password())) {
00535 erase();
00536 return;
00537 }
00538 accept();
00539 }
00540
00541
00542 void KPasswordDialog::slotCancel()
00543 {
00544 reject();
00545 }
00546
00547
00548 void KPasswordDialog::slotKeep(bool keep)
00549 {
00550 m_Keep = keep;
00551 }
00552
00553
00554
00555 int KPasswordDialog::getPassword(QCString &password, QString prompt,
00556 int *keep)
00557 {
00558 const bool enableKeep = (keep && *keep);
00559 KPasswordDialog* const dlg = new KPasswordDialog(int(Password), prompt, enableKeep);
00560 const int ret = dlg->exec();
00561 if (ret == Accepted) {
00562 password = dlg->password();
00563 if (enableKeep)
00564 *keep = dlg->keep();
00565 }
00566 delete dlg;
00567 return ret;
00568 }
00569
00570
00571
00572 int KPasswordDialog::getNewPassword(QCString &password, QString prompt)
00573 {
00574 KPasswordDialog* const dlg = new KPasswordDialog(NewPassword, prompt);
00575 const int ret = dlg->exec();
00576 if (ret == Accepted)
00577 password = dlg->password();
00578 delete dlg;
00579 return ret;
00580 }
00581
00582
00583
00584 void KPasswordDialog::disableCoreDumps()
00585 {
00586 struct rlimit rlim;
00587 rlim.rlim_cur = rlim.rlim_max = 0;
00588 setrlimit(RLIMIT_CORE, &rlim);
00589 }
00590
00591 void KPasswordDialog::virtual_hook( int id, void* data )
00592 { KDialogBase::virtual_hook( id, data ); }
00593
00594 void KPasswordDialog::enableOkBtn()
00595 {
00596 if (m_Type == NewPassword) {
00597 const bool match = strcmp(m_pEdit->password(), m_pEdit2->password()) == 0
00598 && (d->allowEmptyPasswords || m_pEdit->password()[0]);
00599
00600 const QString pass(m_pEdit->password());
00601
00602 const int minPasswordLength = minimumPasswordLength();
00603
00604 if ((int) pass.length() < minPasswordLength) {
00605 enableButtonOK(false);
00606 } else {
00607 enableButtonOK( match );
00608 }
00609
00610 if ( match && d->allowEmptyPasswords && m_pEdit->password()[0] == 0 ) {
00611 d->m_MatchLabel->setText( i18n("Password is empty") );
00612 } else {
00613 if ((int) pass.length() < minPasswordLength) {
00614 d->m_MatchLabel->setText(i18n("Password must be at least 1 character long", "Password must be at least %n characters long", minPasswordLength));
00615 } else {
00616 d->m_MatchLabel->setText( match? i18n("Passwords match")
00617 :i18n("Passwords do not match") );
00618 }
00619 }
00620
00621
00622
00623
00624
00625
00626
00627 const double lengthFactor = d->reasonablePasswordLength / 8.0;
00628
00629
00630 int pwlength = (int) (pass.length() / lengthFactor);
00631 if (pwlength > 5) pwlength = 5;
00632
00633 const QRegExp numRxp("[0-9]", true, false);
00634 int numeric = (int) (pass.contains(numRxp) / lengthFactor);
00635 if (numeric > 3) numeric = 3;
00636
00637 const QRegExp symbRxp("\\W", false, false);
00638 int numsymbols = (int) (pass.contains(symbRxp) / lengthFactor);
00639 if (numsymbols > 3) numsymbols = 3;
00640
00641 const QRegExp upperRxp("[A-Z]", true, false);
00642 int upper = (int) (pass.contains(upperRxp) / lengthFactor);
00643 if (upper > 3) upper = 3;
00644
00645 int pwstrength=((pwlength*10)-20) + (numeric*10) + (numsymbols*15) + (upper*10);
00646
00647 if ( pwstrength < 0 ) {
00648 pwstrength = 0;
00649 }
00650
00651 if ( pwstrength > 100 ) {
00652 pwstrength = 100;
00653 }
00654 d->m_strengthBar->setProgress(pwstrength);
00655
00656 }
00657 }
00658
00659
00660 void KPasswordDialog::setAllowEmptyPasswords(bool allowed) {
00661 d->allowEmptyPasswords = allowed;
00662 enableOkBtn();
00663 }
00664
00665
00666 bool KPasswordDialog::allowEmptyPasswords() const {
00667 return d->allowEmptyPasswords;
00668 }
00669
00670 void KPasswordDialog::setMinimumPasswordLength(int minLength) {
00671 d->minimumPasswordLength = minLength;
00672 enableOkBtn();
00673 }
00674
00675 int KPasswordDialog::minimumPasswordLength() const {
00676 return d->minimumPasswordLength;
00677 }
00678
00679 void KPasswordDialog::setMaximumPasswordLength(int maxLength) {
00680
00681 if (maxLength < 0) maxLength = 0;
00682 if (maxLength >= KPasswordEdit::PassLen) maxLength = KPasswordEdit::PassLen - 1;
00683
00684 d->maximumPasswordLength = maxLength;
00685
00686 m_pEdit->setMaxPasswordLength(maxLength);
00687 if (m_pEdit2) m_pEdit2->setMaxPasswordLength(maxLength);
00688
00689 }
00690
00691 int KPasswordDialog::maximumPasswordLength() const {
00692 return d->maximumPasswordLength;
00693 }
00694
00695
00696
00697 void KPasswordDialog::setReasonablePasswordLength(int reasonableLength) {
00698
00699 if (reasonableLength < 1) reasonableLength = 1;
00700 if (reasonableLength >= maximumPasswordLength()) reasonableLength = maximumPasswordLength();
00701
00702 d->reasonablePasswordLength = reasonableLength;
00703
00704 }
00705
00706 int KPasswordDialog::reasonablePasswordLength() const {
00707 return d->reasonablePasswordLength;
00708 }
00709
00710
00711 void KPasswordDialog::setPasswordStrengthWarningLevel(int warningLevel) {
00712 if (warningLevel < 0) warningLevel = 0;
00713 if (warningLevel > 99) warningLevel = 99;
00714 d->passwordStrengthWarningLevel = warningLevel;
00715 }
00716
00717 int KPasswordDialog::passwordStrengthWarningLevel() const {
00718 return d->passwordStrengthWarningLevel;
00719 }
00720
00721 #include "kpassdlg.moc"