forked from qt-creator/qt-creator
Utils: Add password input dialog
Task-number: QTCREATORBUG-29485 Change-Id: I2b55e7d39f848f1c89d3a365a2cadd44e8aac97c Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -114,6 +114,7 @@ add_qtc_library(Utils
|
|||||||
overlaywidget.cpp overlaywidget.h
|
overlaywidget.cpp overlaywidget.h
|
||||||
overridecursor.cpp overridecursor.h
|
overridecursor.cpp overridecursor.h
|
||||||
parameteraction.cpp parameteraction.h
|
parameteraction.cpp parameteraction.h
|
||||||
|
passworddialog.cpp passworddialog.h
|
||||||
pathchooser.cpp pathchooser.h
|
pathchooser.cpp pathchooser.h
|
||||||
pathlisteditor.cpp pathlisteditor.h
|
pathlisteditor.cpp pathlisteditor.h
|
||||||
persistentsettings.cpp persistentsettings.h
|
persistentsettings.cpp persistentsettings.h
|
||||||
|
|||||||
204
src/libs/utils/passworddialog.cpp
Normal file
204
src/libs/utils/passworddialog.cpp
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "passworddialog.h"
|
||||||
|
|
||||||
|
#include "layoutbuilder.h"
|
||||||
|
#include "stylehelper.h"
|
||||||
|
#include "utilsicons.h"
|
||||||
|
#include "utilstr.h"
|
||||||
|
|
||||||
|
#include <QAbstractButton>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QEnterEvent>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
namespace Utils {
|
||||||
|
|
||||||
|
ShowPasswordButton::ShowPasswordButton(QWidget *parent)
|
||||||
|
: QAbstractButton(parent)
|
||||||
|
{
|
||||||
|
setAttribute(Qt::WA_Hover);
|
||||||
|
setCheckable(true);
|
||||||
|
setToolTip(Tr::tr("Show/hide password"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShowPasswordButton::paintEvent(QPaintEvent *e)
|
||||||
|
{
|
||||||
|
Q_UNUSED(e);
|
||||||
|
QIcon icon = isChecked() ? Utils::Icons::EYE_OPEN_TOOLBAR.icon()
|
||||||
|
: Utils::Icons::EYE_CLOSED_TOOLBAR.icon();
|
||||||
|
QPainter p(this);
|
||||||
|
QRect r(QPoint(), size());
|
||||||
|
|
||||||
|
if (m_containsMouse)
|
||||||
|
StyleHelper::drawPanelBgRect(&p, r, creatorTheme()->color(Theme::FancyToolButtonHoverColor));
|
||||||
|
|
||||||
|
QWindow *window = this->window()->windowHandle();
|
||||||
|
QSize s = icon.actualSize(window, QSize(32, 16));
|
||||||
|
|
||||||
|
QPixmap px = icon.pixmap(s);
|
||||||
|
QRect iRect(QPoint(), s);
|
||||||
|
iRect.moveCenter(r.center());
|
||||||
|
p.drawPixmap(iRect, px);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShowPasswordButton::enterEvent(QEnterEvent *e)
|
||||||
|
{
|
||||||
|
m_containsMouse = true;
|
||||||
|
e->accept();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShowPasswordButton::leaveEvent(QEvent *e)
|
||||||
|
{
|
||||||
|
m_containsMouse = false;
|
||||||
|
e->accept();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize ShowPasswordButton::sizeHint() const
|
||||||
|
{
|
||||||
|
QWindow *window = this->window()->windowHandle();
|
||||||
|
QSize s = Utils::Icons::EYE_OPEN_TOOLBAR.icon().actualSize(window, QSize(32, 16)) + QSize(8, 8);
|
||||||
|
|
||||||
|
if (StyleHelper::toolbarStyle() == StyleHelper::ToolbarStyleRelaxed)
|
||||||
|
s += QSize(5, 5);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
class PasswordDialogPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QLineEdit *m_userNameLineEdit{nullptr};
|
||||||
|
QLineEdit *m_passwordLineEdit{nullptr};
|
||||||
|
QCheckBox *m_checkBox{nullptr};
|
||||||
|
QDialogButtonBox *m_buttonBox{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
PasswordDialog::PasswordDialog(const QString &title,
|
||||||
|
const QString &prompt,
|
||||||
|
const QString &doNotAskAgainLabel,
|
||||||
|
bool withUsername,
|
||||||
|
QWidget *parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
, d(new PasswordDialogPrivate)
|
||||||
|
{
|
||||||
|
setWindowTitle(title);
|
||||||
|
|
||||||
|
d->m_passwordLineEdit = new QLineEdit();
|
||||||
|
d->m_passwordLineEdit->setEchoMode(QLineEdit::Password);
|
||||||
|
|
||||||
|
if (withUsername)
|
||||||
|
d->m_userNameLineEdit = new QLineEdit();
|
||||||
|
|
||||||
|
d->m_checkBox = new QCheckBox();
|
||||||
|
d->m_checkBox->setText(doNotAskAgainLabel);
|
||||||
|
|
||||||
|
auto *showPasswordButton = new ShowPasswordButton;
|
||||||
|
|
||||||
|
connect(showPasswordButton, &QAbstractButton::toggled, this, [this, showPasswordButton] {
|
||||||
|
d->m_passwordLineEdit->setEchoMode(showPasswordButton->isChecked() ? QLineEdit::Normal
|
||||||
|
: QLineEdit::Password);
|
||||||
|
});
|
||||||
|
|
||||||
|
d->m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||||
|
|
||||||
|
connect(d->m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||||
|
connect(d->m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||||
|
|
||||||
|
using namespace Layouting;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
Column {
|
||||||
|
prompt,
|
||||||
|
If {
|
||||||
|
withUsername, {
|
||||||
|
Form {
|
||||||
|
Tr::tr("User:"), d->m_userNameLineEdit, br,
|
||||||
|
Tr::tr("Password:"), Row { d->m_passwordLineEdit, showPasswordButton }, br,
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
Row {
|
||||||
|
d->m_passwordLineEdit, showPasswordButton,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Row {
|
||||||
|
d->m_checkBox,
|
||||||
|
d->m_buttonBox,
|
||||||
|
}
|
||||||
|
}.attachTo(this);
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
d->m_passwordLineEdit->setMinimumWidth(d->m_passwordLineEdit->width() / 2);
|
||||||
|
setFixedSize(sizeHint());
|
||||||
|
}
|
||||||
|
|
||||||
|
PasswordDialog::~PasswordDialog() = default;
|
||||||
|
|
||||||
|
void PasswordDialog::setUser(const QString &user)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->m_userNameLineEdit, return);
|
||||||
|
d->m_userNameLineEdit->setText(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PasswordDialog::user() const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->m_userNameLineEdit, return {});
|
||||||
|
return d->m_userNameLineEdit->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PasswordDialog::password() const
|
||||||
|
{
|
||||||
|
return d->m_passwordLineEdit->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QPair<QString, QString>> PasswordDialog::getUserAndPassword(
|
||||||
|
const QString &title,
|
||||||
|
const QString &prompt,
|
||||||
|
const QString &doNotAskAgainLabel,
|
||||||
|
const QString &userName,
|
||||||
|
const CheckableDecider &decider,
|
||||||
|
QWidget *parent)
|
||||||
|
{
|
||||||
|
if (!decider.shouldAskAgain())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
PasswordDialog dialog(title, prompt, doNotAskAgainLabel, true, parent);
|
||||||
|
|
||||||
|
dialog.setUser(userName);
|
||||||
|
|
||||||
|
if (dialog.exec() == QDialog::Accepted)
|
||||||
|
return qMakePair(dialog.user(), dialog.password());
|
||||||
|
|
||||||
|
if (dialog.d->m_checkBox->isChecked())
|
||||||
|
decider.doNotAskAgain();
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QString> PasswordDialog::getPassword(const QString &title,
|
||||||
|
const QString &prompt,
|
||||||
|
const QString &doNotAskAgainLabel,
|
||||||
|
const CheckableDecider &decider,
|
||||||
|
QWidget *parent)
|
||||||
|
{
|
||||||
|
if (!decider.shouldAskAgain())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
PasswordDialog dialog(title, prompt, doNotAskAgainLabel, false, parent);
|
||||||
|
|
||||||
|
if (dialog.exec() == QDialog::Accepted)
|
||||||
|
return dialog.password();
|
||||||
|
|
||||||
|
if (dialog.d->m_checkBox->isChecked())
|
||||||
|
decider.doNotAskAgain();
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Utils
|
||||||
68
src/libs/utils/passworddialog.h
Normal file
68
src/libs/utils/passworddialog.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "utils_global.h"
|
||||||
|
|
||||||
|
#include "checkablemessagebox.h"
|
||||||
|
|
||||||
|
#include <QAbstractButton>
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
namespace Utils {
|
||||||
|
|
||||||
|
class PasswordDialogPrivate;
|
||||||
|
|
||||||
|
class QTCREATOR_UTILS_EXPORT ShowPasswordButton : public QAbstractButton
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ShowPasswordButton(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
void enterEvent(QEnterEvent *e) override;
|
||||||
|
void leaveEvent(QEvent *e) override;
|
||||||
|
|
||||||
|
QSize sizeHint() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_containsMouse{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
class QTCREATOR_UTILS_EXPORT PasswordDialog : public QDialog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PasswordDialog(const QString &title,
|
||||||
|
const QString &prompt,
|
||||||
|
const QString &doNotAskAgainLabel,
|
||||||
|
bool withUsername,
|
||||||
|
QWidget *parent = nullptr);
|
||||||
|
virtual ~PasswordDialog();
|
||||||
|
|
||||||
|
void setUser(const QString &user);
|
||||||
|
QString user() const;
|
||||||
|
|
||||||
|
QString password() const;
|
||||||
|
|
||||||
|
static std::optional<QPair<QString, QString>> getUserAndPassword(
|
||||||
|
const QString &title,
|
||||||
|
const QString &prompt,
|
||||||
|
const QString &doNotAskAgainLabel,
|
||||||
|
const QString &userName,
|
||||||
|
const CheckableDecider &decider,
|
||||||
|
QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
static std::optional<QString> getPassword(const QString &title,
|
||||||
|
const QString &prompt,
|
||||||
|
const QString &doNotAskAgainLabel,
|
||||||
|
const CheckableDecider &decider,
|
||||||
|
QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<PasswordDialogPrivate> d;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Utils
|
||||||
@@ -220,18 +220,20 @@ Project {
|
|||||||
"overridecursor.h",
|
"overridecursor.h",
|
||||||
"parameteraction.cpp",
|
"parameteraction.cpp",
|
||||||
"parameteraction.h",
|
"parameteraction.h",
|
||||||
|
"passworddialog.cpp",
|
||||||
|
"passworddialog.h",
|
||||||
"pathchooser.cpp",
|
"pathchooser.cpp",
|
||||||
"pathchooser.h",
|
"pathchooser.h",
|
||||||
"pathlisteditor.cpp",
|
"pathlisteditor.cpp",
|
||||||
"pathlisteditor.h",
|
"pathlisteditor.h",
|
||||||
"persistentsettings.cpp",
|
"persistentsettings.cpp",
|
||||||
"persistentsettings.h",
|
"persistentsettings.h",
|
||||||
"predicates.h",
|
|
||||||
"pointeralgorithm.h",
|
"pointeralgorithm.h",
|
||||||
"port.cpp",
|
"port.cpp",
|
||||||
"port.h",
|
"port.h",
|
||||||
"portlist.cpp",
|
"portlist.cpp",
|
||||||
"portlist.h",
|
"portlist.h",
|
||||||
|
"predicates.h",
|
||||||
"process.cpp",
|
"process.cpp",
|
||||||
"process.h",
|
"process.h",
|
||||||
"processenums.h",
|
"processenums.h",
|
||||||
|
|||||||
Reference in New Issue
Block a user