• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

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->showButtonSeparator( true );
00070     q->setDefaultButton( Ok );
00071 
00072     ui.setupUi( q->mainWidget() );
00073 
00074     ui.labelIcon->setPixmap( KIcon("dialog-password").pixmap(96, 96) );
00075     ui.labelMatch->setHidden(true);
00076 
00077     const QString strengthBarWhatsThis(i18n("The password strength meter gives an indication of the security "
00078             "of the password you have entered.  To improve the strength of "
00079             "the password, try:\n"
00080             " - using a longer password;\n"
00081             " - using a mixture of upper- and lower-case letters;\n"
00082             " - using numbers or symbols, such as #, as well as letters."));
00083     ui.labelStrengthMeter->setWhatsThis(strengthBarWhatsThis);
00084     ui.strengthBar->setWhatsThis(strengthBarWhatsThis);
00085 
00086     connect( ui.linePassword, SIGNAL(textChanged(const QString&)), q, SLOT(_k_textChanged()) );
00087     connect( ui.lineVerifyPassword, SIGNAL(textChanged(const QString&)), q, SLOT(_k_textChanged()) );
00088 
00089     _k_textChanged();
00090 }
00091 
00092 
00093 int KNewPasswordDialog::KNewPasswordDialogPrivate::effectivePasswordLength(const QString &password)
00094 {
00095     enum Category {
00096         Digit,
00097         Upper,
00098         Vowel,
00099         Consonant,
00100         Special
00101     };
00102 
00103     Category previousCategory = Vowel;
00104     QString vowels("aeiou");
00105     int count = 0;
00106 
00107     for (int i = 0; i < password.length(); ++i) {
00108         QChar currentChar = password.at(i);
00109         if (!password.left(i).contains(currentChar)) {
00110             Category currentCategory;
00111             switch (currentChar.category()) {
00112                 case QChar::Letter_Uppercase:
00113                     currentCategory = Upper;
00114                     break;
00115                 case QChar::Letter_Lowercase:
00116                     if (vowels.contains(currentChar)) {
00117                         currentCategory = Vowel;
00118                     } else {
00119                         currentCategory = Consonant;
00120                     }
00121                     break;
00122                 case QChar::Number_DecimalDigit:
00123                     currentCategory = Digit;
00124                     break;
00125                 default:
00126                     currentCategory = Special;
00127                     break;
00128             }
00129             switch (currentCategory) {
00130                 case Vowel:
00131                     if (previousCategory != Consonant) {
00132                         ++count;
00133                     }
00134                     break;
00135                 case Consonant:
00136                     if (previousCategory != Vowel) {
00137                         ++count;
00138                     }
00139                     break;
00140                 default:
00141                     if (previousCategory != currentCategory) {
00142                         ++count;
00143                     }
00144                     break;
00145             }
00146             previousCategory = currentCategory;
00147         }
00148     }
00149     return count;
00150 }
00151 
00152 
00153 void KNewPasswordDialog::KNewPasswordDialogPrivate::_k_textChanged()
00154 {
00155     const bool match = ui.linePassword->text() == ui.lineVerifyPassword->text();
00156 
00157     const int minPasswordLength = q->minimumPasswordLength();
00158 
00159     if ( ui.linePassword->text().length() < minPasswordLength) {
00160         q->enableButtonOk(false);
00161     } else {
00162         q->enableButtonOk( match );
00163     }
00164 
00165     if ( match && !q->allowEmptyPasswords() && ui.linePassword->text().isEmpty()) {
00166         ui.labelMatch->setPixmap( KIcon("dialog-error") );
00167         ui.labelMatch->setText( i18n("Password is empty") );
00168     }
00169     else {
00170         if ( ui.linePassword->text().length() < minPasswordLength ) {
00171             ui.labelMatch->setPixmap( KIcon("dialog-error") );
00172             ui.labelMatch->setText(i18np("Password must be at least 1 character long", "Password must be at least %1 characters long", minPasswordLength));
00173         } else {
00174             ui.labelMatch->setPixmap( match ? KIcon("dialog-ok") : KIcon("dialog-error") );
00175             // "ok" icon should probably be "dialog-success", but we don't have that icon in KDE 4.0
00176             ui.labelMatch->setText( match? i18n("Passwords match")
00177                 :i18n("Passwords do not match") );
00178         }
00179     }
00180 
00181     // Password strength calculator
00182     int pwstrength = (20 * ui.linePassword->text().length() + 80 * effectivePasswordLength(ui.linePassword->text())) / qMax(reasonablePasswordLength, 2);
00183     if (pwstrength < 0) {
00184         pwstrength = 0;
00185     } else if (pwstrength > 100) {
00186         pwstrength = 100;
00187     }
00188     ui.strengthBar->setValue(pwstrength);
00189 }
00190 
00191 /*
00192  * Password dialog.
00193  */
00194 
00195 KNewPasswordDialog::KNewPasswordDialog( QWidget *parent)
00196     : KDialog(parent), d(new KNewPasswordDialogPrivate(this))
00197 {
00198     d->init();
00199 }
00200 
00201 
00202 KNewPasswordDialog::~KNewPasswordDialog()
00203 {
00204     delete d;
00205 }
00206 
00207 
00208 void KNewPasswordDialog::setPrompt(const QString &prompt)
00209 {
00210     d->ui.labelPrompt->setText(prompt);
00211 }
00212 
00213 
00214 QString KNewPasswordDialog::prompt() const
00215 {
00216     return d->ui.labelPrompt->text();
00217 }
00218 
00219 
00220 void KNewPasswordDialog::setPixmap(const QPixmap &pixmap)
00221 {
00222     d->ui.labelIcon->setPixmap(pixmap);
00223     d->ui.labelIcon->setFixedSize( d->ui.labelIcon->sizeHint() );
00224 }
00225 
00226 
00227 QPixmap KNewPasswordDialog::pixmap() const
00228 {
00229     return *d->ui.labelIcon->pixmap();
00230 }
00231 
00232 bool KNewPasswordDialog::checkAndGetPassword(QString *pwd)
00233 {
00234     pwd->clear();
00235     if ( d->ui.linePassword->text() != d->ui.lineVerifyPassword->text() ) {
00236         d->ui.labelMatch->setPixmap( KTitleWidget::ErrorMessage );
00237         d->ui.labelMatch->setText( i18n("You entered two different "
00238                 "passwords. Please try again.") );
00239 
00240         d->ui.linePassword->clear();
00241         d->ui.lineVerifyPassword->clear();
00242         return false;
00243     }
00244     if (d->ui.strengthBar && d->ui.strengthBar->value() < d->passwordStrengthWarningLevel) {
00245         int retVal = KMessageBox::warningYesNo(this,
00246                 i18n(   "The password you have entered has a low strength. "
00247                         "To improve the strength of "
00248                         "the password, try:\n"
00249                         " - using a longer password;\n"
00250                         " - using a mixture of upper- and lower-case letters;\n"
00251                         " - using numbers or symbols as well as letters.\n"
00252                         "\n"
00253                         "Would you like to use this password anyway?"),
00254                 i18n("Low Password Strength"));
00255         if (retVal == KMessageBox::No) return false;
00256     }
00257     if ( !checkPassword(d->ui.linePassword->text()) ) {
00258         return false;
00259     }
00260 
00261     *pwd = d->ui.linePassword->text();
00262     return true;
00263 }
00264 
00265 void KNewPasswordDialog::accept()
00266 {
00267     QString pwd;
00268     if (!checkAndGetPassword(&pwd)) {
00269         return;
00270     }
00271     d->pass = pwd;
00272     emit newPassword( d->pass );
00273     KDialog::accept();
00274 }
00275 
00276 
00277 void KNewPasswordDialog::setAllowEmptyPasswords(bool allowed)
00278 {
00279     setMinimumPasswordLength( allowed ? 0 : 1 );
00280     d->_k_textChanged();
00281 }
00282 
00283 
00284 bool KNewPasswordDialog::allowEmptyPasswords() const
00285 {
00286     return d->minimumPasswordLength == 0;
00287 }
00288 
00289 void KNewPasswordDialog::setMinimumPasswordLength(int minLength)
00290 {
00291     d->minimumPasswordLength = minLength;
00292     d->_k_textChanged();
00293 }
00294 
00295 int KNewPasswordDialog::minimumPasswordLength() const
00296 {
00297     return d->minimumPasswordLength;
00298 }
00299 
00300 void KNewPasswordDialog::setMaximumPasswordLength(int maxLength)
00301 {
00302     d->ui.linePassword->setMaxLength(maxLength);
00303     d->ui.lineVerifyPassword->setMaxLength(maxLength);
00304 }
00305 
00306 int KNewPasswordDialog::maximumPasswordLength() const
00307 {
00308     return d->ui.linePassword->maxLength();
00309 }
00310 
00311 // reasonable password length code contributed by Steffen Mthing
00312 
00313 void KNewPasswordDialog::setReasonablePasswordLength(int reasonableLength)
00314 {
00315 
00316     if (reasonableLength < 1) {
00317         reasonableLength = 1;
00318     }
00319     if (reasonableLength >= maximumPasswordLength()) {
00320         reasonableLength = maximumPasswordLength();
00321     }
00322 
00323     d->reasonablePasswordLength = reasonableLength;
00324 
00325 }
00326 
00327 int KNewPasswordDialog::reasonablePasswordLength() const
00328 {
00329     return d->reasonablePasswordLength;
00330 }
00331 
00332 
00333 void KNewPasswordDialog::setPasswordStrengthWarningLevel(int warningLevel)
00334 {
00335     if (warningLevel < 0) {
00336         warningLevel = 0;
00337     }
00338     if (warningLevel > 99) {
00339         warningLevel = 99;
00340     }
00341     d->passwordStrengthWarningLevel = warningLevel;
00342 }
00343 
00344 int KNewPasswordDialog::passwordStrengthWarningLevel() const
00345 {
00346     return d->passwordStrengthWarningLevel;
00347 }
00348 
00349 QString KNewPasswordDialog::password() const 
00350 {
00351     return d->pass;
00352 }
00353 
00354 bool KNewPasswordDialog::checkPassword(const QString &)
00355 {
00356     return true;
00357 }
00358 
00359 #include "knewpassworddialog.moc"
00360 
00361 // kate: space-indent on; indent-width 4; encoding utf-8; replace-tabs on;

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal