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 <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 * Password line editor. 00054 */ 00055 00056 // BCI: Add a real d-pointer and put the int into that 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); // Just in case 00146 setAcceptDrops(false); 00147 int* t = ourMaxLength(this); 00148 *t = (PassLen - 1); // the internal max length 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: // Delete 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; //Ignore 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; // stop bubbling 00254 } 00255 00256 default: 00257 // Do nothing 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); //To update the password comparison if need be. 00278 break; 00279 } 00280 } 00281 00282 void KPasswordEdit::setMaxPasswordLength(int newLength) 00283 { 00284 if (newLength >= PassLen) newLength = PassLen - 1; // belt and braces 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 * Password dialog. 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 // Row 1: pixmap + prompt 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 // Row 2+: space for 4 extra info lines 00366 m_pGrid->addRowSpacing(6, 5); 00367 m_pGrid->setRowStretch(6, 12); 00368 00369 // Row 3: Password editor #1 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 // Row 4: Password editor #2 or keep password checkbox 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 // Row 6: Password strength meter 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 // Row 6: Label saying whether the passwords match 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 /* KDE 4: Make it const QString & */ 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 /* KDE 4: Make them const QString & */ 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 // static . antlarr: KDE 4: Make it const QString & prompt 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 // static . antlarr: KDE 4: Make it const QString & prompt 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 // static 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 // Password strength calculator 00622 // Based on code in the Master Password dialog in Firefox 00623 // (pref-masterpass.js) 00624 // Original code triple-licensed under the MPL, GPL, and LGPL 00625 // so is license-compatible with this file 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 // reasonable password length code contributed by Steffen Mthing 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"