00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 <kapplication.h>
00033 #include <klocale.h>
00034 #include <kiconloader.h>
00035 #include <kmessagebox.h>
00036 #include <kaboutdialog.h>
00037 #include <kconfig.h>
00038 #include <kstandarddirs.h>
00039
00040 #include <sys/time.h>
00041 #include <sys/resource.h>
00042
00043 #include "kpassdlg.h"
00044
00045
00046
00047
00048
00049 class KPasswordDialog::KPasswordDialogPrivate
00050 {
00051 public:
00052 QLabel *m_MatchLabel;
00053 };
00054
00055 const int KPasswordEdit::PassLen = 100;
00056
00057 KPasswordEdit::KPasswordEdit(QWidget *parent, const char *name)
00058 : QLineEdit(parent, name)
00059 {
00060 init();
00061
00062 KConfig *cfg = KGlobal::config();
00063 KConfigGroupSaver saver(cfg, "Passwords");
00064
00065 QString val = cfg->readEntry("EchoMode", "OneStar");
00066 if (val == "ThreeStars")
00067 m_EchoMode = ThreeStars;
00068 else if (val == "NoEcho")
00069 m_EchoMode = NoEcho;
00070 else
00071 m_EchoMode = OneStar;
00072 }
00073
00074 KPasswordEdit::KPasswordEdit(QWidget *parent, const char *name, int echoMode)
00075 : QLineEdit(parent, name), m_EchoMode(echoMode)
00076 {
00077 init();
00078 }
00079
00080 KPasswordEdit::KPasswordEdit(EchoModes echoMode, QWidget *parent, const char *name)
00081 : QLineEdit(parent, name), m_EchoMode(echoMode)
00082 {
00083 init();
00084 }
00085
00086 KPasswordEdit::KPasswordEdit(EchoMode echoMode, QWidget *parent, const char *name)
00087 : QLineEdit(parent, name)
00088 , m_EchoMode( echoMode == QLineEdit::NoEcho ? NoEcho : OneStar )
00089 {
00090 init();
00091 }
00092
00093 void KPasswordEdit::init()
00094 {
00095 setEchoMode(QLineEdit::Password);
00096 setAcceptDrops(false);
00097 m_Password = new char[PassLen];
00098 m_Password[0] = '\000';
00099 m_Length = 0;
00100 }
00101
00102 KPasswordEdit::~KPasswordEdit()
00103 {
00104 for (int i=0; i<PassLen; i++)
00105 m_Password[i] = '\000';
00106 delete[] m_Password;
00107 }
00108
00109 void KPasswordEdit::insert(const QString &txt)
00110 {
00111 QCString localTxt = txt.local8Bit();
00112 for(unsigned int i=0; i < localTxt.length(); i++)
00113 {
00114 unsigned char ke = localTxt[i];
00115 if (m_Length < (PassLen - 1))
00116 {
00117 m_Password[m_Length] = ke;
00118 m_Password[++m_Length] = '\000';
00119 }
00120 }
00121 showPass();
00122 }
00123
00124 void KPasswordEdit::erase()
00125 {
00126 m_Length = 0;
00127 for (int i=0; i<PassLen; i++)
00128 m_Password[i] = '\000';
00129 setText("");
00130 }
00131
00132 void KPasswordEdit::focusInEvent(QFocusEvent *e)
00133 {
00134 QString txt = text();
00135 setUpdatesEnabled(false);
00136 QLineEdit::focusInEvent(e);
00137 setUpdatesEnabled(true);
00138 setText(txt);
00139 }
00140
00141
00142 void KPasswordEdit::keyPressEvent(QKeyEvent *e)
00143 {
00144 switch (e->key()) {
00145 case Key_Return:
00146 case Key_Enter:
00147 case Key_Escape:
00148 e->ignore();
00149 break;
00150 case Key_Backspace:
00151 case Key_Delete:
00152 case 0x7f:
00153 if (e->state() & (ControlButton | AltButton))
00154 e->ignore();
00155 else if (m_Length) {
00156 m_Password[--m_Length] = '\000';
00157 showPass();
00158 }
00159 break;
00160 default:
00161 unsigned char ke = e->text().local8Bit()[0];
00162 if (ke >= 32) {
00163 insert(e->text());
00164 } else
00165 e->ignore();
00166 break;
00167 }
00168 }
00169
00170 bool KPasswordEdit::event(QEvent *e) {
00171 switch(e->type()) {
00172
00173 case QEvent::MouseButtonPress:
00174 case QEvent::MouseButtonRelease:
00175 case QEvent::MouseButtonDblClick:
00176 case QEvent::MouseMove:
00177 case QEvent::IMStart:
00178 case QEvent::IMCompose:
00179 return true;
00180
00181 case QEvent::IMEnd:
00182 {
00183 QIMEvent *ie = (QIMEvent*) e;
00184 insert( ie->text() );
00185 return true;
00186 }
00187
00188 case QEvent::AccelOverride:
00189 {
00190 QKeyEvent *k = (QKeyEvent*) e;
00191 switch (k->key()) {
00192 case Key_U:
00193 if (k->state() & ControlButton) {
00194 m_Length = 0;
00195 m_Password[m_Length] = '\000';
00196 showPass();
00197 }
00198 }
00199 return true;
00200 }
00201
00202 default:
00203
00204 break;
00205 }
00206 return QLineEdit::event(e);
00207 }
00208
00209 void KPasswordEdit::showPass()
00210 {
00211 QString tmp;
00212
00213 switch (m_EchoMode) {
00214 case OneStar:
00215 tmp.fill('*', m_Length);
00216 setText(tmp);
00217 break;
00218 case ThreeStars:
00219 tmp.fill('*', m_Length*3);
00220 setText(tmp);
00221 break;
00222 case NoEcho: default:
00223 emit textChanged(QString::null);
00224 break;
00225 }
00226 }
00227
00228
00229
00230
00231
00232
00233 KPasswordDialog::KPasswordDialog(Types type, bool enableKeep, int extraBttn,
00234 QWidget *parent, const char *name)
00235 : KDialogBase(parent, name, true, "", Ok|Cancel|extraBttn,
00236 Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), d(new KPasswordDialogPrivate)
00237 {
00238 init();
00239 }
00240
00241
00242 KPasswordDialog::KPasswordDialog(int type, QString prompt, bool enableKeep,
00243 int extraBttn)
00244 : KDialogBase(0L, "Password Dialog", true, "", Ok|Cancel|extraBttn,
00245 Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), d(new KPasswordDialogPrivate)
00246 {
00247 init();
00248 setPrompt(prompt);
00249 }
00250
00251
00252 void KPasswordDialog::init()
00253 {
00254 m_Row = 0;
00255
00256 KConfig *cfg = KGlobal::config();
00257 KConfigGroupSaver saver(cfg, "Passwords");
00258 if (m_Keep && cfg->readBoolEntry("Keep", false))
00259 m_Keep++;
00260
00261 m_pMain = new QWidget(this);
00262 setMainWidget(m_pMain);
00263 m_pGrid = new QGridLayout(m_pMain, 10, 3, 0, 0);
00264 m_pGrid->addColSpacing(1, 10);
00265
00266
00267 QLabel *lbl;
00268 QPixmap pix(locate("data", QString::fromLatin1("kdeui/pics/keys.png")));
00269 if (!pix.isNull()) {
00270 lbl = new QLabel(m_pMain);
00271 lbl->setPixmap(pix);
00272 lbl->setAlignment(AlignLeft|AlignVCenter);
00273 lbl->setFixedSize(lbl->sizeHint());
00274 m_pGrid->addWidget(lbl, 0, 0, AlignLeft);
00275 }
00276
00277 m_pHelpLbl = new QLabel(m_pMain);
00278 m_pHelpLbl->setAlignment(AlignLeft|AlignVCenter|WordBreak);
00279 m_pGrid->addWidget(m_pHelpLbl, 0, 2, AlignLeft);
00280 m_pGrid->addRowSpacing(1, 10);
00281 m_pGrid->setRowStretch(1, 12);
00282
00283
00284 m_pGrid->addRowSpacing(6, 5);
00285 m_pGrid->setRowStretch(6, 12);
00286
00287
00288 lbl = new QLabel(m_pMain);
00289 lbl->setAlignment(AlignLeft|AlignVCenter);
00290 lbl->setText(i18n("&Password:"));
00291 lbl->setFixedSize(lbl->sizeHint());
00292 m_pGrid->addWidget(lbl, 7, 0, AlignLeft);
00293
00294 QHBoxLayout *h_lay = new QHBoxLayout();
00295 m_pGrid->addLayout(h_lay, 7, 2);
00296 m_pEdit = new KPasswordEdit(m_pMain);
00297 lbl->setBuddy(m_pEdit);
00298 QSize size = m_pEdit->sizeHint();
00299 m_pEdit->setFixedHeight(size.height());
00300 m_pEdit->setMinimumWidth(size.width());
00301 h_lay->addWidget(m_pEdit);
00302
00303
00304
00305 if ((m_Type == Password) && m_Keep) {
00306 m_pGrid->addRowSpacing(8, 10);
00307 m_pGrid->setRowStretch(8, 12);
00308 QCheckBox *cb = new QCheckBox(i18n("&Keep password"), m_pMain);
00309 cb->setFixedSize(cb->sizeHint());
00310 if (m_Keep > 1)
00311 cb->setChecked(true);
00312 else
00313 m_Keep = 0;
00314 connect(cb, SIGNAL(toggled(bool)), SLOT(slotKeep(bool)));
00315 m_pGrid->addWidget(cb, 9, 2, AlignLeft|AlignVCenter);
00316 } else if (m_Type == NewPassword) {
00317 m_pGrid->addRowSpacing(8, 10);
00318 lbl = new QLabel(m_pMain);
00319 lbl->setAlignment(AlignLeft|AlignVCenter);
00320 lbl->setText(i18n("&Verify:"));
00321 lbl->setFixedSize(lbl->sizeHint());
00322 m_pGrid->addWidget(lbl, 9, 0, AlignLeft);
00323
00324 h_lay = new QHBoxLayout();
00325 m_pGrid->addLayout(h_lay, 9, 2);
00326 m_pEdit2 = new KPasswordEdit(m_pMain);
00327 lbl->setBuddy(m_pEdit2);
00328 size = m_pEdit2->sizeHint();
00329 m_pEdit2->setFixedHeight(size.height());
00330 m_pEdit2->setMinimumWidth(size.width());
00331 h_lay->addWidget(m_pEdit2);
00332
00333
00334 m_pGrid->addRowSpacing(10, 10);
00335 m_pGrid->setRowStretch(10, 12);
00336 d->m_MatchLabel = new QLabel(m_pMain);
00337 d->m_MatchLabel->setAlignment(AlignLeft|AlignVCenter|WordBreak);
00338 m_pGrid->addMultiCellWidget(d->m_MatchLabel, 11, 11, 0, 2);
00339 d->m_MatchLabel->setText(i18n("Passwords do not match"));
00340 connect( m_pEdit, SIGNAL(textChanged(const QString&)), SLOT(enableOkBtn()) );
00341 connect( m_pEdit2, SIGNAL(textChanged(const QString&)), SLOT(enableOkBtn()) );
00342 enableOkBtn();
00343 }
00344
00345 erase();
00346 }
00347
00348
00349 KPasswordDialog::~KPasswordDialog()
00350 {
00351 }
00352
00353
00354
00355 void KPasswordDialog::setPrompt(QString prompt)
00356 {
00357 m_pHelpLbl->setText(prompt);
00358 m_pHelpLbl->setFixedSize(275, m_pHelpLbl->heightForWidth(275));
00359 }
00360
00361
00362 QString KPasswordDialog::prompt() const
00363
00364 {
00365 return m_pHelpLbl->text();
00366 }
00367
00368
00369
00370 void KPasswordDialog::addLine(QString key, QString value)
00371 {
00372 if (m_Row > 3)
00373 return;
00374
00375 QLabel *lbl = new QLabel(key, m_pMain);
00376 lbl->setAlignment(AlignLeft|AlignTop);
00377 lbl->setFixedSize(lbl->sizeHint());
00378 m_pGrid->addWidget(lbl, m_Row+2, 0, AlignLeft);
00379
00380 lbl = new QLabel(value, m_pMain);
00381 lbl->setAlignment(AlignTop|WordBreak);
00382 lbl->setFixedSize(275, lbl->heightForWidth(275));
00383 m_pGrid->addWidget(lbl, m_Row+2, 2, AlignLeft);
00384 m_Row++;
00385 }
00386
00387
00388 void KPasswordDialog::erase()
00389 {
00390 m_pEdit->erase();
00391 m_pEdit->setFocus();
00392 if (m_Type == NewPassword)
00393 m_pEdit2->erase();
00394 }
00395
00396
00397 void KPasswordDialog::slotOk()
00398 {
00399 if (m_Type == NewPassword) {
00400 if (strcmp(m_pEdit->password(), m_pEdit2->password())) {
00401 KMessageBox::sorry(this, i18n("You entered two different "
00402 "passwords. Please try again."));
00403 erase();
00404 return;
00405 }
00406 }
00407 if (!checkPassword(m_pEdit->password())) {
00408 erase();
00409 return;
00410 }
00411 accept();
00412 }
00413
00414
00415 void KPasswordDialog::slotCancel()
00416 {
00417 reject();
00418 }
00419
00420
00421 void KPasswordDialog::slotKeep(bool keep)
00422 {
00423 m_Keep = keep;
00424 }
00425
00426
00427
00428 int KPasswordDialog::getPassword(QCString &password, QString prompt,
00429 int *keep)
00430 {
00431 bool enableKeep = keep && *keep;
00432 KPasswordDialog *dlg = new KPasswordDialog(Password, prompt, enableKeep);
00433 int ret = dlg->exec();
00434 if (ret == Accepted) {
00435 password = dlg->password();
00436 if (enableKeep)
00437 *keep = dlg->keep();
00438 }
00439 delete dlg;
00440 return ret;
00441 }
00442
00443
00444
00445 int KPasswordDialog::getNewPassword(QCString &password, QString prompt)
00446 {
00447 KPasswordDialog *dlg = new KPasswordDialog(NewPassword, prompt);
00448 int ret = dlg->exec();
00449 if (ret == Accepted)
00450 password = dlg->password();
00451 delete dlg;
00452 return ret;
00453 }
00454
00455
00456
00457 void KPasswordDialog::disableCoreDumps()
00458 {
00459 struct rlimit rlim;
00460 rlim.rlim_cur = rlim.rlim_max = 0;
00461 setrlimit(RLIMIT_CORE, &rlim);
00462 }
00463
00464 void KPasswordDialog::virtual_hook( int id, void* data )
00465 { KDialogBase::virtual_hook( id, data ); }
00466
00467 void KPasswordDialog::enableOkBtn()
00468 {
00469 if (m_Type == NewPassword) {
00470 bool match = ((strcmp(m_pEdit->password(), m_pEdit2->password()))==0)
00471 && (strcmp(m_pEdit->password(), "") != 0);
00472 enableButtonOK( match );
00473 d->m_MatchLabel->setText( match?QString(i18n("Passwords match")):QString(i18n("Passwords do not match")) );
00474 }
00475 }
00476
00477 #include "kpassdlg.moc"