KDEUI
knewpassworddialog.cpp
Go to the documentation of this file.
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 Copyright (C) 2007 Michaƫl Larouche <larouche@kde.org> 00007 Copyright (C) 2009 Christoph Feck <christoph@maxiom.de> 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Library General Public 00011 License version 2 as published by the Free Software Foundation. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Library General Public License for more details. 00017 00018 You should have received a copy of the GNU Library General Public License 00019 along with this library; see the file COPYING.LIB. If not, write to 00020 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00021 Boston, MA 02110-1301, USA. 00022 */ 00023 #include "knewpassworddialog.h" 00024 00025 #include <QtGui/QApplication> 00026 #include <QtGui/QProgressBar> 00027 #include <QtCore/QRegExp> 00028 #include <QtCore/QSize> 00029 #include <QtCore/QString> 00030 00031 #include <kapplication.h> 00032 #include <kglobal.h> 00033 #include <kicon.h> 00034 #include <klocale.h> 00035 #include <kmessagebox.h> 00036 #include <klineedit.h> 00037 #include <ktitlewidget.h> 00038 00039 #include "ui_knewpassworddialog.h" 00040 00041 class KNewPasswordDialog::KNewPasswordDialogPrivate 00042 { 00043 public: 00044 KNewPasswordDialogPrivate( KNewPasswordDialog *parent ) 00045 : q( parent ), 00046 minimumPasswordLength(0), passwordStrengthWarningLevel(1),reasonablePasswordLength(8) 00047 {} 00048 00049 void init(); 00050 void _k_textChanged(); 00051 00052 KNewPasswordDialog *q; 00053 00054 int minimumPasswordLength; 00055 int passwordStrengthWarningLevel; 00056 int reasonablePasswordLength; 00057 00058 int effectivePasswordLength(const QString &password); 00059 00060 QString pass; 00061 00062 Ui::KNewPasswordDialog ui; 00063 }; 00064 00065 00066 void KNewPasswordDialog::KNewPasswordDialogPrivate::init() 00067 { 00068 q->setButtons( Ok | Cancel ); 00069 q->setDefaultButton( Ok ); 00070 00071 ui.setupUi( q->mainWidget() ); 00072 00073 ui.labelIcon->setPixmap( KIcon("dialog-password").pixmap(96, 96) ); 00074 ui.labelMatch->setHidden(true); 00075 00076 const QString strengthBarWhatsThis(i18n("The password strength meter gives an indication of the security " 00077 "of the password you have entered. To improve the strength of " 00078 "the password, try:\n" 00079 " - using a longer password;\n" 00080 " - using a mixture of upper- and lower-case letters;\n" 00081 " - using numbers or symbols, such as #, as well as letters.")); 00082 ui.labelStrengthMeter->setWhatsThis(strengthBarWhatsThis); 00083 ui.strengthBar->setWhatsThis(strengthBarWhatsThis); 00084 00085 connect( ui.linePassword, SIGNAL(textChanged(const QString&)), q, SLOT(_k_textChanged()) ); 00086 connect( ui.lineVerifyPassword, SIGNAL(textChanged(const QString&)), q, SLOT(_k_textChanged()) ); 00087 00088 _k_textChanged(); 00089 } 00090 00091 00092 int KNewPasswordDialog::KNewPasswordDialogPrivate::effectivePasswordLength(const QString &password) 00093 { 00094 enum Category { 00095 Digit, 00096 Upper, 00097 Vowel, 00098 Consonant, 00099 Special 00100 }; 00101 00102 Category previousCategory = Vowel; 00103 QString vowels("aeiou"); 00104 int count = 0; 00105 00106 for (int i = 0; i < password.length(); ++i) { 00107 QChar currentChar = password.at(i); 00108 if (!password.left(i).contains(currentChar)) { 00109 Category currentCategory; 00110 switch (currentChar.category()) { 00111 case QChar::Letter_Uppercase: 00112 currentCategory = Upper; 00113 break; 00114 case QChar::Letter_Lowercase: 00115 if (vowels.contains(currentChar)) { 00116 currentCategory = Vowel; 00117 } else { 00118 currentCategory = Consonant; 00119 } 00120 break; 00121 case QChar::Number_DecimalDigit: 00122 currentCategory = Digit; 00123 break; 00124 default: 00125 currentCategory = Special; 00126 break; 00127 } 00128 switch (currentCategory) { 00129 case Vowel: 00130 if (previousCategory != Consonant) { 00131 ++count; 00132 } 00133 break; 00134 case Consonant: 00135 if (previousCategory != Vowel) { 00136 ++count; 00137 } 00138 break; 00139 default: 00140 if (previousCategory != currentCategory) { 00141 ++count; 00142 } 00143 break; 00144 } 00145 previousCategory = currentCategory; 00146 } 00147 } 00148 return count; 00149 } 00150 00151 00152 void KNewPasswordDialog::KNewPasswordDialogPrivate::_k_textChanged() 00153 { 00154 const bool match = ui.linePassword->text() == ui.lineVerifyPassword->text(); 00155 00156 const int minPasswordLength = q->minimumPasswordLength(); 00157 00158 if ( ui.linePassword->text().length() < minPasswordLength) { 00159 q->enableButtonOk(false); 00160 } else { 00161 q->enableButtonOk( match ); 00162 } 00163 00164 if ( match && !q->allowEmptyPasswords() && ui.linePassword->text().isEmpty()) { 00165 ui.labelMatch->setPixmap( KIcon("dialog-error") ); 00166 ui.labelMatch->setText( i18n("Password is empty") ); 00167 } 00168 else { 00169 if ( ui.linePassword->text().length() < minPasswordLength ) { 00170 ui.labelMatch->setPixmap( KIcon("dialog-error") ); 00171 ui.labelMatch->setText(i18np("Password must be at least 1 character long", "Password must be at least %1 characters long", minPasswordLength)); 00172 } else { 00173 ui.labelMatch->setPixmap( match ? KIcon("dialog-ok") : KIcon("dialog-error") ); 00174 // "ok" icon should probably be "dialog-success", but we don't have that icon in KDE 4.0 00175 ui.labelMatch->setText( match? i18n("Passwords match") 00176 :i18n("Passwords do not match") ); 00177 } 00178 } 00179 00180 // Password strength calculator 00181 int pwstrength = (20 * ui.linePassword->text().length() + 80 * effectivePasswordLength(ui.linePassword->text())) / qMax(reasonablePasswordLength, 2); 00182 if (pwstrength < 0) { 00183 pwstrength = 0; 00184 } else if (pwstrength > 100) { 00185 pwstrength = 100; 00186 } 00187 ui.strengthBar->setValue(pwstrength); 00188 } 00189 00190 /* 00191 * Password dialog. 00192 */ 00193 00194 KNewPasswordDialog::KNewPasswordDialog( QWidget *parent) 00195 : KDialog(parent), d(new KNewPasswordDialogPrivate(this)) 00196 { 00197 d->init(); 00198 } 00199 00200 00201 KNewPasswordDialog::~KNewPasswordDialog() 00202 { 00203 delete d; 00204 } 00205 00206 00207 void KNewPasswordDialog::setPrompt(const QString &prompt) 00208 { 00209 d->ui.labelPrompt->setText(prompt); 00210 } 00211 00212 00213 QString KNewPasswordDialog::prompt() const 00214 { 00215 return d->ui.labelPrompt->text(); 00216 } 00217 00218 00219 void KNewPasswordDialog::setPixmap(const QPixmap &pixmap) 00220 { 00221 d->ui.labelIcon->setPixmap(pixmap); 00222 d->ui.labelIcon->setFixedSize( d->ui.labelIcon->sizeHint() ); 00223 } 00224 00225 00226 QPixmap KNewPasswordDialog::pixmap() const 00227 { 00228 return *d->ui.labelIcon->pixmap(); 00229 } 00230 00231 bool KNewPasswordDialog::checkAndGetPassword(QString *pwd) 00232 { 00233 pwd->clear(); 00234 if ( d->ui.linePassword->text() != d->ui.lineVerifyPassword->text() ) { 00235 d->ui.labelMatch->setPixmap( KTitleWidget::ErrorMessage ); 00236 d->ui.labelMatch->setText( i18n("You entered two different " 00237 "passwords. Please try again.") ); 00238 00239 d->ui.linePassword->clear(); 00240 d->ui.lineVerifyPassword->clear(); 00241 return false; 00242 } 00243 if (d->ui.strengthBar && d->ui.strengthBar->value() < d->passwordStrengthWarningLevel) { 00244 int retVal = KMessageBox::warningYesNo(this, 00245 i18n( "The password you have entered has a low strength. " 00246 "To improve the strength of " 00247 "the password, try:\n" 00248 " - using a longer password;\n" 00249 " - using a mixture of upper- and lower-case letters;\n" 00250 " - using numbers or symbols as well as letters.\n" 00251 "\n" 00252 "Would you like to use this password anyway?"), 00253 i18n("Low Password Strength")); 00254 if (retVal == KMessageBox::No) return false; 00255 } 00256 if ( !checkPassword(d->ui.linePassword->text()) ) { 00257 return false; 00258 } 00259 00260 *pwd = d->ui.linePassword->text(); 00261 return true; 00262 } 00263 00264 void KNewPasswordDialog::accept() 00265 { 00266 QString pwd; 00267 if (!checkAndGetPassword(&pwd)) { 00268 return; 00269 } 00270 d->pass = pwd; 00271 emit newPassword( d->pass ); 00272 KDialog::accept(); 00273 } 00274 00275 00276 void KNewPasswordDialog::setAllowEmptyPasswords(bool allowed) 00277 { 00278 setMinimumPasswordLength( allowed ? 0 : 1 ); 00279 d->_k_textChanged(); 00280 } 00281 00282 00283 bool KNewPasswordDialog::allowEmptyPasswords() const 00284 { 00285 return d->minimumPasswordLength == 0; 00286 } 00287 00288 void KNewPasswordDialog::setMinimumPasswordLength(int minLength) 00289 { 00290 d->minimumPasswordLength = minLength; 00291 d->_k_textChanged(); 00292 } 00293 00294 int KNewPasswordDialog::minimumPasswordLength() const 00295 { 00296 return d->minimumPasswordLength; 00297 } 00298 00299 void KNewPasswordDialog::setMaximumPasswordLength(int maxLength) 00300 { 00301 d->ui.linePassword->setMaxLength(maxLength); 00302 d->ui.lineVerifyPassword->setMaxLength(maxLength); 00303 } 00304 00305 int KNewPasswordDialog::maximumPasswordLength() const 00306 { 00307 return d->ui.linePassword->maxLength(); 00308 } 00309 00310 // reasonable password length code contributed by Steffen Mthing 00311 00312 void KNewPasswordDialog::setReasonablePasswordLength(int reasonableLength) 00313 { 00314 00315 if (reasonableLength < 1) { 00316 reasonableLength = 1; 00317 } 00318 if (reasonableLength >= maximumPasswordLength()) { 00319 reasonableLength = maximumPasswordLength(); 00320 } 00321 00322 d->reasonablePasswordLength = reasonableLength; 00323 00324 } 00325 00326 int KNewPasswordDialog::reasonablePasswordLength() const 00327 { 00328 return d->reasonablePasswordLength; 00329 } 00330 00331 00332 void KNewPasswordDialog::setPasswordStrengthWarningLevel(int warningLevel) 00333 { 00334 if (warningLevel < 0) { 00335 warningLevel = 0; 00336 } 00337 if (warningLevel > 99) { 00338 warningLevel = 99; 00339 } 00340 d->passwordStrengthWarningLevel = warningLevel; 00341 } 00342 00343 int KNewPasswordDialog::passwordStrengthWarningLevel() const 00344 { 00345 return d->passwordStrengthWarningLevel; 00346 } 00347 00348 QString KNewPasswordDialog::password() const 00349 { 00350 return d->pass; 00351 } 00352 00353 bool KNewPasswordDialog::checkPassword(const QString &) 00354 { 00355 return true; 00356 } 00357 00358 #include "knewpassworddialog.moc" 00359 00360 // kate: space-indent on; indent-width 4; encoding utf-8; replace-tabs on;
KDE 4.6 API Reference