kpassdlg.cpp
00001 // vi: ts=8 sts=4 sw=4 00002 /* This file is part of the KDE libraries 00003 Copyright (C) 1998 Pietro Iglio <iglio@fub.it> 00004 Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org> 00005 Copyright (C) 2004,2005 Andrew Coles <andrew_coles@yahoo.co.uk> 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License version 2 as published by the Free Software Foundation. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 #include <unistd.h> 00022 00023 #include <tqwidget.h> 00024 #include <tqlineedit.h> 00025 #include <tqlabel.h> 00026 #include <tqlayout.h> 00027 #include <tqsize.h> 00028 #include <tqevent.h> 00029 #include <tqkeycode.h> 00030 #include <tqcheckbox.h> 00031 #include <tqregexp.h> 00032 #include <tqhbox.h> 00033 #include <tqwhatsthis.h> 00034 #include <tqptrdict.h> 00035 #include <tqtimer.h> 00036 #include <tqtextcodec.h> 00037 00038 #include <tdeglobal.h> 00039 #include <kdebug.h> 00040 #include <tdeapplication.h> 00041 #include <tdelocale.h> 00042 #include <kiconloader.h> 00043 #include <tdemessagebox.h> 00044 #include <tdeaboutdialog.h> 00045 #include <tdeconfig.h> 00046 #include <kstandarddirs.h> 00047 #include <kprogress.h> 00048 00049 #include <sys/time.h> 00050 #include <sys/resource.h> 00051 00052 #include "kpassdlg.h" 00053 00054 #include "../tdesu/defaults.h" 00055 00056 /* 00057 * Password line editor. 00058 */ 00059 00060 const int KPasswordEdit::PassLen = 200; 00061 00062 class KPasswordDialog::KPasswordDialogPrivate 00063 { 00064 public: 00065 KPasswordDialogPrivate() 00066 : m_MatchLabel( 0 ), iconName( 0 ), allowEmptyPasswords( false ), 00067 minimumPasswordLength(0), maximumPasswordLength(KPasswordEdit::PassLen - 1), 00068 passwordStrengthWarningLevel(1), m_strengthBar(0), 00069 reasonablePasswordLength(8) 00070 {} 00071 TQLabel *m_MatchLabel; 00072 TQString iconName; 00073 bool allowEmptyPasswords; 00074 int minimumPasswordLength; 00075 int maximumPasswordLength; 00076 int passwordStrengthWarningLevel; 00077 KProgress* m_strengthBar; 00078 int reasonablePasswordLength; 00079 }; 00080 00081 00082 KPasswordEdit::KPasswordEdit(TQWidget *parent, const char *name) 00083 : TQLineEdit(parent, name) 00084 { 00085 init(); 00086 00087 TDEConfig* const cfg = TDEGlobal::config(); 00088 TDEConfigGroupSaver saver(cfg, "Passwords"); 00089 00090 const TQString val = cfg->readEntry("EchoMode", "OneStar"); 00091 if (val == "ThreeStars") { 00092 setEchoMode(PasswordThreeStars); 00093 } 00094 else if (val == "NoEcho") { 00095 setEchoMode(TQLineEdit::NoEcho); 00096 } 00097 else { 00098 setEchoMode(TQLineEdit::Password); 00099 } 00100 00101 setInputMethodEnabled( true ); 00102 } 00103 00104 KPasswordEdit::KPasswordEdit(TQWidget *parent, const char *name, int echoMode) 00105 : TQLineEdit(parent, name) 00106 { 00107 setEchoMode((TQLineEdit::EchoMode)echoMode); 00108 init(); 00109 } 00110 00111 KPasswordEdit::KPasswordEdit(EchoMode echoMode, TQWidget *parent, const char *name) 00112 : TQLineEdit(parent, name) 00113 { 00114 setEchoMode(echoMode); 00115 init(); 00116 } 00117 00118 KPasswordEdit::KPasswordEdit(EchoModes echoMode, TQWidget *parent, const char *name) 00119 : TQLineEdit(parent, name) 00120 { 00121 if (echoMode == KPasswordEdit::NoEcho) { 00122 setEchoMode(TQLineEdit::NoEcho); 00123 } 00124 else if (echoMode == KPasswordEdit::ThreeStars) { 00125 setEchoMode(TQLineEdit::PasswordThreeStars); 00126 } 00127 else if (echoMode == KPasswordEdit::OneStar) { 00128 setEchoMode(TQLineEdit::Password); 00129 } 00130 init(); 00131 } 00132 00133 void KPasswordEdit::init() 00134 { 00135 setAcceptDrops(false); 00136 } 00137 00138 KPasswordEdit::~KPasswordEdit() 00139 { 00140 } 00141 00142 const char *KPasswordEdit::password() const { 00143 TQTextCodec *origCStringCodec = TQTextCodec::codecForCStrings(); 00144 TQTextCodec::setCodecForCStrings(TQTextCodec::codecForLocale()); 00145 const char *outputPassword = text().ascii(); 00146 TQTextCodec::setCodecForCStrings(origCStringCodec); 00147 return outputPassword; 00148 } 00149 00150 void KPasswordEdit::erase() 00151 { 00152 setText(""); 00153 } 00154 00155 void KPasswordEdit::setMaxPasswordLength(int newLength) 00156 { 00157 setMaxLength(newLength); 00158 } 00159 00160 int KPasswordEdit::maxPasswordLength() const 00161 { 00162 return maxLength(); 00163 } 00164 00165 void KPasswordEdit::insert( const TQString &str) { 00166 TQLineEdit::insert(str); 00167 } 00168 00169 void KPasswordEdit::keyPressEvent(TQKeyEvent *e) { 00170 TQLineEdit::keyPressEvent(e); 00171 } 00172 00173 void KPasswordEdit::focusInEvent(TQFocusEvent *e) { 00174 TQLineEdit::focusInEvent(e); 00175 } 00176 00177 bool KPasswordEdit::event(TQEvent *e) { 00178 return TQLineEdit::event(e); 00179 } 00180 00181 /* 00182 * Password dialog. 00183 */ 00184 00185 KPasswordDialog::KPasswordDialog(Types type, bool enableKeep, int extraBttn, 00186 TQWidget *parent, const char *name) 00187 : KDialogBase(parent, name, true, "", Ok|Cancel|extraBttn, 00188 Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), m_keepWarnLbl(0), d(new KPasswordDialogPrivate) 00189 { 00190 d->iconName = "password"; 00191 init(); 00192 } 00193 00194 KPasswordDialog::KPasswordDialog(Types type, bool enableKeep, int extraBttn, const TQString& icon, 00195 TQWidget *parent, const char *name ) 00196 : KDialogBase(parent, name, true, "", Ok|Cancel|extraBttn, 00197 Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), m_keepWarnLbl(0), d(new KPasswordDialogPrivate) 00198 { 00199 if ( icon.stripWhiteSpace().isEmpty() ) 00200 d->iconName = "password"; 00201 else 00202 d->iconName = icon; 00203 init(); 00204 } 00205 00206 KPasswordDialog::KPasswordDialog(int type, TQString prompt, bool enableKeep, 00207 int extraBttn) 00208 : KDialogBase(0L, "Password Dialog", true, "", Ok|Cancel|extraBttn, 00209 Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), m_keepWarnLbl(0), d(new KPasswordDialogPrivate) 00210 { 00211 d->iconName = "password"; 00212 init(); 00213 setPrompt(prompt); 00214 } 00215 00216 void KPasswordDialog::init() 00217 { 00218 m_Row = 0; 00219 00220 TDEConfig* const cfg = TDEGlobal::config(); 00221 const TDEConfigGroupSaver saver(cfg, "Passwords"); 00222 bool def = ( qstrcmp( tqAppName(), "tdesu" ) == 0 ? defKeep : false ); 00223 if (m_Keep && cfg->readBoolEntry("Keep", def)) 00224 ++m_Keep; 00225 00226 m_pMain = new TQWidget(this); 00227 setMainWidget(m_pMain); 00228 m_pGrid = new TQGridLayout(m_pMain, 10, 3, 0, 0); 00229 m_pGrid->addColSpacing(1, 10); 00230 00231 // Row 1: pixmap + prompt 00232 TQLabel *lbl; 00233 const TQPixmap pix( TDEGlobal::iconLoader()->loadIcon( d->iconName, TDEIcon::NoGroup, TDEIcon::SizeHuge, 0, 0, true)); 00234 if (!pix.isNull()) { 00235 lbl = new TQLabel(m_pMain); 00236 lbl->setPixmap(pix); 00237 lbl->setAlignment(AlignHCenter|AlignVCenter); 00238 lbl->setFixedSize(lbl->sizeHint()); 00239 m_pGrid->addWidget(lbl, 0, 0, (TQ_Alignment)AlignCenter); 00240 } 00241 00242 m_pHelpLbl = new TQLabel(m_pMain); 00243 m_pHelpLbl->setAlignment(AlignLeft|AlignVCenter|WordBreak); 00244 m_pGrid->addWidget(m_pHelpLbl, 0, 2, (TQ_Alignment)AlignLeft); 00245 m_pGrid->addRowSpacing(1, 10); 00246 m_pGrid->setRowStretch(1, 12); 00247 00248 // Row 2+: space for 4 extra info lines 00249 m_pGrid->addRowSpacing(6, 5); 00250 m_pGrid->setRowStretch(6, 12); 00251 00252 // Row 3: Password editor #1 00253 lbl = new TQLabel(m_pMain); 00254 lbl->setAlignment(AlignLeft|AlignVCenter); 00255 lbl->setText(i18n("&Password:")); 00256 lbl->setFixedSize(lbl->sizeHint()); 00257 m_pGrid->addWidget(lbl, 7, 0, (TQ_Alignment)AlignLeft); 00258 00259 TQHBoxLayout *h_lay = new TQHBoxLayout(); 00260 m_pGrid->addLayout(h_lay, 7, 2); 00261 m_pEdit = new KPasswordEdit(m_pMain); 00262 m_pEdit2 = 0; 00263 lbl->setBuddy(m_pEdit); 00264 TQSize size = m_pEdit->sizeHint(); 00265 m_pEdit->setFixedHeight(size.height()); 00266 m_pEdit->setMinimumWidth(size.width()); 00267 h_lay->addWidget(m_pEdit); 00268 00269 // Row 4: Password editor #2 or keep password checkbox 00270 00271 if ((m_Type == Password) && m_Keep) { 00272 m_pGrid->addRowSpacing(8, 10); 00273 m_pGrid->setRowStretch(8, 12); 00274 TQCheckBox* const cb = new TQCheckBox(i18n("&Keep password"), m_pMain); 00275 cb->setFixedSize(cb->sizeHint()); 00276 m_keepWarnLbl = new TQLabel(m_pMain); 00277 m_keepWarnLbl->setAlignment(AlignLeft|AlignVCenter|WordBreak); 00278 if (m_Keep > 1) { 00279 cb->setChecked(true); 00280 m_keepWarnLbl->show(); 00281 } 00282 else { 00283 m_Keep = 0; 00284 m_keepWarnLbl->hide(); 00285 } 00286 connect(cb, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotKeep(bool))); 00287 m_pGrid->addWidget(cb, 9, 2, (TQ_Alignment)(AlignLeft|AlignVCenter)); 00288 // m_pGrid->addWidget(m_keepWarnLbl, 13, 2, (TQ_Alignment)(AlignLeft|AlignVCenter)); 00289 m_pGrid->addMultiCellWidget(m_keepWarnLbl, 13, 13, 0, 3); 00290 } else if (m_Type == NewPassword) { 00291 m_pGrid->addRowSpacing(8, 10); 00292 lbl = new TQLabel(m_pMain); 00293 lbl->setAlignment(AlignLeft|AlignVCenter); 00294 lbl->setText(i18n("&Verify:")); 00295 lbl->setFixedSize(lbl->sizeHint()); 00296 m_pGrid->addWidget(lbl, 9, 0, (TQ_Alignment)AlignLeft); 00297 00298 h_lay = new TQHBoxLayout(); 00299 m_pGrid->addLayout(h_lay, 9, 2); 00300 m_pEdit2 = new KPasswordEdit(m_pMain); 00301 lbl->setBuddy(m_pEdit2); 00302 size = m_pEdit2->sizeHint(); 00303 m_pEdit2->setFixedHeight(size.height()); 00304 m_pEdit2->setMinimumWidth(size.width()); 00305 h_lay->addWidget(m_pEdit2); 00306 00307 // Row 6: Password strength meter 00308 m_pGrid->addRowSpacing(10, 10); 00309 m_pGrid->setRowStretch(10, 12); 00310 00311 TQHBox* const strengthBox = new TQHBox(m_pMain); 00312 strengthBox->setSpacing(10); 00313 m_pGrid->addMultiCellWidget(strengthBox, 11, 11, 0, 2); 00314 TQLabel* const passStrengthLabel = new TQLabel(strengthBox); 00315 passStrengthLabel->setAlignment(AlignLeft|AlignVCenter); 00316 passStrengthLabel->setText(i18n("Password strength meter:")); 00317 d->m_strengthBar = new KProgress(100, strengthBox, "PasswordStrengthMeter"); 00318 d->m_strengthBar->setPercentageVisible(false); 00319 00320 const TQString strengthBarWhatsThis(i18n("The password strength meter gives an indication of the security " 00321 "of the password you have entered. To improve the strength of " 00322 "the password, try:\n" 00323 " - using a longer password;\n" 00324 " - using a mixture of upper- and lower-case letters;\n" 00325 " - using numbers or symbols, such as #, as well as letters.")); 00326 TQWhatsThis::add(passStrengthLabel, strengthBarWhatsThis); 00327 TQWhatsThis::add(d->m_strengthBar, strengthBarWhatsThis); 00328 00329 // Row 6: Label saying whether the passwords match 00330 m_pGrid->addRowSpacing(12, 10); 00331 m_pGrid->setRowStretch(12, 12); 00332 00333 d->m_MatchLabel = new TQLabel(m_pMain); 00334 d->m_MatchLabel->setAlignment(AlignLeft|AlignVCenter|WordBreak); 00335 m_pGrid->addMultiCellWidget(d->m_MatchLabel, 13, 13, 0, 2); 00336 d->m_MatchLabel->setText(i18n("Passwords do not match")); 00337 00338 00339 connect( m_pEdit, TQT_SIGNAL(textChanged(const TQString&)), TQT_SLOT(enableOkBtn()) ); 00340 connect( m_pEdit2, TQT_SIGNAL(textChanged(const TQString&)), TQT_SLOT(enableOkBtn()) ); 00341 enableOkBtn(); 00342 } 00343 00344 erase(); 00345 } 00346 00347 00348 KPasswordDialog::~KPasswordDialog() 00349 { 00350 delete d; 00351 } 00352 00353 00354 void KPasswordDialog::clearPassword() 00355 { 00356 m_pEdit->erase(); 00357 } 00358 00359 /* KDE 4: Make it const TQString & */ 00360 void KPasswordDialog::setPrompt(TQString prompt) 00361 { 00362 m_pHelpLbl->setText(prompt); 00363 m_pHelpLbl->setFixedSize(275, m_pHelpLbl->heightForWidth(275)); 00364 } 00365 00366 void KPasswordDialog::setKeepWarning(TQString warn) 00367 { 00368 if (m_keepWarnLbl) { 00369 m_keepWarnLbl->setText(warn); 00370 } 00371 } 00372 00373 00374 TQString KPasswordDialog::prompt() const 00375 00376 { 00377 return m_pHelpLbl->text(); 00378 } 00379 00380 00381 /* KDE 4: Make them const TQString & */ 00382 void KPasswordDialog::addLine(TQString key, TQString value) 00383 { 00384 if (m_Row > 3) 00385 return; 00386 00387 TQLabel *lbl = new TQLabel(key, m_pMain); 00388 lbl->setAlignment(AlignLeft|AlignTop); 00389 lbl->setFixedSize(lbl->sizeHint()); 00390 m_pGrid->addWidget(lbl, m_Row+2, 0, (TQ_Alignment)AlignLeft); 00391 00392 lbl = new TQLabel(value, m_pMain); 00393 lbl->setAlignment(AlignTop|WordBreak); 00394 lbl->setFixedSize(275, lbl->heightForWidth(275)); 00395 m_pGrid->addWidget(lbl, m_Row+2, 2, (TQ_Alignment)AlignLeft); 00396 ++m_Row; 00397 } 00398 00399 00400 void KPasswordDialog::erase() 00401 { 00402 m_pEdit->erase(); 00403 m_pEdit->setFocus(); 00404 if (m_Type == NewPassword) 00405 m_pEdit2->erase(); 00406 } 00407 00408 00409 void KPasswordDialog::slotOk() 00410 { 00411 if (m_Type == NewPassword) { 00412 if (strcmp(m_pEdit->password(), m_pEdit2->password())) { 00413 KMessageBox::sorry(this, i18n("You entered two different " 00414 "passwords. Please try again.")); 00415 erase(); 00416 return; 00417 } 00418 if (d->m_strengthBar && d->m_strengthBar->progress() < d->passwordStrengthWarningLevel) { 00419 int retVal = KMessageBox::warningContinueCancel(this, 00420 i18n( "The password you have entered has a low strength. " 00421 "To improve the strength of " 00422 "the password, try:\n" 00423 " - using a longer password;\n" 00424 " - using a mixture of upper- and lower-case letters;\n" 00425 " - using numbers or symbols as well as letters.\n" 00426 "\n" 00427 "Would you like to use this password anyway?"), 00428 i18n("Low Password Strength")); 00429 if (retVal == KMessageBox::Cancel) return; 00430 } 00431 } 00432 if (!checkPassword(m_pEdit->password())) { 00433 erase(); 00434 return; 00435 } 00436 accept(); 00437 } 00438 00439 00440 void KPasswordDialog::slotCancel() 00441 { 00442 reject(); 00443 } 00444 00445 00446 void KPasswordDialog::slotKeep(bool keep) 00447 { 00448 if (m_keepWarnLbl->text() != "") { 00449 if (keep) { 00450 m_keepWarnLbl->show(); 00451 } 00452 else { 00453 m_keepWarnLbl->hide(); 00454 } 00455 TQTimer::singleShot(0, this, SLOT(slotLayout())); 00456 } 00457 00458 m_Keep = keep; 00459 } 00460 00461 void KPasswordDialog::slotLayout() 00462 { 00463 resize(sizeHint()); 00464 } 00465 00466 00467 // static . antlarr: KDE 4: Make it const TQString & prompt 00468 int KPasswordDialog::getPassword(TQCString &password, TQString prompt, 00469 int *keep) 00470 { 00471 const bool enableKeep = (keep && *keep); 00472 KPasswordDialog* const dlg = new KPasswordDialog(int(Password), prompt, enableKeep); 00473 const int ret = dlg->exec(); 00474 if (ret == Accepted) { 00475 password = dlg->password(); 00476 if (enableKeep) 00477 *keep = dlg->keep(); 00478 } 00479 delete dlg; 00480 return ret; 00481 } 00482 00483 00484 // static . antlarr: KDE 4: Make it const TQString & prompt 00485 int KPasswordDialog::getNewPassword(TQCString &password, TQString prompt) 00486 { 00487 KPasswordDialog* const dlg = new KPasswordDialog(NewPassword, prompt); 00488 const int ret = dlg->exec(); 00489 if (ret == Accepted) 00490 password = dlg->password(); 00491 delete dlg; 00492 return ret; 00493 } 00494 00495 00496 // static 00497 void KPasswordDialog::disableCoreDumps() 00498 { 00499 struct rlimit rlim; 00500 rlim.rlim_cur = rlim.rlim_max = 0; 00501 setrlimit(RLIMIT_CORE, &rlim); 00502 } 00503 00504 void KPasswordDialog::virtual_hook( int id, void* data ) 00505 { KDialogBase::virtual_hook( id, data ); } 00506 00507 void KPasswordDialog::enableOkBtn() 00508 { 00509 if (m_Type == NewPassword) { 00510 const bool match = strcmp(m_pEdit->password(), m_pEdit2->password()) == 0 00511 && (d->allowEmptyPasswords || m_pEdit->password()[0]); 00512 00513 const TQString pass(m_pEdit->password()); 00514 00515 const int minPasswordLength = minimumPasswordLength(); 00516 00517 if ((int) pass.length() < minPasswordLength) { 00518 enableButtonOK(false); 00519 } else { 00520 enableButtonOK( match ); 00521 } 00522 00523 if ( match && d->allowEmptyPasswords && m_pEdit->password()[0] == 0 ) { 00524 d->m_MatchLabel->setText( i18n("Password is empty") ); 00525 } else { 00526 if ((int) pass.length() < minPasswordLength) { 00527 d->m_MatchLabel->setText(i18n("Password must be at least 1 character long", "Password must be at least %n characters long", minPasswordLength)); 00528 } else { 00529 d->m_MatchLabel->setText( match? i18n("Passwords match") 00530 :i18n("Passwords do not match") ); 00531 } 00532 } 00533 00534 // Password strength calculator 00535 // Based on code in the Master Password dialog in Firefox 00536 // (pref-masterpass.js) 00537 // Original code triple-licensed under the MPL, GPL, and LGPL 00538 // so is license-compatible with this file 00539 00540 const double lengthFactor = d->reasonablePasswordLength / 8.0; 00541 00542 00543 int pwlength = (int) (pass.length() / lengthFactor); 00544 if (pwlength > 5) pwlength = 5; 00545 00546 const TQRegExp numRxp("[0-9]", true, false); 00547 int numeric = (int) (pass.contains(numRxp) / lengthFactor); 00548 if (numeric > 3) numeric = 3; 00549 00550 const TQRegExp symbRxp("\\W", false, false); 00551 int numsymbols = (int) (pass.contains(symbRxp) / lengthFactor); 00552 if (numsymbols > 3) numsymbols = 3; 00553 00554 const TQRegExp upperRxp("[A-Z]", true, false); 00555 int upper = (int) (pass.contains(upperRxp) / lengthFactor); 00556 if (upper > 3) upper = 3; 00557 00558 int pwstrength=((pwlength*10)-20) + (numeric*10) + (numsymbols*15) + (upper*10); 00559 00560 if ( pwstrength < 0 ) { 00561 pwstrength = 0; 00562 } 00563 00564 if ( pwstrength > 100 ) { 00565 pwstrength = 100; 00566 } 00567 d->m_strengthBar->setProgress(pwstrength); 00568 00569 } 00570 } 00571 00572 00573 void KPasswordDialog::setAllowEmptyPasswords(bool allowed) { 00574 d->allowEmptyPasswords = allowed; 00575 enableOkBtn(); 00576 } 00577 00578 00579 bool KPasswordDialog::allowEmptyPasswords() const { 00580 return d->allowEmptyPasswords; 00581 } 00582 00583 void KPasswordDialog::setMinimumPasswordLength(int minLength) { 00584 d->minimumPasswordLength = minLength; 00585 enableOkBtn(); 00586 } 00587 00588 int KPasswordDialog::minimumPasswordLength() const { 00589 return d->minimumPasswordLength; 00590 } 00591 00592 void KPasswordDialog::setMaximumPasswordLength(int maxLength) { 00593 00594 if (maxLength < 0) maxLength = 0; 00595 if (maxLength >= KPasswordEdit::PassLen) maxLength = KPasswordEdit::PassLen - 1; 00596 00597 d->maximumPasswordLength = maxLength; 00598 00599 m_pEdit->setMaxPasswordLength(maxLength); 00600 if (m_pEdit2) m_pEdit2->setMaxPasswordLength(maxLength); 00601 00602 } 00603 00604 int KPasswordDialog::maximumPasswordLength() const { 00605 return d->maximumPasswordLength; 00606 } 00607 00608 // reasonable password length code contributed by Steffen Mthing 00609 00610 void KPasswordDialog::setReasonablePasswordLength(int reasonableLength) { 00611 00612 if (reasonableLength < 1) reasonableLength = 1; 00613 if (reasonableLength >= maximumPasswordLength()) reasonableLength = maximumPasswordLength(); 00614 00615 d->reasonablePasswordLength = reasonableLength; 00616 00617 } 00618 00619 int KPasswordDialog::reasonablePasswordLength() const { 00620 return d->reasonablePasswordLength; 00621 } 00622 00623 00624 void KPasswordDialog::setPasswordStrengthWarningLevel(int warningLevel) { 00625 if (warningLevel < 0) warningLevel = 0; 00626 if (warningLevel > 99) warningLevel = 99; 00627 d->passwordStrengthWarningLevel = warningLevel; 00628 } 00629 00630 int KPasswordDialog::passwordStrengthWarningLevel() const { 00631 return d->passwordStrengthWarningLevel; 00632 } 00633 00634 #include "kpassdlg.moc"