File indexing completed on 2024-04-28 15:32:10

0001 /*
0002     SPDX-FileCopyrightText: 2017 Montel Laurent <montel@kde.org>
0003     SPDX-FileCopyrightText: 2015 Elvis Angelaccio <elvis.angelaccio@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include "kpasswordlineedit.h"
0009 
0010 #include <QAction>
0011 #include <QHBoxLayout>
0012 #include <QIcon>
0013 
0014 class KPasswordLineEditPrivate
0015 {
0016 public:
0017     KPasswordLineEditPrivate(KPasswordLineEdit *qq)
0018         : q(qq)
0019     {
0020     }
0021     void initialize();
0022     void echoModeToggled();
0023     void showToggleEchoModeAction(const QString &text);
0024 
0025     QIcon passwordIcon;
0026     QIcon visibleIcon;
0027 
0028     QLineEdit *passwordLineEdit = nullptr;
0029     QAction *toggleEchoModeAction = nullptr;
0030     bool isToggleEchoModeAvailable = true;
0031     bool revealPasswordAvailable = true;
0032     KPasswordLineEdit *const q;
0033 };
0034 
0035 void KPasswordLineEditPrivate::initialize()
0036 {
0037     QIcon visibilityIcon = QIcon::fromTheme(QStringLiteral("visibility"), QIcon(QStringLiteral(":/icons/visibility.svg")));
0038     toggleEchoModeAction = passwordLineEdit->addAction(visibilityIcon, QLineEdit::TrailingPosition);
0039     toggleEchoModeAction->setObjectName(QStringLiteral("visibilityAction"));
0040     toggleEchoModeAction->setVisible(false);
0041     toggleEchoModeAction->setToolTip(QObject::tr("Change the visibility of the password", "@info:tooltip"));
0042     q->connect(toggleEchoModeAction, &QAction::triggered, q, [this]() {
0043         echoModeToggled();
0044     });
0045     q->connect(passwordLineEdit, &QLineEdit::textChanged, q, [this](const QString &str) {
0046         showToggleEchoModeAction(str);
0047     });
0048 }
0049 
0050 void KPasswordLineEditPrivate::showToggleEchoModeAction(const QString &text)
0051 {
0052     if (revealPasswordAvailable) {
0053         toggleEchoModeAction->setVisible(isToggleEchoModeAvailable && (passwordLineEdit->echoMode() == QLineEdit::Normal || !text.isEmpty()));
0054     } else {
0055         toggleEchoModeAction->setVisible(false);
0056     }
0057 }
0058 
0059 void KPasswordLineEditPrivate::echoModeToggled()
0060 {
0061     if (passwordLineEdit->echoMode() == QLineEdit::Password) {
0062         passwordLineEdit->setEchoMode(QLineEdit::Normal);
0063         if (passwordIcon.isNull()) {
0064             passwordIcon = QIcon::fromTheme(QStringLiteral("hint"), QIcon(QStringLiteral(":/icons/hint.svg")));
0065         }
0066         toggleEchoModeAction->setIcon(passwordIcon);
0067     } else if (passwordLineEdit->echoMode() == QLineEdit::Normal) {
0068         if (visibleIcon.isNull()) {
0069             visibleIcon = QIcon::fromTheme(QStringLiteral("visibility"), QIcon(QStringLiteral(":/icons/visibility.svg")));
0070         }
0071         passwordLineEdit->setEchoMode(QLineEdit::Password);
0072         toggleEchoModeAction->setIcon(visibleIcon);
0073     }
0074     Q_EMIT q->echoModeChanged(passwordLineEdit->echoMode());
0075 }
0076 
0077 KPasswordLineEdit::KPasswordLineEdit(QWidget *parent)
0078     : QWidget(parent)
0079     , d(new KPasswordLineEditPrivate(this))
0080 {
0081     QHBoxLayout *mainLayout = new QHBoxLayout(this);
0082     mainLayout->setObjectName(QStringLiteral("mainlayout"));
0083     mainLayout->setContentsMargins(0, 0, 0, 0);
0084     d->passwordLineEdit = new QLineEdit(this);
0085     d->passwordLineEdit->setObjectName(QStringLiteral("passwordlineedit"));
0086     d->passwordLineEdit->setEchoMode(QLineEdit::Password);
0087     connect(d->passwordLineEdit, &QLineEdit::textChanged, this, &KPasswordLineEdit::passwordChanged);
0088     setFocusProxy(d->passwordLineEdit);
0089     setFocusPolicy(d->passwordLineEdit->focusPolicy());
0090     mainLayout->addWidget(d->passwordLineEdit);
0091     d->initialize();
0092 }
0093 
0094 KPasswordLineEdit::~KPasswordLineEdit() = default;
0095 
0096 void KPasswordLineEdit::setPassword(const QString &password)
0097 {
0098     if (d->passwordLineEdit->text() != password) {
0099         d->isToggleEchoModeAvailable = password.isEmpty();
0100         d->passwordLineEdit->setText(password);
0101     }
0102 }
0103 
0104 QString KPasswordLineEdit::password() const
0105 {
0106     return d->passwordLineEdit->text();
0107 }
0108 
0109 void KPasswordLineEdit::clear()
0110 {
0111     d->passwordLineEdit->clear();
0112 }
0113 
0114 void KPasswordLineEdit::setClearButtonEnabled(bool clear)
0115 {
0116     d->passwordLineEdit->setClearButtonEnabled(clear);
0117 }
0118 
0119 bool KPasswordLineEdit::isClearButtonEnabled() const
0120 {
0121     return d->passwordLineEdit->isClearButtonEnabled();
0122 }
0123 
0124 void KPasswordLineEdit::setEchoMode(QLineEdit::EchoMode mode)
0125 {
0126     d->passwordLineEdit->setEchoMode(mode);
0127 }
0128 
0129 QLineEdit::EchoMode KPasswordLineEdit::echoMode() const
0130 {
0131     return d->passwordLineEdit->echoMode();
0132 }
0133 
0134 QLineEdit *KPasswordLineEdit::lineEdit() const
0135 {
0136     return d->passwordLineEdit;
0137 }
0138 
0139 void KPasswordLineEdit::setRevealPasswordAvailable(bool reveal)
0140 {
0141     d->revealPasswordAvailable = reveal;
0142     d->showToggleEchoModeAction(password());
0143 }
0144 
0145 bool KPasswordLineEdit::isRevealPasswordAvailable() const
0146 {
0147     return d->revealPasswordAvailable;
0148 }
0149 
0150 QAction *KPasswordLineEdit::toggleEchoModeAction() const
0151 {
0152     return d->toggleEchoModeAction;
0153 }
0154 
0155 #include "moc_kpasswordlineedit.cpp"