1 /*
2 SPDX-FileCopyrightText: 2017 Montel Laurent <montel@kde.org>
3 SPDX-FileCopyrightText: 2015 Elvis Angelaccio <elvis.angelaccio@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7
8 #include "kpasswordlineedit.h"
9
10 #include <QAction>
11 #include <QHBoxLayout>
12 #include <QIcon>
13
14 class KPasswordLineEditPrivate
15 {
16 public:
KPasswordLineEditPrivate(KPasswordLineEdit * qq)17 KPasswordLineEditPrivate(KPasswordLineEdit *qq)
18 : q(qq)
19 {
20 }
21 void initialize();
22 void echoModeToggled();
23 void showToggleEchoModeAction(const QString &text);
24
25 QIcon passwordIcon;
26 QIcon visibleIcon;
27
28 QLineEdit *passwordLineEdit = nullptr;
29 QAction *toggleEchoModeAction = nullptr;
30 bool isToggleEchoModeAvailable = true;
31 bool revealPasswordAvailable = true;
32 KPasswordLineEdit *const q;
33 };
34
initialize()35 void KPasswordLineEditPrivate::initialize()
36 {
37 QIcon visibilityIcon = QIcon::fromTheme(QStringLiteral("visibility"), QIcon(QStringLiteral(":/icons/visibility.svg")));
38 toggleEchoModeAction = passwordLineEdit->addAction(visibilityIcon, QLineEdit::TrailingPosition);
39 toggleEchoModeAction->setObjectName(QStringLiteral("visibilityAction"));
40 toggleEchoModeAction->setVisible(false);
41 toggleEchoModeAction->setToolTip(QObject::tr("Change the visibility of the password", "@info:tooltip"));
42 q->connect(toggleEchoModeAction, &QAction::triggered, q, [this]() {
43 echoModeToggled();
44 });
45 q->connect(passwordLineEdit, &QLineEdit::textChanged, q, [this](const QString &str) {
46 showToggleEchoModeAction(str);
47 });
48 }
49
showToggleEchoModeAction(const QString & text)50 void KPasswordLineEditPrivate::showToggleEchoModeAction(const QString &text)
51 {
52 if (revealPasswordAvailable) {
53 toggleEchoModeAction->setVisible(isToggleEchoModeAvailable && (passwordLineEdit->echoMode() == QLineEdit::Normal || !text.isEmpty()));
54 } else {
55 toggleEchoModeAction->setVisible(false);
56 }
57 }
58
echoModeToggled()59 void KPasswordLineEditPrivate::echoModeToggled()
60 {
61 if (passwordLineEdit->echoMode() == QLineEdit::Password) {
62 passwordLineEdit->setEchoMode(QLineEdit::Normal);
63 if (passwordIcon.isNull()) {
64 passwordIcon = QIcon::fromTheme(QStringLiteral("hint"), QIcon(QStringLiteral(":/icons/hint.svg")));
65 }
66 toggleEchoModeAction->setIcon(passwordIcon);
67 } else if (passwordLineEdit->echoMode() == QLineEdit::Normal) {
68 if (visibleIcon.isNull()) {
69 visibleIcon = QIcon::fromTheme(QStringLiteral("visibility"), QIcon(QStringLiteral(":/icons/visibility.svg")));
70 }
71 passwordLineEdit->setEchoMode(QLineEdit::Password);
72 toggleEchoModeAction->setIcon(visibleIcon);
73 }
74 Q_EMIT q->echoModeChanged(passwordLineEdit->echoMode());
75 }
76
KPasswordLineEdit(QWidget * parent)77 KPasswordLineEdit::KPasswordLineEdit(QWidget *parent)
78 : QWidget(parent)
79 , d(new KPasswordLineEditPrivate(this))
80 {
81 QHBoxLayout *mainLayout = new QHBoxLayout(this);
82 mainLayout->setObjectName(QStringLiteral("mainlayout"));
83 mainLayout->setContentsMargins(0, 0, 0, 0);
84 d->passwordLineEdit = new QLineEdit(this);
85 d->passwordLineEdit->setObjectName(QStringLiteral("passwordlineedit"));
86 d->passwordLineEdit->setEchoMode(QLineEdit::Password);
87 connect(d->passwordLineEdit, &QLineEdit::textChanged, this, &KPasswordLineEdit::passwordChanged);
88 setFocusProxy(d->passwordLineEdit);
89 setFocusPolicy(d->passwordLineEdit->focusPolicy());
90 mainLayout->addWidget(d->passwordLineEdit);
91 d->initialize();
92 }
93
94 KPasswordLineEdit::~KPasswordLineEdit() = default;
95
setPassword(const QString & password)96 void KPasswordLineEdit::setPassword(const QString &password)
97 {
98 if (d->passwordLineEdit->text() != password) {
99 d->isToggleEchoModeAvailable = password.isEmpty();
100 d->passwordLineEdit->setText(password);
101 }
102 }
103
password() const104 QString KPasswordLineEdit::password() const
105 {
106 return d->passwordLineEdit->text();
107 }
108
clear()109 void KPasswordLineEdit::clear()
110 {
111 d->passwordLineEdit->clear();
112 }
113
setClearButtonEnabled(bool clear)114 void KPasswordLineEdit::setClearButtonEnabled(bool clear)
115 {
116 d->passwordLineEdit->setClearButtonEnabled(clear);
117 }
118
isClearButtonEnabled() const119 bool KPasswordLineEdit::isClearButtonEnabled() const
120 {
121 return d->passwordLineEdit->isClearButtonEnabled();
122 }
123
setEchoMode(QLineEdit::EchoMode mode)124 void KPasswordLineEdit::setEchoMode(QLineEdit::EchoMode mode)
125 {
126 d->passwordLineEdit->setEchoMode(mode);
127 }
128
echoMode() const129 QLineEdit::EchoMode KPasswordLineEdit::echoMode() const
130 {
131 return d->passwordLineEdit->echoMode();
132 }
133
lineEdit() const134 QLineEdit *KPasswordLineEdit::lineEdit() const
135 {
136 return d->passwordLineEdit;
137 }
138
setRevealPasswordAvailable(bool reveal)139 void KPasswordLineEdit::setRevealPasswordAvailable(bool reveal)
140 {
141 d->revealPasswordAvailable = reveal;
142 d->showToggleEchoModeAction(password());
143 }
144
isRevealPasswordAvailable() const145 bool KPasswordLineEdit::isRevealPasswordAvailable() const
146 {
147 return d->revealPasswordAvailable;
148 }
149
toggleEchoModeAction() const150 QAction *KPasswordLineEdit::toggleEchoModeAction() const
151 {
152 return d->toggleEchoModeAction;
153 }
154
155 #include "moc_kpasswordlineedit.cpp"
156