00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <qpushbutton.h>
00020 #include <qcheckbox.h>
00021 #include <qlabel.h>
00022 #include <qlayout.h>
00023 #include <qaccel.h>
00024 #include <qhbox.h>
00025 #include <qsimplerichtext.h>
00026 #include <qstylesheet.h>
00027
00028 #include <kapplication.h>
00029 #include <klineedit.h>
00030 #include <kconfig.h>
00031 #include <kiconloader.h>
00032 #include <klocale.h>
00033 #include <kbuttonbox.h>
00034 #include <kstandarddirs.h>
00035 #include <kseparator.h>
00036
00037 #include "passdlg.h"
00038 #include <kcombobox.h>
00039
00040 using namespace KIO;
00041
00042 struct PasswordDialog::PasswordDialogPrivate
00043 {
00044 QGridLayout *layout;
00045 QLineEdit* userEdit;
00046 KLineEdit* passEdit;
00047 QLabel* userNameLabel;
00048 QLabel* prompt;
00049 QCheckBox* keepCheckBox;
00050 QMap<QString,QString> knownLogins;
00051 KComboBox* userEditCombo;
00052 QHBox* userNameHBox;
00053
00054 bool keep;
00055 short unsigned int nRow;
00056 };
00057
00058 PasswordDialog::PasswordDialog( const QString& prompt, const QString& user,
00059 bool enableKeep, bool modal, QWidget* parent,
00060 const char* name )
00061 :KDialogBase( parent, name, modal, i18n("Password"), Ok|Cancel, Ok, true)
00062 {
00063 init ( prompt, user, enableKeep );
00064 }
00065
00066 PasswordDialog::~PasswordDialog()
00067 {
00068 delete d;
00069 }
00070
00071 void PasswordDialog::init( const QString& prompt, const QString& user,
00072 bool enableKeep )
00073 {
00074 QWidget *main = makeMainWidget();
00075
00076 d = new PasswordDialogPrivate;
00077 d->keep = false;
00078 d->nRow = 0;
00079 d->keepCheckBox = 0;
00080
00081 KConfig* cfg = KGlobal::config();
00082 KConfigGroupSaver saver( cfg, "Passwords" );
00083
00084 d->layout = new QGridLayout( main, 9, 3, spacingHint(), marginHint());
00085 d->layout->addColSpacing(1, 5);
00086
00087
00088 QLabel* lbl;
00089 QPixmap pix( KGlobal::iconLoader()->loadIcon( "password", KIcon::NoGroup, KIcon::SizeHuge, 0, 0, true));
00090 if ( !pix.isNull() )
00091 {
00092 lbl = new QLabel( main );
00093 lbl->setPixmap( pix );
00094 lbl->setAlignment( Qt::AlignLeft|Qt::AlignVCenter );
00095 lbl->setFixedSize( lbl->sizeHint() );
00096 d->layout->addWidget( lbl, 0, 0, Qt::AlignLeft );
00097 }
00098 d->prompt = new QLabel( main );
00099 d->prompt->setAlignment( Qt::AlignLeft|Qt::AlignVCenter|Qt::WordBreak );
00100 d->layout->addWidget( d->prompt, 0, 2, Qt::AlignLeft );
00101 if ( prompt.isEmpty() )
00102 setPrompt( i18n( "You need to supply a username and a password" ) );
00103 else
00104 setPrompt( prompt );
00105
00106
00107 d->layout->addRowSpacing( 1, 7 );
00108
00109
00110
00111
00112 d->userNameLabel = new QLabel( i18n("&Username:"), main );
00113 d->userNameLabel->setAlignment( Qt::AlignVCenter | Qt::AlignLeft );
00114 d->userNameLabel->setFixedSize( d->userNameLabel->sizeHint() );
00115 d->userNameHBox = new QHBox( main );
00116
00117 d->userEdit = new KLineEdit( d->userNameHBox );
00118 QSize s = d->userEdit->sizeHint();
00119 d->userEdit->setFixedHeight( s.height() );
00120 d->userEdit->setMinimumWidth( s.width() );
00121 d->userNameLabel->setBuddy( d->userEdit );
00122 d->layout->addWidget( d->userNameLabel, 4, 0 );
00123 d->layout->addWidget( d->userNameHBox, 4, 2 );
00124
00125
00126 d->layout->addRowSpacing( 5, 4 );
00127
00128
00129 lbl = new QLabel( i18n("&Password:"), main );
00130 lbl->setAlignment( Qt::AlignVCenter | Qt::AlignLeft );
00131 lbl->setFixedSize( lbl->sizeHint() );
00132 QHBox* hbox = new QHBox( main );
00133 d->passEdit = new KLineEdit( hbox );
00134 if ( cfg->readEntry("EchoMode", "OneStar") == "NoEcho" )
00135 d->passEdit->setEchoMode( QLineEdit::NoEcho );
00136 else
00137 d->passEdit->setEchoMode( QLineEdit::Password );
00138 s = d->passEdit->sizeHint();
00139 d->passEdit->setFixedHeight( s.height() );
00140 d->passEdit->setMinimumWidth( s.width() );
00141 lbl->setBuddy( d->passEdit );
00142 d->layout->addWidget( lbl, 6, 0 );
00143 d->layout->addWidget( hbox, 6, 2 );
00144
00145 if ( enableKeep )
00146 {
00147
00148 d->layout->addRowSpacing( 7, 4 );
00149
00150 hbox = new QHBox( main );
00151 d->keepCheckBox = new QCheckBox( i18n("&Keep password"), hbox );
00152 d->keepCheckBox->setFixedSize( d->keepCheckBox->sizeHint() );
00153 d->keep = cfg->readBoolEntry("Keep", false );
00154 d->keepCheckBox->setChecked( d->keep );
00155 connect(d->keepCheckBox, SIGNAL(toggled( bool )), SLOT(slotKeep( bool )));
00156 d->layout->addWidget( hbox, 8, 2 );
00157 }
00158
00159
00160 connect( d->userEdit, SIGNAL(returnPressed()), d->passEdit, SLOT(setFocus()) );
00161 connect( d->passEdit, SIGNAL(returnPressed()), SLOT(slotOk()) );
00162
00163 if ( !user.isEmpty() )
00164 {
00165 d->userEdit->setText( user );
00166 d->passEdit->setFocus();
00167 }
00168 else
00169 d->userEdit->setFocus();
00170
00171 d->userEditCombo = 0;
00172
00173 }
00174
00175 QString PasswordDialog::username() const
00176 {
00177 return d->userEdit->text();
00178 }
00179
00180 QString PasswordDialog::password() const
00181 {
00182 return d->passEdit->text();
00183 }
00184
00185 void PasswordDialog::setKeepPassword( bool b )
00186 {
00187 if ( d->keepCheckBox )
00188 d->keepCheckBox->setChecked( b );
00189 }
00190
00191 bool PasswordDialog::keepPassword() const
00192 {
00193 return d->keep;
00194 }
00195
00196 static void calculateLabelSize(QLabel *label)
00197 {
00198 QString qt_text = label->text();
00199
00200 int pref_width = 0;
00201 int pref_height = 0;
00202
00203 {
00204 QSimpleRichText rt(qt_text, label->font());
00205 QRect d = KGlobalSettings::desktopGeometry(label->topLevelWidget());
00206
00207 pref_width = d.width() / 4;
00208 rt.setWidth(pref_width-10);
00209 int used_width = rt.widthUsed();
00210 pref_height = rt.height();
00211 if (used_width <= pref_width)
00212 {
00213 while(true)
00214 {
00215 int new_width = (used_width * 9) / 10;
00216 rt.setWidth(new_width-10);
00217 int new_height = rt.height();
00218 if (new_height > pref_height)
00219 break;
00220 used_width = rt.widthUsed();
00221 if (used_width > new_width)
00222 break;
00223 }
00224 pref_width = used_width;
00225 }
00226 else
00227 {
00228 if (used_width > (pref_width *2))
00229 pref_width = pref_width *2;
00230 else
00231 pref_width = used_width;
00232 }
00233 }
00234 label->setFixedSize(QSize(pref_width+10, pref_height));
00235 }
00236
00237 void PasswordDialog::addCommentLine( const QString& label,
00238 const QString comment )
00239 {
00240 if (d->nRow > 0)
00241 return;
00242
00243 QWidget *main = mainWidget();
00244
00245 QLabel* lbl = new QLabel( label, main);
00246 lbl->setAlignment( Qt::AlignVCenter|Qt::AlignRight );
00247 lbl->setFixedSize( lbl->sizeHint() );
00248 d->layout->addWidget( lbl, d->nRow+2, 0, Qt::AlignLeft );
00249 lbl = new QLabel( comment, main);
00250 lbl->setAlignment( Qt::AlignVCenter|Qt::AlignLeft|Qt::WordBreak );
00251 calculateLabelSize(lbl);
00252 d->layout->addWidget( lbl, d->nRow+2, 2, Qt::AlignLeft );
00253 d->layout->addRowSpacing( 3, 10 );
00254 d->nRow++;
00255 }
00256
00257 void PasswordDialog::slotKeep( bool keep )
00258 {
00259 d->keep = keep;
00260 }
00261
00262 static QString qrichtextify( const QString& text )
00263 {
00264 if ( text.isEmpty() || text[0] == '<' )
00265 return text;
00266
00267 QStringList lines = QStringList::split('\n', text);
00268 for(QStringList::Iterator it = lines.begin(); it != lines.end(); ++it)
00269 {
00270 *it = QStyleSheet::convertFromPlainText( *it, QStyleSheetItem::WhiteSpaceNormal );
00271 }
00272
00273 return lines.join(QString::null);
00274 }
00275
00276 void PasswordDialog::setPrompt(const QString& prompt)
00277 {
00278 QString text = qrichtextify(prompt);
00279 d->prompt->setText(text);
00280 calculateLabelSize(d->prompt);
00281 }
00282
00283 void PasswordDialog::setPassword(const QString &p)
00284 {
00285 d->passEdit->setText(p);
00286 }
00287
00288 void PasswordDialog::setUserReadOnly( bool readOnly )
00289 {
00290 d->userEdit->setReadOnly( readOnly );
00291 if ( readOnly && d->userEdit->hasFocus() )
00292 d->passEdit->setFocus();
00293 }
00294
00295 void PasswordDialog::setKnownLogins( const QMap<QString, QString>& knownLogins )
00296 {
00297 const int nr = knownLogins.count();
00298 if ( nr == 0 )
00299 return;
00300 if ( nr == 1 ) {
00301 d->userEdit->setText( knownLogins.begin().key() );
00302 setPassword( knownLogins.begin().data() );
00303 return;
00304 }
00305
00306 Q_ASSERT( !d->userEdit->isReadOnly() );
00307 if ( !d->userEditCombo ) {
00308 delete d->userEdit;
00309 d->userEditCombo = new KComboBox( true, d->userNameHBox );
00310 d->userEdit = d->userEditCombo->lineEdit();
00311 QSize s = d->userEditCombo->sizeHint();
00312 d->userEditCombo->setFixedHeight( s.height() );
00313 d->userEditCombo->setMinimumWidth( s.width() );
00314 d->userNameLabel->setBuddy( d->userEditCombo );
00315 d->layout->addWidget( d->userNameHBox, 4, 2 );
00316 }
00317
00318 d->knownLogins = knownLogins;
00319 d->userEditCombo->insertStringList( knownLogins.keys() );
00320 d->userEditCombo->setFocus();
00321
00322 connect( d->userEditCombo, SIGNAL( activated( const QString& ) ),
00323 this, SLOT( slotActivated( const QString& ) ) );
00324 }
00325
00326 void PasswordDialog::slotActivated( const QString& userName )
00327 {
00328 QMap<QString, QString>::ConstIterator it = d->knownLogins.find( userName );
00329 if ( it != d->knownLogins.end() )
00330 setPassword( it.data() );
00331 }
00332
00333
00334 int PasswordDialog::getNameAndPassword( QString& user, QString& pass, bool* keep,
00335 const QString& prompt, bool readOnly,
00336 const QString& caption,
00337 const QString& comment,
00338 const QString& label )
00339 {
00340 PasswordDialog* dlg;
00341 if( keep )
00342 dlg = new PasswordDialog( prompt, user, (*keep) );
00343 else
00344 dlg = new PasswordDialog( prompt, user );
00345
00346 if ( !caption.isEmpty() )
00347 dlg->setPlainCaption( caption );
00348 else
00349 dlg->setPlainCaption( i18n("Authorization Dialog") );
00350
00351 if ( !comment.isEmpty() )
00352 dlg->addCommentLine( label, comment );
00353
00354 if ( readOnly )
00355 dlg->setUserReadOnly( readOnly );
00356
00357 int ret = dlg->exec();
00358 if ( ret == Accepted )
00359 {
00360 user = dlg->username();
00361 pass = dlg->password();
00362 if ( keep ) { (*keep) = dlg->keepPassword(); }
00363 }
00364 delete dlg;
00365 return ret;
00366 }
00367
00368 void PasswordDialog::virtual_hook( int id, void* data )
00369 { KDialogBase::virtual_hook( id, data ); }
00370
00371 #include "passdlg.moc"