24 #include <tqlineedit.h>
29 #include <tqkeycode.h>
30 #include <tqcheckbox.h>
33 #include <tqwhatsthis.h>
34 #include <tqptrdict.h>
39 #include <kapplication.h>
41 #include <kiconloader.h>
42 #include <kmessagebox.h>
43 #include <kaboutdialog.h>
45 #include <kstandarddirs.h>
46 #include <kprogress.h>
49 #include <sys/resource.h>
53 #include "../kdesu/defaults.h"
61 static TQPtrDict<int>* d_ptr = 0;
63 static void cleanup_d_ptr() {
69 d_ptr =
new TQPtrDict<int>;
70 d_ptr->setAutoDelete(
true);
71 qAddPostRoutine( cleanup_d_ptr );
73 int* ret = d_ptr->find( (
void*) e );
76 d_ptr->replace( (
void*) e, ret );
83 d_ptr->remove( (
void*) e );
86 const int KPasswordEdit::PassLen = 200;
88 class KPasswordDialog::KPasswordDialogPrivate
91 KPasswordDialogPrivate()
97 TQLabel *m_MatchLabel;
109 : TQLineEdit(parent, name)
116 const TQString val = cfg->
readEntry(
"EchoMode",
"OneStar");
117 if (val ==
"ThreeStars")
118 m_EchoMode = ThreeStars;
119 else if (val ==
"NoEcho")
122 m_EchoMode = OneStar;
124 setInputMethodEnabled(
true );
128 : TQLineEdit(parent, name), m_EchoMode(echoMode)
134 : TQLineEdit(parent, name), m_EchoMode(echoMode)
140 : TQLineEdit(parent, name)
141 , m_EchoMode( echoMode == TQLineEdit::NoEcho ? NoEcho : OneStar )
146 void KPasswordEdit::init()
148 setEchoMode(TQLineEdit::Password);
149 setAcceptDrops(
false);
150 int* t = ourMaxLength(
this);
152 m_Password =
new char[PassLen];
153 m_Password[0] =
'\000';
159 memset(m_Password, 0, PassLen *
sizeof(
char));
166 const TQCString localTxt = txt.local8Bit();
167 const unsigned int lim = localTxt.length();
169 for(
unsigned int i=0; i < lim; ++i)
171 const unsigned char ke = localTxt[i];
172 if (m_Length < m_MaxLength)
174 m_Password[m_Length] = ke;
175 m_Password[++m_Length] =
'\000';
184 memset(m_Password, 0, PassLen *
sizeof(
char));
188 void KPasswordEdit::focusInEvent(TQFocusEvent *e)
190 const TQString txt = text();
191 setUpdatesEnabled(
false);
192 TQLineEdit::focusInEvent(e);
193 setUpdatesEnabled(
true);
198 void KPasswordEdit::keyPressEvent(TQKeyEvent *e)
209 if (e->state() & (ControlButton | AltButton))
212 m_Password[--m_Length] =
'\000';
217 const unsigned char ke = TQString(e->text()).local8Bit()[0];
226 bool KPasswordEdit::event(TQEvent *e) {
229 case TQEvent::MouseButtonPress:
230 case TQEvent::MouseButtonRelease:
231 case TQEvent::MouseButtonDblClick:
232 case TQEvent::MouseMove:
233 case TQEvent::IMStart:
234 case TQEvent::IMCompose:
239 TQIMEvent*
const ie = (TQIMEvent*) e;
240 if (!ie->text().isEmpty())
245 case TQEvent::AccelOverride:
247 TQKeyEvent*
const k = (TQKeyEvent*) e;
250 if (k->state() & ControlButton) {
252 m_Password[m_Length] =
'\000';
263 return TQLineEdit::event(e);
266 void KPasswordEdit::showPass()
270 switch (m_EchoMode) {
272 tmp.fill(
'*', m_Length);
276 tmp.fill(
'*', m_Length*3);
279 case NoEcho:
default:
280 emit textChanged(TQString::null);
287 if (newLength >= PassLen) newLength = PassLen - 1;
288 if (newLength < 0) newLength = 0;
289 int* t = ourMaxLength(
this);
291 while (m_Length > newLength) {
292 m_Password[m_Length] =
'\000';
300 return *(ourMaxLength(
this));
307 TQWidget *parent,
const char *name)
308 :
KDialogBase(parent, name, true,
"", Ok|Cancel|extraBttn,
309 Ok, true), m_Keep(enableKeep? 1 : 0), m_keepWarnLbl(0), m_Type(type), d(new KPasswordDialogPrivate)
311 d->iconName =
"password";
316 TQWidget *parent,
const char *name )
317 :
KDialogBase(parent, name, true,
"", Ok|Cancel|extraBttn,
318 Ok, true), m_Keep(enableKeep? 1 : 0), m_keepWarnLbl(0), m_Type(type), d(new KPasswordDialogPrivate)
320 if ( icon.stripWhiteSpace().isEmpty() )
321 d->iconName =
"password";
329 :
KDialogBase(0L,
"Password Dialog", true,
"", Ok|Cancel|extraBttn,
330 Ok, true), m_Keep(enableKeep? 1 : 0), m_keepWarnLbl(0), m_Type(type), d(new KPasswordDialogPrivate)
332 d->iconName =
"password";
337 void KPasswordDialog::init()
343 bool def = ( qstrcmp( tqAppName(),
"kdesu" ) == 0 ? defKeep : false );
347 m_pMain =
new TQWidget(
this);
349 m_pGrid =
new TQGridLayout(m_pMain, 10, 3, 0, 0);
350 m_pGrid->addColSpacing(1, 10);
356 lbl =
new TQLabel(m_pMain);
358 lbl->setAlignment(AlignHCenter|AlignVCenter);
359 lbl->setFixedSize(lbl->sizeHint());
360 m_pGrid->addWidget(lbl, 0, 0, (TQ_Alignment)AlignCenter);
363 m_pHelpLbl =
new TQLabel(m_pMain);
364 m_pHelpLbl->setAlignment(AlignLeft|AlignVCenter|WordBreak);
365 m_pGrid->addWidget(m_pHelpLbl, 0, 2, (TQ_Alignment)AlignLeft);
366 m_pGrid->addRowSpacing(1, 10);
367 m_pGrid->setRowStretch(1, 12);
370 m_pGrid->addRowSpacing(6, 5);
371 m_pGrid->setRowStretch(6, 12);
374 lbl =
new TQLabel(m_pMain);
375 lbl->setAlignment(AlignLeft|AlignVCenter);
376 lbl->setText(i18n(
"&Password:"));
377 lbl->setFixedSize(lbl->sizeHint());
378 m_pGrid->addWidget(lbl, 7, 0, (TQ_Alignment)AlignLeft);
380 TQHBoxLayout *h_lay =
new TQHBoxLayout();
381 m_pGrid->addLayout(h_lay, 7, 2);
384 lbl->setBuddy(m_pEdit);
385 TQSize size = m_pEdit->sizeHint();
386 m_pEdit->setFixedHeight(size.height());
387 m_pEdit->setMinimumWidth(size.width());
388 h_lay->addWidget(m_pEdit);
392 if ((m_Type ==
Password) && m_Keep) {
393 m_pGrid->addRowSpacing(8, 10);
394 m_pGrid->setRowStretch(8, 12);
395 TQCheckBox*
const cb =
new TQCheckBox(i18n(
"&Keep password"), m_pMain);
396 cb->setFixedSize(cb->sizeHint());
397 m_keepWarnLbl =
new TQLabel(m_pMain);
398 m_keepWarnLbl->setAlignment(AlignLeft|AlignVCenter|WordBreak);
400 cb->setChecked(
true);
401 m_keepWarnLbl->show();
405 m_keepWarnLbl->hide();
407 connect(cb, TQT_SIGNAL(toggled(
bool)), TQT_SLOT(slotKeep(
bool)));
408 m_pGrid->addWidget(cb, 9, 2, (TQ_Alignment)(AlignLeft|AlignVCenter));
410 m_pGrid->addMultiCellWidget(m_keepWarnLbl, 13, 13, 0, 3);
412 m_pGrid->addRowSpacing(8, 10);
413 lbl =
new TQLabel(m_pMain);
414 lbl->setAlignment(AlignLeft|AlignVCenter);
415 lbl->setText(i18n(
"&Verify:"));
416 lbl->setFixedSize(lbl->sizeHint());
417 m_pGrid->addWidget(lbl, 9, 0, (TQ_Alignment)AlignLeft);
419 h_lay =
new TQHBoxLayout();
420 m_pGrid->addLayout(h_lay, 9, 2);
422 lbl->setBuddy(m_pEdit2);
423 size = m_pEdit2->sizeHint();
424 m_pEdit2->setFixedHeight(size.height());
425 m_pEdit2->setMinimumWidth(size.width());
426 h_lay->addWidget(m_pEdit2);
429 m_pGrid->addRowSpacing(10, 10);
430 m_pGrid->setRowStretch(10, 12);
432 TQHBox*
const strengthBox =
new TQHBox(m_pMain);
433 strengthBox->setSpacing(10);
434 m_pGrid->addMultiCellWidget(strengthBox, 11, 11, 0, 2);
435 TQLabel*
const passStrengthLabel =
new TQLabel(strengthBox);
436 passStrengthLabel->setAlignment(AlignLeft|AlignVCenter);
437 passStrengthLabel->setText(i18n(
"Password strength meter:"));
438 d->m_strengthBar =
new KProgress(100, strengthBox,
"PasswordStrengthMeter");
439 d->m_strengthBar->setPercentageVisible(
false);
441 const TQString strengthBarWhatsThis(i18n(
"The password strength meter gives an indication of the security "
442 "of the password you have entered. To improve the strength of "
443 "the password, try:\n"
444 " - using a longer password;\n"
445 " - using a mixture of upper- and lower-case letters;\n"
446 " - using numbers or symbols, such as #, as well as letters."));
447 TQWhatsThis::add(passStrengthLabel, strengthBarWhatsThis);
448 TQWhatsThis::add(d->m_strengthBar, strengthBarWhatsThis);
451 m_pGrid->addRowSpacing(12, 10);
452 m_pGrid->setRowStretch(12, 12);
454 d->m_MatchLabel =
new TQLabel(m_pMain);
455 d->m_MatchLabel->setAlignment(AlignLeft|AlignVCenter|WordBreak);
456 m_pGrid->addMultiCellWidget(d->m_MatchLabel, 13, 13, 0, 2);
457 d->m_MatchLabel->setText(i18n(
"Passwords do not match"));
460 connect( m_pEdit, TQT_SIGNAL(textChanged(
const TQString&)), TQT_SLOT(enableOkBtn()) );
461 connect( m_pEdit2, TQT_SIGNAL(textChanged(
const TQString&)), TQT_SLOT(enableOkBtn()) );
483 m_pHelpLbl->setText(prompt);
484 m_pHelpLbl->setFixedSize(275, m_pHelpLbl->heightForWidth(275));
490 m_keepWarnLbl->setText(warn);
498 return m_pHelpLbl->text();
508 TQLabel *lbl =
new TQLabel(key, m_pMain);
509 lbl->setAlignment(AlignLeft|AlignTop);
510 lbl->setFixedSize(lbl->sizeHint());
511 m_pGrid->addWidget(lbl, m_Row+2, 0, (TQ_Alignment)AlignLeft);
513 lbl =
new TQLabel(value, m_pMain);
514 lbl->setAlignment(AlignTop|WordBreak);
515 lbl->setFixedSize(275, lbl->heightForWidth(275));
516 m_pGrid->addWidget(lbl, m_Row+2, 2, (TQ_Alignment)AlignLeft);
521 void KPasswordDialog::erase()
530 void KPasswordDialog::slotOk()
535 "passwords. Please try again."));
539 if (d->m_strengthBar && d->m_strengthBar->progress() < d->passwordStrengthWarningLevel) {
541 i18n(
"The password you have entered has a low strength. "
542 "To improve the strength of "
543 "the password, try:\n"
544 " - using a longer password;\n"
545 " - using a mixture of upper- and lower-case letters;\n"
546 " - using numbers or symbols as well as letters.\n"
548 "Would you like to use this password anyway?"),
549 i18n(
"Low Password Strength"));
550 if (retVal == KMessageBox::Cancel)
return;
561 void KPasswordDialog::slotCancel()
567 void KPasswordDialog::slotKeep(
bool keep)
569 if (m_keepWarnLbl->text() !=
"") {
571 m_keepWarnLbl->show();
574 m_keepWarnLbl->hide();
576 TQTimer::singleShot(0,
this, SLOT(slotLayout()));
582 void KPasswordDialog::slotLayout()
592 const bool enableKeep = (keep && *
keep);
594 const int ret = dlg->exec();
595 if (ret == Accepted) {
609 const int ret = dlg->exec();
621 rlim.rlim_cur = rlim.rlim_max = 0;
622 setrlimit(RLIMIT_CORE, &rlim);
625 void KPasswordDialog::virtual_hook(
int id,
void* data )
626 { KDialogBase::virtual_hook(
id, data ); }
628 void KPasswordDialog::enableOkBtn()
632 && (d->allowEmptyPasswords || m_pEdit->
password()[0]);
634 const TQString pass(m_pEdit->
password());
638 if ((
int) pass.length() < minPasswordLength) {
644 if ( match && d->allowEmptyPasswords && m_pEdit->
password()[0] == 0 ) {
645 d->m_MatchLabel->setText( i18n(
"Password is empty") );
647 if ((
int) pass.length() < minPasswordLength) {
648 d->m_MatchLabel->setText(i18n(
"Password must be at least 1 character long",
"Password must be at least %n characters long", minPasswordLength));
650 d->m_MatchLabel->setText( match? i18n(
"Passwords match")
651 :i18n(
"Passwords do not match") );
661 const double lengthFactor = d->reasonablePasswordLength / 8.0;
664 int pwlength = (int) (pass.length() / lengthFactor);
665 if (pwlength > 5) pwlength = 5;
667 const TQRegExp numRxp(
"[0-9]",
true,
false);
668 int numeric = (int) (pass.contains(numRxp) / lengthFactor);
669 if (numeric > 3) numeric = 3;
671 const TQRegExp symbRxp(
"\\W",
false,
false);
672 int numsymbols = (int) (pass.contains(symbRxp) / lengthFactor);
673 if (numsymbols > 3) numsymbols = 3;
675 const TQRegExp upperRxp(
"[A-Z]",
true,
false);
676 int upper = (int) (pass.contains(upperRxp) / lengthFactor);
677 if (upper > 3) upper = 3;
679 int pwstrength=((pwlength*10)-20) + (numeric*10) + (numsymbols*15) + (upper*10);
681 if ( pwstrength < 0 ) {
685 if ( pwstrength > 100 ) {
688 d->m_strengthBar->setProgress(pwstrength);
695 d->allowEmptyPasswords = allowed;
701 return d->allowEmptyPasswords;
705 d->minimumPasswordLength = minLength;
710 return d->minimumPasswordLength;
715 if (maxLength < 0) maxLength = 0;
716 if (maxLength >= KPasswordEdit::PassLen) maxLength = KPasswordEdit::PassLen - 1;
718 d->maximumPasswordLength = maxLength;
726 return d->maximumPasswordLength;
733 if (reasonableLength < 1) reasonableLength = 1;
736 d->reasonablePasswordLength = reasonableLength;
741 return d->reasonablePasswordLength;
746 if (warningLevel < 0) warningLevel = 0;
747 if (warningLevel > 99) warningLevel = 99;
748 d->passwordStrengthWarningLevel = warningLevel;
752 return d->passwordStrengthWarningLevel;
755 #include "kpassdlg.moc"