kdeui Library API Documentation

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 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License version 2 as published by the Free Software Foundation.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018    Boston, MA 02111-1307, USA.
00019 */
00020 #include <unistd.h>
00021 
00022 #include <qwidget.h>
00023 #include <qlineedit.h>
00024 #include <qlabel.h>
00025 #include <qlayout.h>
00026 #include <qsize.h>
00027 #include <qevent.h>
00028 #include <qkeycode.h>
00029 #include <qcheckbox.h>
00030 
00031 #include <kglobal.h>
00032 #include <kdebug.h>
00033 #include <kapplication.h>
00034 #include <klocale.h>
00035 #include <kiconloader.h>
00036 #include <kmessagebox.h>
00037 #include <kaboutdialog.h>
00038 #include <kconfig.h>
00039 #include <kstandarddirs.h>
00040 
00041 #include <sys/time.h>
00042 #include <sys/resource.h>
00043 
00044 #include "kpassdlg.h"
00045 
00046 /*
00047  * Password line editor.
00048  */
00049 
00050 class KPasswordDialog::KPasswordDialogPrivate
00051 {
00052     public:
00053     KPasswordDialogPrivate()
00054         : m_MatchLabel( 0 ), iconName( 0 )
00055         {}
00056     QLabel *m_MatchLabel;
00057     QString iconName;
00058 };
00059 
00060 const int KPasswordEdit::PassLen = 200;
00061 
00062 KPasswordEdit::KPasswordEdit(QWidget *parent, const char *name)
00063     : QLineEdit(parent, name)
00064 {
00065     init();
00066 
00067     KConfig *cfg = KGlobal::config();
00068     KConfigGroupSaver saver(cfg, "Passwords");
00069 
00070     QString val = cfg->readEntry("EchoMode", "OneStar");
00071     if (val == "ThreeStars")
00072     m_EchoMode = ThreeStars;
00073     else if (val == "NoEcho")
00074     m_EchoMode = NoEcho;
00075     else
00076     m_EchoMode = OneStar;
00077 }
00078 
00079 KPasswordEdit::KPasswordEdit(QWidget *parent, const char *name, int echoMode)
00080     : QLineEdit(parent, name), m_EchoMode(echoMode)
00081 {
00082     init();
00083 }
00084 
00085 KPasswordEdit::KPasswordEdit(EchoModes echoMode, QWidget *parent, const char *name)
00086     : QLineEdit(parent, name), m_EchoMode(echoMode)
00087 {
00088     init();
00089 }
00090 
00091 KPasswordEdit::KPasswordEdit(EchoMode echoMode, QWidget *parent, const char *name)
00092     : QLineEdit(parent, name)
00093     , m_EchoMode( echoMode == QLineEdit::NoEcho ? NoEcho : OneStar )
00094 {
00095     init();
00096 }
00097 
00098 void KPasswordEdit::init()
00099 {
00100     setEchoMode(QLineEdit::Password); // Just in case
00101     setAcceptDrops(false);
00102     m_Password = new char[PassLen];
00103     m_Password[0] = '\000';
00104     m_Length = 0;
00105 }
00106 
00107 KPasswordEdit::~KPasswordEdit()
00108 {
00109     for (int i=0; i<PassLen; i++)
00110     m_Password[i] = '\000';
00111     delete[] m_Password;
00112 }
00113 
00114 void KPasswordEdit::insert(const QString &txt)
00115 {
00116     QCString localTxt = txt.local8Bit();
00117     for(unsigned int i=0; i < localTxt.length(); i++)
00118     {
00119         unsigned char ke = localTxt[i];
00120         if (m_Length < (PassLen - 1))
00121         {
00122             m_Password[m_Length] = ke;
00123             m_Password[++m_Length] = '\000';
00124         }
00125     }
00126     showPass();
00127 }
00128 
00129 void KPasswordEdit::erase()
00130 {
00131     m_Length = 0;
00132     for (int i=0; i<PassLen; i++)
00133     m_Password[i] = '\000';
00134     setText("");
00135 }
00136 
00137 void KPasswordEdit::focusInEvent(QFocusEvent *e)
00138 {
00139     QString txt = text();
00140     setUpdatesEnabled(false);
00141     QLineEdit::focusInEvent(e);
00142     setUpdatesEnabled(true);
00143     setText(txt);
00144 }
00145 
00146 
00147 void KPasswordEdit::keyPressEvent(QKeyEvent *e)
00148 {
00149     switch (e->key()) {
00150     case Key_Return:
00151     case Key_Enter:
00152     case Key_Escape:
00153     e->ignore();
00154     break;
00155     case Key_Backspace:
00156     case Key_Delete:
00157     case 0x7f: // Delete
00158     if (e->state() & (ControlButton | AltButton))
00159         e->ignore();
00160     else if (m_Length) {
00161         m_Password[--m_Length] = '\000';
00162         showPass();
00163     }
00164     break;
00165     default:
00166     unsigned char ke = e->text().local8Bit()[0];
00167     if (ke >= 32) {
00168         insert(e->text());
00169     } else
00170         e->ignore();
00171     break;
00172     }
00173 }
00174 
00175 bool KPasswordEdit::event(QEvent *e) {
00176     switch(e->type()) {
00177 
00178       case QEvent::MouseButtonPress:
00179       case QEvent::MouseButtonRelease:
00180       case QEvent::MouseButtonDblClick:
00181       case QEvent::MouseMove:
00182       case QEvent::IMStart:
00183       case QEvent::IMCompose:
00184         return true; //Ignore
00185 
00186       case QEvent::IMEnd:
00187       {
00188         QIMEvent *ie = (QIMEvent*) e;
00189         insert( ie->text() );
00190         return true;
00191       }
00192 
00193       case QEvent::AccelOverride:
00194       {
00195         QKeyEvent *k = (QKeyEvent*) e;
00196         switch (k->key()) {
00197             case Key_U:
00198                 if (k->state() & ControlButton) {
00199                     m_Length = 0;
00200                     m_Password[m_Length] = '\000';
00201                     showPass();
00202                 }
00203         }
00204         return true; // stop bubbling
00205       }
00206 
00207       default:
00208         // Do nothing
00209         break;
00210     }
00211     return QLineEdit::event(e);
00212 }
00213 
00214 void KPasswordEdit::showPass()
00215 {
00216     QString tmp;
00217 
00218     switch (m_EchoMode) {
00219     case OneStar:
00220     tmp.fill('*', m_Length);
00221     setText(tmp);
00222     break;
00223     case ThreeStars:
00224     tmp.fill('*', m_Length*3);
00225     setText(tmp);
00226     break;
00227     case NoEcho: default:
00228     emit textChanged(QString::null); //To update the password comparison if need be.
00229     break;
00230     }
00231 }
00232 
00233 
00234 /*
00235  * Password dialog.
00236  */
00237 
00238 KPasswordDialog::KPasswordDialog(Types type, bool enableKeep, int extraBttn,
00239                                  QWidget *parent, const char *name)
00240     : KDialogBase(parent, name, true, "", Ok|Cancel|extraBttn,
00241                   Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), d(new KPasswordDialogPrivate)
00242 {
00243     d->iconName = "password";
00244     init();
00245 }
00246 
00247 KPasswordDialog::KPasswordDialog(Types type, bool enableKeep, int extraBttn, const QString& icon,
00248                   QWidget *parent, const char *name )
00249     : KDialogBase(parent, name, true, "", Ok|Cancel|extraBttn,
00250                   Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), d(new KPasswordDialogPrivate)
00251 {
00252     if ( icon.stripWhiteSpace().isEmpty() )
00253     d->iconName = "password";
00254     else
00255     d->iconName = icon;
00256     init();
00257 }
00258 
00259 KPasswordDialog::KPasswordDialog(int type, QString prompt, bool enableKeep,
00260                                  int extraBttn)
00261     : KDialogBase(0L, "Password Dialog", true, "", Ok|Cancel|extraBttn,
00262                   Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), d(new KPasswordDialogPrivate)
00263 {
00264     d->iconName = "password";
00265     init();
00266     setPrompt(prompt);
00267 }
00268 
00269 void KPasswordDialog::init()
00270 {
00271     m_Row = 0;
00272 
00273     KConfig *cfg = KGlobal::config();
00274     KConfigGroupSaver saver(cfg, "Passwords");
00275     if (m_Keep && cfg->readBoolEntry("Keep", false))
00276     m_Keep++;
00277 
00278     m_pMain = new QWidget(this);
00279     setMainWidget(m_pMain);
00280     m_pGrid = new QGridLayout(m_pMain, 10, 3, 0, 0);
00281     m_pGrid->addColSpacing(1, 10);
00282 
00283     // Row 1: pixmap + prompt
00284     QLabel *lbl;
00285     QPixmap pix( KGlobal::iconLoader()->loadIcon( d->iconName, KIcon::NoGroup, KIcon::SizeHuge, 0, 0, true));
00286     if (!pix.isNull()) {
00287     lbl = new QLabel(m_pMain);
00288     lbl->setPixmap(pix);
00289     lbl->setAlignment(AlignHCenter|AlignVCenter);
00290     lbl->setFixedSize(lbl->sizeHint());
00291     m_pGrid->addWidget(lbl, 0, 0, AlignCenter);
00292     }
00293 
00294     m_pHelpLbl = new QLabel(m_pMain);
00295     m_pHelpLbl->setAlignment(AlignLeft|AlignVCenter|WordBreak);
00296     m_pGrid->addWidget(m_pHelpLbl, 0, 2, AlignLeft);
00297     m_pGrid->addRowSpacing(1, 10);
00298     m_pGrid->setRowStretch(1, 12);
00299 
00300     // Row 2+: space for 4 extra info lines
00301     m_pGrid->addRowSpacing(6, 5);
00302     m_pGrid->setRowStretch(6, 12);
00303 
00304     // Row 3: Password editor #1
00305     lbl = new QLabel(m_pMain);
00306     lbl->setAlignment(AlignLeft|AlignVCenter);
00307     lbl->setText(i18n("&Password:"));
00308     lbl->setFixedSize(lbl->sizeHint());
00309     m_pGrid->addWidget(lbl, 7, 0, AlignLeft);
00310 
00311     QHBoxLayout *h_lay = new QHBoxLayout();
00312     m_pGrid->addLayout(h_lay, 7, 2);
00313     m_pEdit = new KPasswordEdit(m_pMain);
00314     lbl->setBuddy(m_pEdit);
00315     QSize size = m_pEdit->sizeHint();
00316     m_pEdit->setFixedHeight(size.height());
00317     m_pEdit->setMinimumWidth(size.width());
00318     h_lay->addWidget(m_pEdit);
00319 
00320     // Row 4: Password editor #2 or keep password checkbox
00321 
00322     if ((m_Type == Password) && m_Keep) {
00323     m_pGrid->addRowSpacing(8, 10);
00324     m_pGrid->setRowStretch(8, 12);
00325     QCheckBox *cb = new QCheckBox(i18n("&Keep password"), m_pMain);
00326     cb->setFixedSize(cb->sizeHint());
00327     if (m_Keep > 1)
00328         cb->setChecked(true);
00329     else
00330         m_Keep = 0;
00331     connect(cb, SIGNAL(toggled(bool)), SLOT(slotKeep(bool)));
00332     m_pGrid->addWidget(cb, 9, 2, AlignLeft|AlignVCenter);
00333     } else if (m_Type == NewPassword) {
00334     m_pGrid->addRowSpacing(8, 10);
00335     lbl = new QLabel(m_pMain);
00336     lbl->setAlignment(AlignLeft|AlignVCenter);
00337     lbl->setText(i18n("&Verify:"));
00338     lbl->setFixedSize(lbl->sizeHint());
00339     m_pGrid->addWidget(lbl, 9, 0, AlignLeft);
00340 
00341     h_lay = new QHBoxLayout();
00342     m_pGrid->addLayout(h_lay, 9, 2);
00343     m_pEdit2 = new KPasswordEdit(m_pMain);
00344     lbl->setBuddy(m_pEdit2);
00345     size = m_pEdit2->sizeHint();
00346     m_pEdit2->setFixedHeight(size.height());
00347     m_pEdit2->setMinimumWidth(size.width());
00348     h_lay->addWidget(m_pEdit2);
00349 
00350         // Row 5: Label saying whether the passwords match
00351         m_pGrid->addRowSpacing(10, 10);
00352         m_pGrid->setRowStretch(10, 12);
00353         d->m_MatchLabel = new QLabel(m_pMain);
00354         d->m_MatchLabel->setAlignment(AlignLeft|AlignVCenter|WordBreak);
00355         m_pGrid->addMultiCellWidget(d->m_MatchLabel, 11, 11, 0, 2);
00356         d->m_MatchLabel->setText(i18n("Passwords do not match"));
00357         connect( m_pEdit, SIGNAL(textChanged(const QString&)), SLOT(enableOkBtn()) );
00358         connect( m_pEdit2, SIGNAL(textChanged(const QString&)), SLOT(enableOkBtn()) );
00359         enableOkBtn();
00360     }
00361 
00362     erase();
00363 }
00364 
00365 
00366 KPasswordDialog::~KPasswordDialog()
00367 {
00368 }
00369 
00370 
00371 void KPasswordDialog::clearPassword()
00372 {
00373     m_pEdit->erase();
00374 }
00375 
00376 /* KDE 4: Make it const QString & */
00377 void KPasswordDialog::setPrompt(QString prompt)
00378 {
00379     m_pHelpLbl->setText(prompt);
00380     m_pHelpLbl->setFixedSize(275, m_pHelpLbl->heightForWidth(275));
00381 }
00382 
00383 
00384 QString KPasswordDialog::prompt() const
00385 
00386 {
00387     return m_pHelpLbl->text();
00388 }
00389 
00390 
00391 /* KDE 4: Make them const QString & */
00392 void KPasswordDialog::addLine(QString key, QString value)
00393 {
00394     if (m_Row > 3)
00395     return;
00396 
00397     QLabel *lbl = new QLabel(key, m_pMain);
00398     lbl->setAlignment(AlignLeft|AlignTop);
00399     lbl->setFixedSize(lbl->sizeHint());
00400     m_pGrid->addWidget(lbl, m_Row+2, 0, AlignLeft);
00401 
00402     lbl = new QLabel(value, m_pMain);
00403     lbl->setAlignment(AlignTop|WordBreak);
00404     lbl->setFixedSize(275, lbl->heightForWidth(275));
00405     m_pGrid->addWidget(lbl, m_Row+2, 2, AlignLeft);
00406     m_Row++;
00407 }
00408 
00409 
00410 void KPasswordDialog::erase()
00411 {
00412     m_pEdit->erase();
00413     m_pEdit->setFocus();
00414     if (m_Type == NewPassword)
00415     m_pEdit2->erase();
00416 }
00417 
00418 
00419 void KPasswordDialog::slotOk()
00420 {
00421     if (m_Type == NewPassword) {
00422     if (strcmp(m_pEdit->password(), m_pEdit2->password())) {
00423         KMessageBox::sorry(this, i18n("You entered two different "
00424             "passwords. Please try again."));
00425         erase();
00426         return;
00427     }
00428     }
00429     if (!checkPassword(m_pEdit->password())) {
00430     erase();
00431     return;
00432     }
00433     accept();
00434 }
00435 
00436 
00437 void KPasswordDialog::slotCancel()
00438 {
00439     reject();
00440 }
00441 
00442 
00443 void KPasswordDialog::slotKeep(bool keep)
00444 {
00445     m_Keep = keep;
00446 }
00447 
00448 
00449 // static . antlarr: KDE 4: Make it const QString & prompt
00450 int KPasswordDialog::getPassword(QCString &password, QString prompt,
00451     int *keep)
00452 {
00453     bool enableKeep = keep && *keep;
00454     KPasswordDialog *dlg = new KPasswordDialog(int(Password), prompt, enableKeep);
00455     int ret = dlg->exec();
00456     if (ret == Accepted) {
00457     password = dlg->password();
00458     if (enableKeep)
00459         *keep = dlg->keep();
00460     }
00461     delete dlg;
00462     return ret;
00463 }
00464 
00465 
00466 // static . antlarr: KDE 4: Make it const QString & prompt
00467 int KPasswordDialog::getNewPassword(QCString &password, QString prompt)
00468 {
00469     KPasswordDialog *dlg = new KPasswordDialog(NewPassword, prompt);
00470     int ret = dlg->exec();
00471     if (ret == Accepted)
00472     password = dlg->password();
00473     delete dlg;
00474     return ret;
00475 }
00476 
00477 
00478 // static
00479 void KPasswordDialog::disableCoreDumps()
00480 {
00481     struct rlimit rlim;
00482     rlim.rlim_cur = rlim.rlim_max = 0;
00483     setrlimit(RLIMIT_CORE, &rlim);
00484 }
00485 
00486 void KPasswordDialog::virtual_hook( int id, void* data )
00487 { KDialogBase::virtual_hook( id, data ); }
00488 
00489 void KPasswordDialog::enableOkBtn()
00490 {
00491     if (m_Type == NewPassword) {
00492       bool match = ((strcmp(m_pEdit->password(), m_pEdit2->password()))==0)
00493                    && (strcmp(m_pEdit->password(), "") != 0);
00494       enableButtonOK( match );
00495       d->m_MatchLabel->setText( match? i18n("Passwords match")
00496                                       :i18n("Passwords do not match") );
00497    }
00498 }
00499 
00500 #include "kpassdlg.moc"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.3.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Feb 18 15:10:19 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003