passdlg.cpp
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2000 David Faure <faure@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2 as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "passdlg.h" 00020 00021 #include <tqapplication.h> 00022 #include <tqcheckbox.h> 00023 #include <tqhbox.h> 00024 #include <tqlabel.h> 00025 #include <tqlayout.h> 00026 #include <tqsimplerichtext.h> 00027 #include <tqstylesheet.h> 00028 00029 #include <kcombobox.h> 00030 #include <tdeconfig.h> 00031 #include <kiconloader.h> 00032 #include <klineedit.h> 00033 #include <tdelocale.h> 00034 #include <kstandarddirs.h> 00035 00036 using namespace TDEIO; 00037 00038 struct PasswordDialog::PasswordDialogPrivate 00039 { 00040 TQGridLayout *layout; 00041 TQLineEdit* userEdit; 00042 KLineEdit* passEdit; 00043 TQLabel* userNameLabel; 00044 TQLabel* prompt; 00045 TQCheckBox* keepCheckBox; 00046 TQMap<TQString,TQString> knownLogins; 00047 KComboBox* userEditCombo; 00048 TQHBox* userNameHBox; 00049 00050 bool keep; 00051 short unsigned int nRow; 00052 }; 00053 00054 PasswordDialog::PasswordDialog( const TQString& prompt, const TQString& user, 00055 bool enableKeep, bool modal, TQWidget* parent, 00056 const char* name ) 00057 :KDialogBase( parent, name, modal, i18n("Password"), Ok|Cancel, Ok, true) 00058 { 00059 init ( prompt, user, enableKeep ); 00060 } 00061 00062 PasswordDialog::~PasswordDialog() 00063 { 00064 delete d; 00065 } 00066 00067 void PasswordDialog::init( const TQString& prompt, const TQString& user, 00068 bool enableKeep ) 00069 { 00070 TQWidget *main = makeMainWidget(); 00071 00072 d = new PasswordDialogPrivate; 00073 d->keep = false; 00074 d->nRow = 0; 00075 d->keepCheckBox = 0; 00076 00077 TDEConfig* cfg = TDEGlobal::config(); 00078 TDEConfigGroupSaver saver( cfg, "Passwords" ); 00079 00080 d->layout = new TQGridLayout( main, 9, 3, spacingHint(), marginHint()); 00081 d->layout->addColSpacing(1, 5); 00082 00083 // Row 0: pixmap prompt 00084 TQLabel* lbl; 00085 TQPixmap pix( TDEGlobal::iconLoader()->loadIcon( "password", TDEIcon::NoGroup, TDEIcon::SizeHuge, 0, 0, true)); 00086 if ( !pix.isNull() ) 00087 { 00088 lbl = new TQLabel( main ); 00089 lbl->setPixmap( pix ); 00090 lbl->setAlignment( Qt::AlignLeft|Qt::AlignVCenter ); 00091 lbl->setFixedSize( lbl->sizeHint() ); 00092 d->layout->addWidget( lbl, 0, 0, Qt::AlignLeft ); 00093 } 00094 d->prompt = new TQLabel( main ); 00095 d->prompt->setAlignment( Qt::AlignLeft|Qt::AlignVCenter|TQt::WordBreak ); 00096 d->layout->addWidget( d->prompt, 0, 2, Qt::AlignLeft ); 00097 if ( prompt.isEmpty() ) 00098 setPrompt( i18n( "You need to supply a username and a password" ) ); 00099 else 00100 setPrompt( prompt ); 00101 00102 // Row 1: Row Spacer 00103 d->layout->addRowSpacing( 1, 7 ); 00104 00105 // Row 2-3: Reserved for an additional comment 00106 00107 // Row 4: Username field 00108 d->userNameLabel = new TQLabel( i18n("&Username:"), main ); 00109 d->userNameLabel->setAlignment( Qt::AlignVCenter | Qt::AlignLeft ); 00110 d->userNameLabel->setFixedSize( d->userNameLabel->sizeHint() ); 00111 d->userNameHBox = new TQHBox( main ); 00112 00113 d->userEdit = new KLineEdit( d->userNameHBox ); 00114 TQSize s = d->userEdit->sizeHint(); 00115 d->userEdit->setFixedHeight( s.height() ); 00116 d->userEdit->setMinimumWidth( s.width() ); 00117 d->userNameLabel->setBuddy( d->userEdit ); 00118 d->layout->addWidget( d->userNameLabel, 4, 0 ); 00119 d->layout->addWidget( d->userNameHBox, 4, 2 ); 00120 00121 // Row 5: Row spacer 00122 d->layout->addRowSpacing( 5, 4 ); 00123 00124 // Row 6: Password field 00125 lbl = new TQLabel( i18n("&Password:"), main ); 00126 lbl->setAlignment( Qt::AlignVCenter | Qt::AlignLeft ); 00127 lbl->setFixedSize( lbl->sizeHint() ); 00128 TQHBox* hbox = new TQHBox( main ); 00129 d->passEdit = new KLineEdit( hbox ); 00130 if ( cfg->readEntry("EchoMode", "OneStar") == "NoEcho" ) 00131 d->passEdit->setEchoMode( TQLineEdit::NoEcho ); 00132 else 00133 d->passEdit->setEchoMode( TQLineEdit::Password ); 00134 s = d->passEdit->sizeHint(); 00135 d->passEdit->setFixedHeight( s.height() ); 00136 d->passEdit->setMinimumWidth( s.width() ); 00137 lbl->setBuddy( d->passEdit ); 00138 d->layout->addWidget( lbl, 6, 0 ); 00139 d->layout->addWidget( hbox, 6, 2 ); 00140 00141 if ( enableKeep ) 00142 { 00143 // Row 7: Add spacer 00144 d->layout->addRowSpacing( 7, 4 ); 00145 // Row 8: Keep Password 00146 hbox = new TQHBox( main ); 00147 d->keepCheckBox = new TQCheckBox( i18n("&Keep password"), hbox ); 00148 d->keepCheckBox->setFixedSize( d->keepCheckBox->sizeHint() ); 00149 d->keep = cfg->readBoolEntry("Keep", false ); 00150 d->keepCheckBox->setChecked( d->keep ); 00151 connect(d->keepCheckBox, TQT_SIGNAL(toggled( bool )), TQT_SLOT(slotKeep( bool ))); 00152 d->layout->addWidget( hbox, 8, 2 ); 00153 } 00154 00155 // Configure necessary key-bindings and connect necessar slots and signals 00156 connect( d->userEdit, TQT_SIGNAL(returnPressed()), d->passEdit, TQT_SLOT(setFocus()) ); 00157 connect( d->passEdit, TQT_SIGNAL(returnPressed()), TQT_SLOT(slotOk()) ); 00158 00159 if ( !user.isEmpty() ) 00160 { 00161 d->userEdit->setText( user ); 00162 d->passEdit->setFocus(); 00163 } 00164 else 00165 d->userEdit->setFocus(); 00166 00167 d->userEditCombo = 0; 00168 // setFixedSize( sizeHint() ); 00169 } 00170 00171 TQString PasswordDialog::username() const 00172 { 00173 return d->userEdit->text(); 00174 } 00175 00176 TQString PasswordDialog::password() const 00177 { 00178 return d->passEdit->text(); 00179 } 00180 00181 void PasswordDialog::setKeepPassword( bool b ) 00182 { 00183 if ( d->keepCheckBox ) 00184 d->keepCheckBox->setChecked( b ); 00185 } 00186 00187 bool PasswordDialog::keepPassword() const 00188 { 00189 return d->keep; 00190 } 00191 00192 static void calculateLabelSize(TQLabel *label) 00193 { 00194 TQString qt_text = label->text(); 00195 00196 int pref_width = 0; 00197 int pref_height = 0; 00198 // Calculate a proper size for the text. 00199 { 00200 TQSimpleRichText rt(qt_text, label->font()); 00201 TQRect d = TDEGlobalSettings::desktopGeometry(label->topLevelWidget()); 00202 00203 pref_width = d.width() / 4; 00204 rt.setWidth(pref_width-10); 00205 int used_width = rt.widthUsed(); 00206 pref_height = rt.height(); 00207 if (used_width <= pref_width) 00208 { 00209 while(true) 00210 { 00211 int new_width = (used_width * 9) / 10; 00212 rt.setWidth(new_width-10); 00213 int new_height = rt.height(); 00214 if (new_height > pref_height) 00215 break; 00216 used_width = rt.widthUsed(); 00217 if (used_width > new_width) 00218 break; 00219 } 00220 pref_width = used_width; 00221 } 00222 else 00223 { 00224 if (used_width > (pref_width *2)) 00225 pref_width = pref_width *2; 00226 else 00227 pref_width = used_width; 00228 } 00229 } 00230 label->setFixedSize(TQSize(pref_width+10, pref_height)); 00231 } 00232 00233 void PasswordDialog::addCommentLine( const TQString& label, 00234 const TQString comment ) 00235 { 00236 if (d->nRow > 0) 00237 return; 00238 00239 TQWidget *main = mainWidget(); 00240 00241 TQLabel* lbl = new TQLabel( label, main); 00242 lbl->setAlignment( Qt::AlignVCenter|Qt::AlignRight ); 00243 lbl->setFixedSize( lbl->sizeHint() ); 00244 d->layout->addWidget( lbl, d->nRow+2, 0, Qt::AlignLeft ); 00245 lbl = new TQLabel( comment, main); 00246 lbl->setAlignment( Qt::AlignVCenter|Qt::AlignLeft|TQt::WordBreak ); 00247 calculateLabelSize(lbl); 00248 d->layout->addWidget( lbl, d->nRow+2, 2, Qt::AlignLeft ); 00249 d->layout->addRowSpacing( 3, 10 ); // Add a spacer 00250 d->nRow++; 00251 } 00252 00253 void PasswordDialog::slotKeep( bool keep ) 00254 { 00255 d->keep = keep; 00256 } 00257 00258 static TQString qrichtextify( const TQString& text ) 00259 { 00260 if ( text.isEmpty() || text[0] == '<' ) 00261 return text; 00262 00263 TQStringList lines = TQStringList::split('\n', text); 00264 for(TQStringList::Iterator it = lines.begin(); it != lines.end(); ++it) 00265 { 00266 *it = TQStyleSheet::convertFromPlainText( *it, TQStyleSheetItem::WhiteSpaceNormal ); 00267 } 00268 00269 return lines.join(TQString::null); 00270 } 00271 00272 void PasswordDialog::setPrompt(const TQString& prompt) 00273 { 00274 TQString text = qrichtextify(prompt); 00275 d->prompt->setText(text); 00276 calculateLabelSize(d->prompt); 00277 } 00278 00279 void PasswordDialog::setPassword(const TQString &p) 00280 { 00281 d->passEdit->setText(p); 00282 } 00283 00284 void PasswordDialog::setUserReadOnly( bool readOnly ) 00285 { 00286 d->userEdit->setReadOnly( readOnly ); 00287 if ( readOnly && d->userEdit->hasFocus() ) 00288 d->passEdit->setFocus(); 00289 } 00290 00291 void PasswordDialog::setKnownLogins( const TQMap<TQString, TQString>& knownLogins ) 00292 { 00293 const int nr = knownLogins.count(); 00294 if ( nr == 0 ) 00295 return; 00296 if ( nr == 1 ) { 00297 d->userEdit->setText( knownLogins.begin().key() ); 00298 setPassword( knownLogins.begin().data() ); 00299 return; 00300 } 00301 00302 Q_ASSERT( !d->userEdit->isReadOnly() ); 00303 if ( !d->userEditCombo ) { 00304 delete d->userEdit; 00305 d->userEditCombo = new KComboBox( true, d->userNameHBox ); 00306 d->userEdit = d->userEditCombo->lineEdit(); 00307 TQSize s = d->userEditCombo->sizeHint(); 00308 d->userEditCombo->setFixedHeight( s.height() ); 00309 d->userEditCombo->setMinimumWidth( s.width() ); 00310 d->userNameLabel->setBuddy( d->userEditCombo ); 00311 d->layout->addWidget( d->userNameHBox, 4, 2 ); 00312 } 00313 00314 d->knownLogins = knownLogins; 00315 d->userEditCombo->insertStringList( knownLogins.keys() ); 00316 d->userEditCombo->setFocus(); 00317 00318 connect( d->userEditCombo, TQT_SIGNAL( activated( const TQString& ) ), 00319 this, TQT_SLOT( slotActivated( const TQString& ) ) ); 00320 } 00321 00322 void PasswordDialog::slotActivated( const TQString& userName ) 00323 { 00324 TQMap<TQString, TQString>::ConstIterator it = d->knownLogins.find( userName ); 00325 if ( it != d->knownLogins.end() ) 00326 setPassword( it.data() ); 00327 } 00328 00329 00330 int PasswordDialog::getNameAndPassword( TQString& user, TQString& pass, bool* keep, 00331 const TQString& prompt, bool readOnly, 00332 const TQString& caption, 00333 const TQString& comment, 00334 const TQString& label ) 00335 { 00336 PasswordDialog* dlg; 00337 if( keep ) 00338 dlg = new PasswordDialog( prompt, user, (*keep) ); 00339 else 00340 dlg = new PasswordDialog( prompt, user ); 00341 00342 if ( !caption.isEmpty() ) 00343 dlg->setPlainCaption( caption ); 00344 else 00345 dlg->setPlainCaption( i18n("Authorization Dialog") ); 00346 00347 if ( !comment.isEmpty() ) 00348 dlg->addCommentLine( label, comment ); 00349 00350 if ( readOnly ) 00351 dlg->setUserReadOnly( readOnly ); 00352 00353 int ret = dlg->exec(); 00354 if ( ret == Accepted ) 00355 { 00356 user = dlg->username(); 00357 pass = dlg->password(); 00358 if ( keep ) { (*keep) = dlg->keepPassword(); } 00359 } 00360 delete dlg; 00361 return ret; 00362 } 00363 00364 void PasswordDialog::virtual_hook( int id, void* data ) 00365 { KDialogBase::virtual_hook( id, data ); } 00366 00367 #include "passdlg.moc"