25 #include <sys/resource.h>
27 #include <QtCore/QCoreApplication>
28 #include <QtCore/QRegExp>
29 #include <QtCore/QSize>
30 #include <QtCore/QString>
31 #include <QtGui/QCheckBox>
32 #include <QtGui/QLabel>
33 #include <QtGui/QLayout>
34 #include <QtGui/QKeyEvent>
35 #include <QtGui/QProgressBar>
36 #include <QtGui/QWidget>
55 static Q3PtrDict<int>*
d_ptr = 0;
63 d_ptr =
new Q3PtrDict<int>;
64 d_ptr->setAutoDelete(
true);
67 int* ret =
d_ptr->find( (
void*) e );
70 d_ptr->replace( (
void*) e, ret );
77 d_ptr->remove( (
void*) e );
82 class K3PasswordDialog::K3PasswordDialogPrivate
85 K3PasswordDialogPrivate()
97 QProgressBar* m_strengthBar;
109 if (val ==
"ThreeStars")
111 else if (val ==
"NoEcho")
119 :
QLineEdit(parent), m_EchoMode(echoMode)
126 , m_EchoMode( echoMode ==
QLineEdit::NoEcho ? NoEcho : OneStar )
131 void K3PasswordEdit::init()
133 setEchoMode(QLineEdit::Password);
134 setAcceptDrops(
false);
137 m_Password =
new char[
PassLen];
138 m_Password[0] =
'\000';
144 memset(m_Password, 0,
PassLen *
sizeof(
char));
156 const QByteArray localTxt = txt.toLocal8Bit();
157 const unsigned int lim = localTxt.length();
159 for(
unsigned int i=0; i < lim; ++i)
161 const unsigned char ke = localTxt[i];
162 if (m_Length < m_MaxLength)
164 m_Password[m_Length] = ke;
165 m_Password[++m_Length] =
'\000';
174 memset(m_Password, 0,
PassLen *
sizeof(
char));
181 setUpdatesEnabled(
false);
183 setUpdatesEnabled(
true);
196 case Qt::Key_Backspace:
199 if (e->modifiers() & (Qt::ControlModifier | Qt::AltModifier))
202 m_Password[--m_Length] =
'\000';
207 const unsigned char ke = e->text().toLocal8Bit()[0];
219 case QEvent::MouseButtonPress:
220 case QEvent::MouseButtonRelease:
221 case QEvent::MouseButtonDblClick:
222 case QEvent::MouseMove:
224 case QEvent::InputMethod:
226 QInputMethodEvent*
const ie = (QInputMethodEvent*) e;
227 if (!ie->commitString().isNull())
228 insert( ie->commitString() );
232 case QEvent::ShortcutOverride:
234 QKeyEvent*
const k = (QKeyEvent*) e;
237 if (k->modifiers() & Qt::ControlModifier) {
239 m_Password[m_Length] =
'\000';
253 void K3PasswordEdit::showPass()
257 switch (m_EchoMode) {
259 tmp.fill(
'*', m_Length);
263 tmp.fill(
'*', m_Length*3);
275 if (newLength < 0) newLength = 0;
278 while (m_Length > newLength) {
279 m_Password[m_Length] =
'\000';
296 , m_Keep(enableKeep? 1 : 0), m_Type(type), d(new K3PasswordDialogPrivate)
301 d->iconName =
"password";
308 , m_Keep(enableKeep? 1 : 0), m_Type(type), d(new K3PasswordDialogPrivate)
313 if ( icon.trimmed().isEmpty() )
314 d->iconName =
"password";
321 void K3PasswordDialog::init()
326 if (m_Keep && cg.readEntry(
"Keep",
false))
331 m_pGrid =
new QGridLayout(m_pMain);
332 m_pGrid->setMargin(0);
333 m_pGrid->setSpacing(0);
339 lbl =
new QLabel(m_pMain);
341 lbl->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
342 lbl->setFixedSize(lbl->sizeHint());
343 m_pGrid->addWidget(lbl, 0, 0, Qt::AlignCenter);
346 m_pHelpLbl =
new QLabel(m_pMain);
347 m_pHelpLbl->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
348 m_pHelpLbl->setWordWrap(
true);
349 m_pGrid->addWidget(m_pHelpLbl, 0, 2, Qt::AlignLeft);
350 m_pGrid->setRowStretch(1, 12);
353 m_pGrid->setRowStretch(6, 12);
356 lbl =
new QLabel(m_pMain);
357 lbl->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
358 lbl->setText(
i18n(
"&Password:"));
359 lbl->setFixedSize(lbl->sizeHint());
360 m_pGrid->addWidget(lbl, 7, 0, Qt::AlignLeft);
362 QHBoxLayout *h_lay =
new QHBoxLayout();
363 m_pGrid->addLayout(h_lay, 7, 2);
366 lbl->setBuddy(m_pEdit);
367 QSize size = m_pEdit->sizeHint();
368 m_pEdit->setFixedHeight(size.height());
369 m_pEdit->setMinimumWidth(size.width());
370 h_lay->addWidget(m_pEdit);
374 if ((m_Type ==
Password) && m_Keep) {
375 m_pGrid->setRowStretch(8, 12);
376 QCheckBox*
const cb =
new QCheckBox(
i18n(
"&Keep password"), m_pMain);
377 cb->setFixedSize(cb->sizeHint());
379 cb->setChecked(
true);
382 connect(cb, SIGNAL(toggled(
bool)), SLOT(
slotKeep(
bool)));
383 m_pGrid->addWidget(cb, 9, 2, Qt::AlignLeft|Qt::AlignVCenter);
385 lbl =
new QLabel(m_pMain);
386 lbl->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
387 lbl->setText(
i18n(
"&Verify:"));
388 lbl->setFixedSize(lbl->sizeHint());
389 m_pGrid->addWidget(lbl, 9, 0, Qt::AlignLeft);
391 h_lay =
new QHBoxLayout();
392 m_pGrid->addLayout(h_lay, 9, 2);
394 lbl->setBuddy(m_pEdit2);
395 size = m_pEdit2->sizeHint();
396 m_pEdit2->setFixedHeight(size.height());
397 m_pEdit2->setMinimumWidth(size.width());
398 h_lay->addWidget(m_pEdit2);
401 m_pGrid->setRowStretch(10, 12);
403 KHBox*
const strengthBox =
new KHBox(m_pMain);
405 m_pGrid->addWidget(strengthBox, 11, 0, 1, 3);
406 QLabel*
const passStrengthLabel =
new QLabel(strengthBox);
407 passStrengthLabel->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
408 passStrengthLabel->setText(
i18n(
"Password strength meter:"));
409 d->m_strengthBar =
new QProgressBar(strengthBox);
410 d->m_strengthBar->setObjectName(
"PasswordStrengthMeter");
411 d->m_strengthBar->setRange(0, 100);
412 d->m_strengthBar->setTextVisible(
false);
414 const QString strengthBarWhatsThis(
i18n(
"The password strength meter gives an indication of the security "
415 "of the password you have entered. To improve the strength of "
416 "the password, try:\n"
417 " - using a longer password;\n"
418 " - using a mixture of upper- and lower-case letters;\n"
419 " - using numbers or symbols, such as #, as well as letters."));
420 passStrengthLabel->setWhatsThis(strengthBarWhatsThis);
421 d->m_strengthBar->setWhatsThis(strengthBarWhatsThis);
424 m_pGrid->setRowStretch(12, 12);
426 d->m_MatchLabel =
new QLabel(m_pMain);
427 d->m_MatchLabel->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
428 d->m_MatchLabel->setWordWrap(
true);
429 m_pGrid->addWidget(d->m_MatchLabel, 13, 0, 1, 3);
430 d->m_MatchLabel->setText(
i18n(
"Passwords do not match"));
433 connect( m_pEdit, SIGNAL(textChanged(
QString)), SLOT(enableOkBtn()) );
434 connect( m_pEdit2, SIGNAL(textChanged(
QString)), SLOT(enableOkBtn()) );
455 m_pHelpLbl->setText(prompt);
456 m_pHelpLbl->setFixedSize(275, m_pHelpLbl->heightForWidth(275));
463 return m_pHelpLbl->text();
473 lbl->setAlignment(Qt::AlignLeft|Qt::AlignTop);
474 lbl->setFixedSize(lbl->sizeHint());
475 m_pGrid->addWidget(lbl, m_Row+2, 0, Qt::AlignLeft);
477 lbl =
new QLabel(value, m_pMain);
478 lbl->setAlignment(Qt::AlignTop);
479 lbl->setWordWrap(
true);
480 lbl->setFixedSize(275, lbl->heightForWidth(275));
481 m_pGrid->addWidget(lbl, m_Row+2, 2, Qt::AlignLeft);
486 void K3PasswordDialog::erase()
500 "passwords. Please try again."));
504 if (d->m_strengthBar && d->m_strengthBar->value() < d->passwordStrengthWarningLevel) {
506 i18n(
"The password you have entered has a low strength. "
507 "To improve the strength of "
508 "the password, try:\n"
509 " - using a longer password;\n"
510 " - using a mixture of upper- and lower-case letters;\n"
511 " - using numbers or symbols as well as letters.\n"
513 "Would you like to use this password anyway?"),
514 i18n(
"Low Password Strength"));
540 const QString &prompt,
bool *keep)
542 const bool enableKeep = (keep && *
keep);
544 dlg->setWindowTitle(caption);
546 const int ret = dlg->exec();
547 if (ret == Accepted) {
559 int res = K3PasswordDialog::Rejected;
561 bool boolkeep = *
keep;
562 res =
getPassword(parent, password,
i18n(
"Password Input"), prompt, &boolkeep);
576 dlg->setWindowTitle(caption);
578 const int ret = dlg->exec();
595 rlim.rlim_cur = rlim.rlim_max = 0;
596 setrlimit(RLIMIT_CORE, &rlim);
600 void K3PasswordDialog::enableOkBtn()
604 && (d->allowEmptyPasswords || m_pEdit->
password()[0]);
610 if ((
int) pass.length() < minPasswordLength) {
616 if ( match && d->allowEmptyPasswords && m_pEdit->
password()[0] == 0 ) {
617 d->m_MatchLabel->setText(
i18n(
"Password is empty") );
619 if ((
int) pass.length() < minPasswordLength) {
620 d->m_MatchLabel->setText(
i18np(
"Password must be at least 1 character long",
"Password must be at least %1 characters long", minPasswordLength));
622 d->m_MatchLabel->setText( match?
i18n(
"Passwords match")
623 :
i18n(
"Passwords do not match") );
633 const double lengthFactor = d->reasonablePasswordLength / 8.0;
636 int pwlength = (int) (pass.length() / lengthFactor);
637 if (pwlength > 5) pwlength = 5;
639 const QRegExp numRxp(
"[0-9]", Qt::CaseSensitive, QRegExp::RegExp);
640 int numeric = (int) (pass.count(numRxp) / lengthFactor);
641 if (numeric > 3) numeric = 3;
643 const QRegExp symbRxp(
"\\W", Qt::CaseInsensitive, QRegExp::RegExp);
644 int numsymbols = (int) (pass.count(symbRxp) / lengthFactor);
645 if (numsymbols > 3) numsymbols = 3;
647 const QRegExp upperRxp(
"[A-Z]", Qt::CaseSensitive, QRegExp::RegExp);
648 int upper = (int) (pass.count(upperRxp) / lengthFactor);
649 if (upper > 3) upper = 3;
651 int pwstrength=((pwlength*10)-20) + (numeric*10) + (numsymbols*15) + (upper*10);
653 if ( pwstrength < 0 ) {
657 if ( pwstrength > 100 ) {
660 d->m_strengthBar->setValue(pwstrength);
667 d->allowEmptyPasswords = allowed;
673 return d->allowEmptyPasswords;
677 d->minimumPasswordLength = minLength;
682 return d->minimumPasswordLength;
687 if (maxLength < 0) maxLength = 0;
690 d->maximumPasswordLength = maxLength;
698 return d->maximumPasswordLength;
705 if (reasonableLength < 1) reasonableLength = 1;
708 d->reasonablePasswordLength = reasonableLength;
713 return d->reasonablePasswordLength;
718 if (warningLevel < 0) warningLevel = 0;
719 if (warningLevel > 99) warningLevel = 99;
720 d->passwordStrengthWarningLevel = warningLevel;
724 return d->passwordStrengthWarningLevel;
737 #include "k3passworddialog.moc"