File indexing completed on 2024-05-12 16:40:56
0001 /* This file is part of the KDE libraries 0002 Copyright (C) 2000 David Faure <faure@kde.org> 0003 Copyright (C) 2007 Olivier Goffart <ogoffart at kde.org> 0004 Copyright (C) 2013 Jarosław Staniek <staniek@kde.org> 0005 0006 Based on kpasswordwidget.cpp from kdelibs 0007 0008 This library is free software; you can redistribute it and/or 0009 modify it under the terms of the GNU Library General Public 0010 License version 2 as published by the Free Software Foundation. 0011 0012 This library is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 Library General Public License for more details. 0016 0017 You should have received a copy of the GNU Library General Public License 0018 along with this library; see the file COPYING.LIB. If not, write to 0019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 Boston, MA 02110-1301, USA. 0021 */ 0022 #include "KexiPasswordWidget.h" 0023 #include <kexiutils/utils.h> 0024 0025 #include <QCheckBox> 0026 #include <QLabel> 0027 #include <QLayout> 0028 #include <QPalette> 0029 #include <QLineEdit> 0030 #include <QApplication> 0031 #include <QDesktopWidget> 0032 0033 #include <KComboBox> 0034 #include <KIconLoader> 0035 #include <KTitleWidget> 0036 0037 #include "ui_KexiPasswordWidget.h" 0038 0039 /** @internal */ 0040 class Q_DECL_HIDDEN KexiPasswordWidget::Private 0041 { 0042 public: 0043 explicit Private(KexiPasswordWidget *q, KexiPasswordWidgetFlags flags); 0044 0045 void init(); 0046 0047 KexiPasswordWidget * const q; 0048 KexiPasswordWidgetFlags flags; 0049 Ui_KexiPasswordWidget ui; 0050 QMap<QString,QString> knownLogins; 0051 KComboBox* userEditCombo; 0052 QLabel* pixmapLabel; 0053 unsigned int commentRow; 0054 }; 0055 0056 KexiPasswordWidget::Private::Private(KexiPasswordWidget *qq, KexiPasswordWidgetFlags flags) 0057 : q(qq), 0058 userEditCombo(0), 0059 pixmapLabel(0), 0060 commentRow(0) 0061 { 0062 this->flags = flags; 0063 } 0064 0065 void KexiPasswordWidget::Private::init() 0066 { 0067 ui.setupUi( q ); 0068 ui.errorMessage->setHidden(true); 0069 0070 // Row 4: Username field 0071 if (flags & KexiPasswordWidget::ShowUsernameLine) { 0072 ui.userEdit->setFocus(); 0073 QObject::connect(ui.userEdit, SIGNAL(returnPressed()), ui.passEdit, SLOT(setFocus())); 0074 q->setFocusProxy(ui.userEdit); 0075 } 0076 else { 0077 ui.userNameLabel->hide(); 0078 ui.userEdit->hide(); 0079 ui.passEdit->setFocus(); 0080 q->setFocusProxy(ui.passEdit); 0081 } 0082 0083 if (!(flags & KexiPasswordWidget::ShowAnonymousLoginCheckBox)) { 0084 ui.anonymousCheckBox->hide(); 0085 ui.anonymousLabel->hide(); 0086 } 0087 else { 0088 QObject::connect(ui.anonymousCheckBox, SIGNAL(stateChanged(int)), q, SLOT(updateFields())); 0089 } 0090 0091 if (!(flags & KexiPasswordWidget::ShowDatabaseNameLine)) { 0092 q->showDatabaseName(false); 0093 } 0094 0095 if (!(flags & KexiPasswordWidget::ShowDomainLine)) { 0096 ui.domainLabel->hide(); 0097 ui.domainEdit->hide(); 0098 } 0099 0100 if (!(flags & KexiPasswordWidget::ShowKeepPassword)) { 0101 ui.keepCheckBox->hide(); 0102 ui.keepCheckBoxLabel->hide(); 0103 } 0104 0105 q->updateFields(); 0106 0107 QRect desktop = QApplication::desktop()->screenGeometry(q->topLevelWidget()); 0108 q->setMinimumWidth(qMin(1000, qMax(q->sizeHint().width(), desktop.width() / 4))); 0109 if ( ( flags & KexiPasswordWidget::ShowIcon ) ) { 0110 q->setPixmap(QIcon::fromTheme("dialog-password").pixmap(KIconLoader::SizeHuge)); 0111 } 0112 0113 QObject::connect(ui.userEdit, SIGNAL(returnPressed()), q, SIGNAL(returnPressed())); 0114 QObject::connect(ui.domainEdit, SIGNAL(returnPressed()), q, SIGNAL(returnPressed())); 0115 QObject::connect(ui.passEdit, SIGNAL(returnPressed()), q, SIGNAL(returnPressed())); 0116 } 0117 0118 // --- 0119 0120 KexiPasswordWidget::KexiPasswordWidget(QWidget* parent , 0121 KexiPasswordWidgetFlags flags) 0122 : QWidget(parent), d(new Private(this, flags)) 0123 { 0124 d->init(); 0125 } 0126 0127 KexiPasswordWidget::~KexiPasswordWidget() 0128 { 0129 delete d; 0130 } 0131 0132 static void setLineEditReadOnly(QLineEdit *edit, bool readOnly) 0133 { 0134 QPalette p(edit->parentWidget()->palette()); 0135 p.setColor(QPalette::Base, Qt::transparent); 0136 0137 edit->setReadOnly(readOnly); 0138 edit->setFrame(!readOnly); 0139 edit->setPalette(readOnly ? p : edit->parentWidget()->palette()); 0140 edit->setFocusPolicy(readOnly ? Qt::NoFocus : Qt::StrongFocus); 0141 edit->setClearButtonEnabled(!readOnly); 0142 QFont f = edit->font(); 0143 f.setBold(readOnly); 0144 edit->setFont(f); 0145 } 0146 0147 void KexiPasswordWidget::updateFields() 0148 { 0149 if (anonymousMode()) { 0150 d->ui.userEdit->setEnabled( false ); 0151 d->ui.nameEdit->setEnabled( false ); 0152 d->ui.domainEdit->setEnabled( false ); 0153 d->ui.passEdit->setEnabled( false ); 0154 d->ui.keepCheckBox->setEnabled( false ); 0155 } 0156 else { 0157 setLineEditReadOnly(d->ui.userEdit, d->flags & KexiPasswordWidget::UsernameReadOnly); 0158 setLineEditReadOnly(d->ui.nameEdit, d->flags & KexiPasswordWidget::DatabaseNameReadOnly); 0159 setLineEditReadOnly(d->ui.domainEdit, d->flags & KexiPasswordWidget::DomainReadOnly); 0160 d->ui.passEdit->setEnabled( true ); 0161 d->ui.keepCheckBox->setEnabled( true ); 0162 } 0163 } 0164 0165 void KexiPasswordWidget::setPixmap(const QPixmap &pixmap) 0166 { 0167 if ( !d->pixmapLabel ) 0168 { 0169 d->pixmapLabel = new QLabel(this); 0170 d->pixmapLabel->setAlignment( Qt::AlignLeft | Qt::AlignTop ); 0171 d->ui.hboxLayout->insertWidget( 0, d->pixmapLabel ); 0172 } 0173 0174 d->pixmapLabel->setPixmap( pixmap ); 0175 } 0176 0177 QPixmap KexiPasswordWidget::pixmap() const 0178 { 0179 if ( !d->pixmapLabel ) { 0180 return QPixmap(); 0181 } 0182 0183 return *d->pixmapLabel->pixmap(); 0184 } 0185 0186 0187 void KexiPasswordWidget::setUsername(const QString& user) 0188 { 0189 d->ui.userEdit->setText(user); 0190 if ( user.isEmpty() ) 0191 return; 0192 0193 activated(user); 0194 if ( d->ui.userEdit->isVisibleTo( this ) ) 0195 { 0196 d->ui.passEdit->setFocus(); 0197 } 0198 } 0199 0200 0201 QString KexiPasswordWidget::username() const 0202 { 0203 return d->ui.userEdit->text(); 0204 } 0205 0206 QString KexiPasswordWidget::password() const 0207 { 0208 return d->ui.passEdit->text(); 0209 } 0210 0211 void KexiPasswordWidget::setDomain(const QString& domain) 0212 { 0213 d->ui.domainEdit->setText(domain); 0214 } 0215 0216 QString KexiPasswordWidget::domain() const 0217 { 0218 return d->ui.domainEdit->text(); 0219 } 0220 0221 void KexiPasswordWidget::setAnonymousMode(bool anonymous) 0222 { 0223 d->ui.anonymousCheckBox->setChecked( anonymous ); 0224 } 0225 0226 bool KexiPasswordWidget::anonymousMode() const 0227 { 0228 return d->ui.anonymousCheckBox->isChecked(); 0229 } 0230 0231 0232 void KexiPasswordWidget::setKeepPassword( bool b ) 0233 { 0234 d->ui.keepCheckBox->setChecked( b ); 0235 } 0236 0237 bool KexiPasswordWidget::keepPassword() const 0238 { 0239 return d->ui.keepCheckBox->isChecked(); 0240 } 0241 0242 void KexiPasswordWidget::addCommentLine( const QString& label, 0243 const QString& comment ) 0244 { 0245 int gridMarginLeft, gridMarginTop, gridMarginRight, gridMarginBottom; 0246 d->ui.formLayout->getContentsMargins(&gridMarginLeft, &gridMarginTop, &gridMarginRight, &gridMarginBottom); 0247 0248 int spacing = d->ui.formLayout->horizontalSpacing(); 0249 if (spacing < 0) { 0250 // same inter-column spacing for all rows, see comment in qformlayout.cpp 0251 spacing = style()->combinedLayoutSpacing(QSizePolicy::Label, QSizePolicy::LineEdit, Qt::Horizontal, 0, this); 0252 } 0253 0254 QLabel* c = new QLabel(comment, this); 0255 c->setWordWrap(true); 0256 0257 d->ui.formLayout->insertRow(d->commentRow, label, c); 0258 ++d->commentRow; 0259 0260 // cycle through column 0 widgets and see the max width so we can set the minimum height of 0261 // column 2 wordwrapable labels 0262 int firstColumnWidth = 0; 0263 for (int i = 0; i < d->ui.formLayout->rowCount(); ++i) { 0264 QLayoutItem *li = d->ui.formLayout->itemAt(i, QFormLayout::LabelRole); 0265 if (li) { 0266 QWidget *w = li->widget(); 0267 if (w && !w->isHidden()) { 0268 firstColumnWidth = qMax(firstColumnWidth, w->sizeHint().width()); 0269 } 0270 } 0271 } 0272 for (int i = 0; i < d->ui.formLayout->rowCount(); ++i) { 0273 QLayoutItem *li = d->ui.formLayout->itemAt(i, QFormLayout::FieldRole); 0274 if (li) { 0275 QLabel *l = qobject_cast<QLabel*>(li->widget()); 0276 if (l && l->wordWrap()) { 0277 int w = sizeHint().width() - firstColumnWidth - ( 2 * KexiUtils::marginHint() ) 0278 - gridMarginLeft - gridMarginRight - spacing; 0279 l->setMinimumSize( w, l->heightForWidth(w) ); 0280 } 0281 } 0282 } 0283 } 0284 0285 void KexiPasswordWidget::showErrorMessage( const QString& message, const ErrorType type ) 0286 { 0287 d->ui.errorMessage->setText( message, KTitleWidget::ErrorMessage ); 0288 0289 QFont bold = font(); 0290 bold.setBold( true ); 0291 switch ( type ) { 0292 case PasswordError: 0293 d->ui.passwordLabel->setFont( bold ); 0294 d->ui.passEdit->clear(); 0295 d->ui.passEdit->setFocus(); 0296 break; 0297 case UsernameError: 0298 if ( d->ui.userEdit->isVisibleTo( this ) ) 0299 { 0300 d->ui.userNameLabel->setFont( bold ); 0301 d->ui.userEdit->setFocus(); 0302 } 0303 break; 0304 case DomainError: 0305 if ( d->ui.domainEdit->isVisibleTo( this ) ) 0306 { 0307 d->ui.domainLabel->setFont( bold ); 0308 d->ui.domainEdit->setFocus(); 0309 } 0310 break; 0311 case FatalError: 0312 d->ui.userNameLabel->setEnabled( false ); 0313 d->ui.userEdit->setEnabled( false ); 0314 d->ui.passwordLabel->setEnabled( false ); 0315 d->ui.passEdit->setEnabled( false ); 0316 d->ui.keepCheckBox->setEnabled( false ); 0317 //enableButton( Ok, false ); 0318 break; 0319 default: 0320 break; 0321 } 0322 adjustSize(); 0323 } 0324 0325 void KexiPasswordWidget::setPrompt(const QString& prompt) 0326 { 0327 d->ui.prompt->setVisible(!prompt.isEmpty()); 0328 d->ui.prompt->setText( prompt ); 0329 d->ui.prompt->setWordWrap( true ); 0330 d->ui.prompt->setMinimumHeight( 0331 d->ui.prompt->heightForWidth( width() - ( 2 * KexiUtils::marginHint() ) ) ); 0332 } 0333 0334 QString KexiPasswordWidget::prompt() const 0335 { 0336 return d->ui.prompt->text(); 0337 } 0338 0339 void KexiPasswordWidget::setPassword(const QString &p) 0340 { 0341 d->ui.passEdit->setText(p); 0342 } 0343 0344 void KexiPasswordWidget::setUsernameReadOnly(bool readOnly) 0345 { 0346 setLineEditReadOnly(d->ui.userEdit, readOnly); 0347 d->flags |= KexiPasswordWidget::UsernameReadOnly; 0348 if (readOnly) { 0349 d->flags ^= KexiPasswordWidget::UsernameReadOnly; 0350 } 0351 0352 if ( readOnly && d->ui.userEdit->hasFocus() ) { 0353 d->ui.passEdit->setFocus(); 0354 } 0355 } 0356 0357 void KexiPasswordWidget::showDatabaseName(bool show) 0358 { 0359 d->ui.nameLabel->setVisible(show); 0360 d->ui.nameEdit->setVisible(show); 0361 } 0362 0363 void KexiPasswordWidget::setDatabaseName(const QString& databaseName) 0364 { 0365 d->ui.nameEdit->setText(databaseName); 0366 } 0367 0368 void KexiPasswordWidget::setDatabaseNameReadOnly(bool readOnly) 0369 { 0370 setLineEditReadOnly(d->ui.nameEdit, readOnly); 0371 d->flags |= KexiPasswordWidget::DatabaseNameReadOnly; 0372 if (readOnly) { 0373 d->flags ^= KexiPasswordWidget::DatabaseNameReadOnly; 0374 } 0375 0376 if ( readOnly && d->ui.userEdit->hasFocus() ) { 0377 d->ui.passEdit->setFocus(); 0378 } 0379 } 0380 0381 void KexiPasswordWidget::setKnownLogins( const QMap<QString, QString>& knownLogins ) 0382 { 0383 const int nr = knownLogins.count(); 0384 if ( nr == 0 ) { 0385 return; 0386 } 0387 0388 if ( nr == 1 ) { 0389 d->ui.userEdit->setText( knownLogins.begin().key() ); 0390 setPassword( knownLogins.begin().value() ); 0391 return; 0392 } 0393 0394 Q_ASSERT( !d->ui.userEdit->isReadOnly() ); 0395 if ( !d->userEditCombo ) { 0396 d->ui.formLayout->removeWidget(d->ui.userEdit); 0397 delete d->ui.userEdit; 0398 d->userEditCombo = new KComboBox(true, this); 0399 d->ui.userEdit = qobject_cast<KLineEdit*>(d->userEditCombo->lineEdit()); 0400 d->ui.userNameLabel->setBuddy( d->userEditCombo ); 0401 d->ui.formLayout->setWidget( d->commentRow, QFormLayout::FieldRole, d->userEditCombo ); 0402 setTabOrder( d->ui.userEdit, d->ui.anonymousCheckBox ); 0403 setTabOrder( d->ui.anonymousCheckBox, d->ui.domainEdit ); 0404 setTabOrder( d->ui.domainEdit, d->ui.passEdit ); 0405 setTabOrder( d->ui.passEdit, d->ui.keepCheckBox ); 0406 connect( d->ui.userEdit, SIGNAL(returnPressed()), d->ui.passEdit, SLOT(setFocus()) ); 0407 } 0408 0409 d->knownLogins = knownLogins; 0410 d->userEditCombo->addItems( knownLogins.keys() ); 0411 d->userEditCombo->setFocus(); 0412 0413 connect( d->userEditCombo, SIGNAL(activated(QString)), 0414 this, SLOT(activated(QString)) ); 0415 } 0416 0417 void KexiPasswordWidget::activated(const QString& userName) 0418 { 0419 QMap<QString, QString>::ConstIterator it = d->knownLogins.constFind( userName ); 0420 if ( it != d->knownLogins.constEnd() ) { 0421 setPassword( it.value() ); 0422 } 0423 } 0424 0425 bool KexiPasswordWidget::checkPassword() 0426 { 0427 return true; 0428 } 0429