File indexing completed on 2024-04-28 03:59:11
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 <QContextMenuEvent> 0012 #include <QHBoxLayout> 0013 #include <QIcon> 0014 #include <QMenu> 0015 0016 class KPasswordLineEditPrivate 0017 { 0018 public: 0019 KPasswordLineEditPrivate(KPasswordLineEdit *qq) 0020 : q(qq) 0021 { 0022 } 0023 void initialize(); 0024 void echoModeToggled(); 0025 void showToggleEchoModeAction(const QString &text); 0026 void slotCustomContextMenuRequested(const QPoint &pos); 0027 0028 QIcon passwordIcon; 0029 QIcon visibleIcon; 0030 0031 QLineEdit *passwordLineEdit = nullptr; 0032 QAction *toggleEchoModeAction = nullptr; 0033 bool isToggleEchoModeAvailable = true; 0034 KPassword::RevealMode revealPasswordMode = KPassword::RevealMode::OnlyNew; 0035 KPasswordLineEdit *const q; 0036 }; 0037 0038 void KPasswordLineEditPrivate::initialize() 0039 { 0040 QIcon visibilityIcon = QIcon::fromTheme(QStringLiteral("visibility"), QIcon(QStringLiteral(":/icons/visibility.svg"))); 0041 toggleEchoModeAction = passwordLineEdit->addAction(visibilityIcon, QLineEdit::TrailingPosition); 0042 toggleEchoModeAction->setObjectName(QStringLiteral("visibilityAction")); 0043 toggleEchoModeAction->setVisible(false); 0044 toggleEchoModeAction->setToolTip(QObject::tr("Change the visibility of the password", "@info:tooltip")); 0045 q->connect(toggleEchoModeAction, &QAction::triggered, q, [this]() { 0046 echoModeToggled(); 0047 }); 0048 q->connect(passwordLineEdit, &QLineEdit::textChanged, q, [this](const QString &str) { 0049 showToggleEchoModeAction(str); 0050 }); 0051 } 0052 0053 void KPasswordLineEditPrivate::showToggleEchoModeAction(const QString &text) 0054 { 0055 if (revealPasswordMode != KPassword::RevealMode::Never) { 0056 toggleEchoModeAction->setVisible(isToggleEchoModeAvailable && (passwordLineEdit->echoMode() == QLineEdit::Normal || !text.isEmpty())); 0057 } else { 0058 toggleEchoModeAction->setVisible(false); 0059 } 0060 } 0061 0062 void KPasswordLineEditPrivate::echoModeToggled() 0063 { 0064 if (passwordLineEdit->echoMode() == QLineEdit::Password) { 0065 passwordLineEdit->setEchoMode(QLineEdit::Normal); 0066 if (passwordIcon.isNull()) { 0067 passwordIcon = QIcon::fromTheme(QStringLiteral("hint"), QIcon(QStringLiteral(":/icons/hint.svg"))); 0068 } 0069 toggleEchoModeAction->setIcon(passwordIcon); 0070 } else if (passwordLineEdit->echoMode() == QLineEdit::Normal) { 0071 if (visibleIcon.isNull()) { 0072 visibleIcon = QIcon::fromTheme(QStringLiteral("visibility"), QIcon(QStringLiteral(":/icons/visibility.svg"))); 0073 } 0074 passwordLineEdit->setEchoMode(QLineEdit::Password); 0075 toggleEchoModeAction->setIcon(visibleIcon); 0076 } 0077 Q_EMIT q->echoModeChanged(passwordLineEdit->echoMode()); 0078 } 0079 0080 void KPasswordLineEditPrivate::slotCustomContextMenuRequested(const QPoint &pos) 0081 { 0082 auto popup = std::unique_ptr<QMenu>(passwordLineEdit->createStandardContextMenu()); 0083 if (popup) { 0084 if (toggleEchoModeAction->isVisible()) { 0085 popup->addSeparator(); 0086 0087 toggleEchoModeAction->setText(passwordLineEdit->echoMode() == QLineEdit::Password ? QObject::tr("Show Password", "@action:inmenu") 0088 : QObject::tr("Hide Password", "@action:inmenu")); 0089 popup->addAction(toggleEchoModeAction); 0090 } 0091 popup->exec(pos); 0092 } 0093 } 0094 0095 KPasswordLineEdit::KPasswordLineEdit(QWidget *parent) 0096 : QWidget(parent) 0097 , d(new KPasswordLineEditPrivate(this)) 0098 { 0099 QHBoxLayout *mainLayout = new QHBoxLayout(this); 0100 mainLayout->setObjectName(QStringLiteral("mainlayout")); 0101 mainLayout->setContentsMargins(0, 0, 0, 0); 0102 d->passwordLineEdit = new QLineEdit(this); 0103 d->passwordLineEdit->setObjectName(QStringLiteral("passwordlineedit")); 0104 d->passwordLineEdit->setEchoMode(QLineEdit::Password); 0105 d->passwordLineEdit->setContextMenuPolicy(Qt::CustomContextMenu); 0106 connect(d->passwordLineEdit, &QWidget::customContextMenuRequested, this, [this](const QPoint &pos) { 0107 d->slotCustomContextMenuRequested(pos); 0108 }); 0109 connect(d->passwordLineEdit, &QLineEdit::textChanged, this, &KPasswordLineEdit::passwordChanged); 0110 setFocusProxy(d->passwordLineEdit); 0111 setFocusPolicy(d->passwordLineEdit->focusPolicy()); 0112 mainLayout->addWidget(d->passwordLineEdit); 0113 d->initialize(); 0114 } 0115 0116 KPasswordLineEdit::~KPasswordLineEdit() = default; 0117 0118 void KPasswordLineEdit::setPassword(const QString &password) 0119 { 0120 if (d->passwordLineEdit->text() != password) { 0121 if (d->revealPasswordMode == KPassword::RevealMode::OnlyNew) { 0122 d->isToggleEchoModeAvailable = password.isEmpty(); 0123 } 0124 d->passwordLineEdit->setText(password); 0125 } 0126 } 0127 0128 QString KPasswordLineEdit::password() const 0129 { 0130 return d->passwordLineEdit->text(); 0131 } 0132 0133 void KPasswordLineEdit::clear() 0134 { 0135 d->passwordLineEdit->clear(); 0136 } 0137 0138 void KPasswordLineEdit::setClearButtonEnabled(bool clear) 0139 { 0140 d->passwordLineEdit->setClearButtonEnabled(clear); 0141 } 0142 0143 bool KPasswordLineEdit::isClearButtonEnabled() const 0144 { 0145 return d->passwordLineEdit->isClearButtonEnabled(); 0146 } 0147 0148 void KPasswordLineEdit::setEchoMode(QLineEdit::EchoMode mode) 0149 { 0150 d->passwordLineEdit->setEchoMode(mode); 0151 } 0152 0153 QLineEdit::EchoMode KPasswordLineEdit::echoMode() const 0154 { 0155 return d->passwordLineEdit->echoMode(); 0156 } 0157 0158 void KPasswordLineEdit::setReadOnly(bool readOnly) 0159 { 0160 d->passwordLineEdit->setReadOnly(readOnly); 0161 } 0162 0163 bool KPasswordLineEdit::isReadOnly() const 0164 { 0165 return d->passwordLineEdit->isReadOnly(); 0166 } 0167 0168 QLineEdit *KPasswordLineEdit::lineEdit() const 0169 { 0170 return d->passwordLineEdit; 0171 } 0172 0173 #if KWIDGETSADDONS_ENABLE_DEPRECATED_SINCE(6, 0) 0174 void KPasswordLineEdit::setRevealPasswordAvailable(bool reveal) 0175 { 0176 d->revealPasswordMode = reveal ? KPassword::RevealMode::OnlyNew : KPassword::RevealMode::Never; 0177 d->showToggleEchoModeAction(password()); 0178 } 0179 0180 bool KPasswordLineEdit::isRevealPasswordAvailable() const 0181 { 0182 return d->revealPasswordMode != KPassword::RevealMode::Never; 0183 } 0184 #endif 0185 0186 void KPasswordLineEdit::setRevealPasswordMode(KPassword::RevealMode mode) 0187 { 0188 d->revealPasswordMode = mode; 0189 d->showToggleEchoModeAction(password()); 0190 } 0191 0192 KPassword::RevealMode KPasswordLineEdit::revealPasswordMode() const 0193 { 0194 return d->revealPasswordMode; 0195 } 0196 0197 QAction *KPasswordLineEdit::toggleEchoModeAction() const 0198 { 0199 return d->toggleEchoModeAction; 0200 } 0201 0202 #include "moc_kpasswordlineedit.cpp"