kdelibs/kdeui/dialogs/kpassworddialog.cpp

385 lines
11 KiB
C++
Raw Normal View History

2014-11-13 01:04:59 +02:00
/* This file is part of the KDE libraries
Copyright (C) 2000 David Faure <faure@kde.org>
Copyright (C) 2007 Olivier Goffart <ogoffart at kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "kpassworddialog.h"
#include "kcombobox.h"
#include "kconfig.h"
#include "kiconloader.h"
#include "klineedit.h"
#include "klocale.h"
#include "kdebug.h"
#include "kconfiggroup.h"
#include "ktitlewidget.h"
#include "kpixmapwidget.h"
2014-11-13 01:04:59 +02:00
#include <QCheckBox>
#include <QLayout>
#include <QTextDocument>
#include <QTimer>
#include <QDesktopWidget>
2014-11-13 01:04:59 +02:00
#include "ui_kpassworddialog.h"
/** @internal */
class KPasswordDialog::KPasswordDialogPrivate
{
public:
KPasswordDialogPrivate(KPasswordDialog *q)
: q(q),
userEditCombo(nullptr),
pixmapWidget(nullptr),
commentRow(0)
{
}
2014-11-13 01:04:59 +02:00
void actuallyAccept();
void activated(const QString &userName);
2014-11-13 01:04:59 +02:00
void updateFields();
void init();
KPasswordDialog *q;
KPasswordDialogFlags m_flags;
Ui_KPasswordDialog ui;
QMap<QString,QString> knownLogins;
KComboBox* userEditCombo;
KPixmapWidget* pixmapWidget;
2014-11-13 01:04:59 +02:00
unsigned int commentRow;
};
KPasswordDialog::KPasswordDialog(QWidget *parent,
const KPasswordDialogFlags flags,
const KDialog::ButtonCodes otherButtons)
: KDialog(parent),
d(new KPasswordDialogPrivate(this))
2014-11-13 01:04:59 +02:00
{
setCaption(i18n("Password"));
2014-11-13 01:04:59 +02:00
setWindowIcon(KIcon("dialog-password"));
setButtons(KDialog::Ok | KDialog::Cancel | otherButtons);
setDefaultButton(KDialog::Ok);
2014-11-13 01:04:59 +02:00
d->m_flags = flags;
d->init();
2014-11-13 01:04:59 +02:00
}
KPasswordDialog::~KPasswordDialog()
{
delete d;
}
void KPasswordDialog::KPasswordDialogPrivate::updateFields()
{
if (m_flags & KPasswordDialog::UsernameReadOnly) {
ui.userEdit->setReadOnly(true);
ui.credentialsGroup->setFocusProxy(ui.passEdit);
}
ui.credentialsGroup->setEnabled(!q->anonymousMode());
2014-11-13 01:04:59 +02:00
}
void KPasswordDialog::KPasswordDialogPrivate::init()
{
ui.setupUi(q->mainWidget());
2014-11-13 01:04:59 +02:00
ui.errorMessage->setHidden(true);
// Row 4: Username field
if (m_flags & KPasswordDialog::ShowUsernameLine) {
2014-11-13 01:04:59 +02:00
ui.userEdit->setFocus();
ui.credentialsGroup->setFocusProxy(ui.userEdit);
QObject::connect(ui.userEdit, SIGNAL(returnPressed()), ui.passEdit, SLOT(setFocus()));
2014-11-13 01:04:59 +02:00
} else {
ui.userNameLabel->hide();
ui.userEdit->hide();
ui.passEdit->setFocus();
ui.credentialsGroup->setFocusProxy(ui.passEdit);
2014-11-13 01:04:59 +02:00
}
if (!(m_flags & KPasswordDialog::ShowAnonymousLoginCheckBox)) {
2014-11-13 01:04:59 +02:00
ui.anonymousRadioButton->hide();
ui.usePasswordButton->hide();
}
if (!(m_flags & KPasswordDialog::ShowKeepPassword)) {
2014-11-13 01:04:59 +02:00
ui.keepCheckBox->hide();
}
updateFields();
QRect desktop = QApplication::desktop()->screenGeometry(q->window());
2014-11-13 01:04:59 +02:00
q->setMinimumWidth(qMin(1000, qMax(q->sizeHint().width(), desktop.width() / 4)));
q->setPixmap(KIcon("dialog-password").pixmap(KIconLoader::SizeHuge));
}
void KPasswordDialog::setPixmap(const QPixmap &pixmap)
{
if (!d->pixmapWidget) {
d->pixmapWidget = new KPixmapWidget(mainWidget());
d->pixmapWidget->setAlignment(Qt::AlignLeft | Qt::AlignTop);
d->ui.hboxLayout->insertWidget(0, d->pixmapWidget);
2014-11-13 01:04:59 +02:00
}
d->pixmapWidget->setPixmap(pixmap);
2014-11-13 01:04:59 +02:00
}
QPixmap KPasswordDialog::pixmap() const
{
if (!d->pixmapWidget ) {
2014-11-13 01:04:59 +02:00
return QPixmap();
}
return d->pixmapWidget->pixmap();
2014-11-13 01:04:59 +02:00
}
void KPasswordDialog::setUsername(const QString &user)
2014-11-13 01:04:59 +02:00
{
d->ui.userEdit->setText(user);
if (user.isEmpty()) {
2014-11-13 01:04:59 +02:00
return;
}
2014-11-13 01:04:59 +02:00
d->activated(user);
if (d->ui.userEdit->isVisibleTo(this)) {
2014-11-13 01:04:59 +02:00
d->ui.passEdit->setFocus();
}
}
QString KPasswordDialog::username() const
{
return d->ui.userEdit->text();
}
QString KPasswordDialog::password() const
{
return d->ui.passEdit->text();
}
void KPasswordDialog::setAnonymousMode(bool anonymous)
{
if (anonymous && !(d->m_flags & KPasswordDialog::ShowAnonymousLoginCheckBox)) {
// This is an error case, but we can at least let user see what's about
// to happen if they proceed.
d->ui.anonymousRadioButton->setVisible(true);
2014-11-13 01:04:59 +02:00
d->ui.usePasswordButton->setVisible(true);
d->ui.usePasswordButton->setEnabled(false);
2014-11-13 01:04:59 +02:00
}
d->ui.anonymousRadioButton->setChecked(anonymous);
2014-11-13 01:04:59 +02:00
}
bool KPasswordDialog::anonymousMode() const
{
return d->ui.anonymousRadioButton->isChecked();
}
void KPasswordDialog::setKeepPassword(bool b)
2014-11-13 01:04:59 +02:00
{
d->ui.keepCheckBox->setChecked(b);
2014-11-13 01:04:59 +02:00
}
bool KPasswordDialog::keepPassword() const
{
return d->ui.keepCheckBox->isChecked();
}
void KPasswordDialog::addCommentLine(const QString &label, const QString &comment)
2014-11-13 01:04:59 +02:00
{
int gridMarginLeft = 0;
int gridMarginTop = 0;
int gridMarginRight = 0;
int gridMarginBottom = 0;
2014-11-13 01:04:59 +02:00
d->ui.formLayout->getContentsMargins(&gridMarginLeft, &gridMarginTop, &gridMarginRight, &gridMarginBottom);
int spacing = d->ui.formLayout->horizontalSpacing();
if (spacing < 0) {
// same inter-column spacing for all rows, see comment in qformlayout.cpp
spacing = style()->combinedLayoutSpacing(QSizePolicy::Label, QSizePolicy::LineEdit, Qt::Horizontal, 0, this);
}
QLabel* c = new QLabel(comment, mainWidget());
c->setWordWrap(true);
d->ui.formLayout->insertRow(d->commentRow, label, c);
++d->commentRow;
// cycle through column 0 widgets and see the max width so we can set the minimum height of
// column 2 wordwrapable labels
int firstColumnWidth = 0;
for (int i = 0; i < d->ui.formLayout->rowCount(); ++i) {
QLayoutItem *li = d->ui.formLayout->itemAt(i, QFormLayout::LabelRole);
if (li) {
QWidget *w = li->widget();
if (w && !w->isHidden()) {
firstColumnWidth = qMax(firstColumnWidth, w->sizeHint().width());
}
}
}
for (int i = 0; i < d->ui.formLayout->rowCount(); ++i) {
QLayoutItem *li = d->ui.formLayout->itemAt(i, QFormLayout::FieldRole);
if (li) {
QLabel *l = qobject_cast<QLabel*>(li->widget());
if (l && l->wordWrap()) {
int w = sizeHint().width() - firstColumnWidth - (2 * marginHint()) - gridMarginLeft - gridMarginRight - spacing;
2014-11-13 01:04:59 +02:00
l->setMinimumSize( w, l->heightForWidth(w) );
}
}
}
}
void KPasswordDialog::showErrorMessage(const QString &message, const ErrorType type)
2014-11-13 01:04:59 +02:00
{
d->ui.errorMessage->setText(message, KTitleWidget::ErrorMessage);
2014-11-13 01:04:59 +02:00
QFont bold = font();
bold.setBold( true );
switch (type) {
case KPasswordDialog::PasswordError: {
d->ui.passwordLabel->setFont(bold);
2014-11-13 01:04:59 +02:00
d->ui.passEdit->clear();
d->ui.passEdit->setFocus();
break;
}
case KPasswordDialog::UsernameError: {
if (d->ui.userEdit->isVisibleTo(this)) {
d->ui.userNameLabel->setFont(bold);
2014-11-13 01:04:59 +02:00
d->ui.userEdit->setFocus();
}
break;
}
case KPasswordDialog::FatalError: {
d->ui.userNameLabel->setEnabled(false);
d->ui.userEdit->setEnabled(false);
d->ui.passwordLabel->setEnabled(false);
d->ui.passEdit->setEnabled(false);
d->ui.keepCheckBox->setEnabled(false);
enableButton(KDialog::Ok, false);
2014-11-13 01:04:59 +02:00
break;
}
default: {
2014-11-13 01:04:59 +02:00
break;
}
2014-11-13 01:04:59 +02:00
}
adjustSize();
}
void KPasswordDialog::setPrompt(const QString &prompt)
2014-11-13 01:04:59 +02:00
{
d->ui.prompt->setText(prompt);
d->ui.prompt->setWordWrap(true);
d->ui.prompt->setMinimumHeight(d->ui.prompt->heightForWidth(width() - (2 * marginHint())));
2014-11-13 01:04:59 +02:00
}
QString KPasswordDialog::prompt() const
{
return d->ui.prompt->text();
}
void KPasswordDialog::setPassword(const QString &p)
{
d->ui.passEdit->setText(p);
}
void KPasswordDialog::setUsernameReadOnly(bool readOnly)
2014-11-13 01:04:59 +02:00
{
d->ui.userEdit->setReadOnly(readOnly);
if (readOnly && d->ui.userEdit->hasFocus()) {
2014-11-13 01:04:59 +02:00
d->ui.passEdit->setFocus();
}
}
void KPasswordDialog::setKnownLogins(const QMap<QString, QString> &knownLogins)
2014-11-13 01:04:59 +02:00
{
const int nr = knownLogins.count();
if (nr == 0) {
2014-11-13 01:04:59 +02:00
return;
}
if (nr == 1) {
d->ui.userEdit->setText(knownLogins.begin().key());
setPassword(knownLogins.begin().value());
2014-11-13 01:04:59 +02:00
return;
}
Q_ASSERT(!d->ui.userEdit->isReadOnly());
if (!d->userEditCombo) {
2014-11-13 01:04:59 +02:00
int row = -1;
QFormLayout::ItemRole userEditRole = QFormLayout::FieldRole;
d->ui.formLayout->getWidgetPosition(d->ui.userEdit, &row, &userEditRole);
d->ui.formLayout->removeWidget(d->ui.userEdit);
delete d->ui.userEdit;
d->userEditCombo = new KComboBox(true, d->ui.credentialsGroup );
2014-11-13 01:04:59 +02:00
d->ui.userEdit = d->userEditCombo->lineEdit();
d->ui.userNameLabel->setBuddy(d->userEditCombo );
d->ui.formLayout->setWidget(row > -1 ? row : 0, userEditRole, d->userEditCombo);
2014-11-13 01:04:59 +02:00
setTabOrder(d->ui.userEdit, d->ui.anonymousRadioButton);
setTabOrder(d->ui.anonymousRadioButton, d->ui.passEdit);
setTabOrder(d->ui.passEdit, d->ui.keepCheckBox);
connect(d->ui.userEdit, SIGNAL(returnPressed()), d->ui.passEdit, SLOT(setFocus()));
2014-11-13 01:04:59 +02:00
}
d->knownLogins = knownLogins;
d->userEditCombo->addItems( knownLogins.keys() );
d->userEditCombo->setFocus();
connect(d->userEditCombo, SIGNAL(activated(QString)), this, SLOT(activated(QString)));
2014-11-13 01:04:59 +02:00
}
void KPasswordDialog::KPasswordDialogPrivate::activated(const QString &userName)
2014-11-13 01:04:59 +02:00
{
QMap<QString, QString>::ConstIterator it = knownLogins.constFind(userName);
if (it != knownLogins.constEnd()) {
q->setPassword(it.value());
2014-11-13 01:04:59 +02:00
}
}
void KPasswordDialog::accept()
{
if (!d->ui.errorMessage->isHidden()) {
d->ui.errorMessage->setText(QString());
}
2014-11-13 01:04:59 +02:00
// reset the font in case we had an error previously
if (!d->ui.passwordLabel->isHidden()) {
d->ui.passwordLabel->setFont(font());
d->ui.userNameLabel->setFont(font());
2014-11-13 01:04:59 +02:00
}
// allow the error message, if any, to go away. checkPassword() may block for a period of time
QTimer::singleShot(0, this, SLOT(actuallyAccept()));
2014-11-13 01:04:59 +02:00
}
void KPasswordDialog::KPasswordDialogPrivate::actuallyAccept()
{
if (!q->checkPassword()) {
2014-11-13 01:04:59 +02:00
return;
}
bool keep = (ui.keepCheckBox->isVisibleTo(q) && ui.keepCheckBox->isChecked());
emit q->gotPassword(q->password(), keep);
2014-11-13 01:04:59 +02:00
if (ui.userEdit->isVisibleTo(q)) {
emit q->gotUsernameAndPassword(q->username(), q->password() , keep);
2014-11-13 01:04:59 +02:00
}
q->KDialog::accept();
}
bool KPasswordDialog::checkPassword()
{
return true;
}
#include "moc_kpassworddialog.cpp"