VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/wizards/editors/UIUserNamePasswordEditor.cpp@ 103551

Last change on this file since 103551 was 101560, checked in by vboxsync, 14 months ago

FE/Qt: bugref:10450: Bits forgotten in r159636.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.7 KB
Line 
1/* $Id: UIUserNamePasswordEditor.cpp 101560 2023-10-23 16:10:12Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIUserNamePasswordEditor class implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QGridLayout>
30#include <QLabel>
31#include <QStyle>
32#include <QVBoxLayout>
33#include <QWindow>
34
35/* GUI includes: */
36#include "QILineEdit.h"
37#include "QIRichTextLabel.h"
38#include "QIToolButton.h"
39#include "UICursor.h"
40#include "UIIconPool.h"
41#include "UIUserNamePasswordEditor.h"
42
43/* Other VBox includes: */
44#include "iprt/assert.h"
45
46
47UIPasswordLineEdit::UIPasswordLineEdit(QWidget *pParent /*= 0 */)
48 : QLineEdit(pParent)
49 , m_pTextVisibilityButton(0)
50 , m_pErrorIconLabel(0)
51 , m_fMarkForError(false)
52{
53 prepare();
54}
55
56void UIPasswordLineEdit::toggleTextVisibility(bool fTextVisible)
57{
58 AssertPtrReturnVoid(m_pTextVisibilityButton);
59
60 if (fTextVisible)
61 {
62 setEchoMode(QLineEdit::Normal);
63 if (m_pTextVisibilityButton)
64 m_pTextVisibilityButton->setIcon(UIIconPool::iconSet(":/eye_closed_10px.png"));
65 }
66 else
67 {
68 setEchoMode(QLineEdit::Password);
69 if (m_pTextVisibilityButton)
70 m_pTextVisibilityButton->setIcon(UIIconPool::iconSet(":/eye_10px.png"));
71 }
72}
73
74void UIPasswordLineEdit::mark(bool fError, const QString &strErrorToolTip)
75{
76 /* Check if something really changed: */
77 if (m_fMarkForError == fError && m_strErrorToolTip == strErrorToolTip)
78 return;
79
80 /* Save new values: */
81 m_fMarkForError = fError;
82 m_strErrorToolTip = strErrorToolTip;
83
84 /* Update accordingly: */
85 if (m_fMarkForError)
86 {
87 /* Create label if absent: */
88 if (!m_pErrorIconLabel)
89 m_pErrorIconLabel = new QLabel(this);
90
91 /* Update label content, visibility & position: */
92 const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) * .625;
93 const int iShift = height() > iIconMetric ? (height() - iIconMetric) / 2 : 0;
94 const qreal fDevicePixelRatio = window() && window()->windowHandle() ? window()->windowHandle()->devicePixelRatio() : 1;
95 m_pErrorIconLabel->setPixmap(m_markIcon.pixmap(QSize(iIconMetric, iIconMetric), fDevicePixelRatio));
96 m_pErrorIconLabel->setToolTip(m_strErrorToolTip);
97 int iIconX = width() - iIconMetric - iShift;
98 if (m_pTextVisibilityButton)
99 iIconX -= m_pTextVisibilityButton->width() - iShift;
100 m_pErrorIconLabel->move(iIconX, iShift);
101 m_pErrorIconLabel->show();
102 }
103 else
104 {
105 /* Hide label: */
106 if (m_pErrorIconLabel)
107 m_pErrorIconLabel->hide();
108 }
109}
110
111void UIPasswordLineEdit::prepare()
112{
113 m_markIcon = UIIconPool::iconSet(":/status_error_16px.png");
114 /* Prepare text visibility button: */
115 m_pTextVisibilityButton = new QIToolButton(this);
116 if (m_pTextVisibilityButton)
117 {
118 m_pTextVisibilityButton->setIconSize(QSize(10, 10));
119 m_pTextVisibilityButton->setFocusPolicy(Qt::ClickFocus);
120 UICursor::setCursor(m_pTextVisibilityButton, Qt::ArrowCursor);
121 m_pTextVisibilityButton->show();
122 connect(m_pTextVisibilityButton, &QToolButton::clicked, this, &UIPasswordLineEdit::sltHandleTextVisibilityChange);
123 }
124 m_pErrorIconLabel = new QLabel(this);
125 toggleTextVisibility(false);
126 adjustTextVisibilityButtonGeometry();
127}
128
129void UIPasswordLineEdit::adjustTextVisibilityButtonGeometry()
130{
131 AssertPtrReturnVoid(m_pTextVisibilityButton);
132
133#ifdef VBOX_WS_MAC
134 /* Do not forget to update QIToolButton size on macOS, it's FIXED: */
135 m_pTextVisibilityButton->setFixedSize(m_pTextVisibilityButton->minimumSizeHint());
136 /* Calculate suitable position for a QIToolButton, it's FRAMELESS: */
137 const int iWidth = m_pTextVisibilityButton->width();
138 const int iMinHeight = qMin(height(), m_pTextVisibilityButton->height());
139 const int iMaxHeight = qMax(height(), m_pTextVisibilityButton->height());
140 const int iHalfHeightDiff = (iMaxHeight - iMinHeight) / 2;
141 m_pTextVisibilityButton->setGeometry(width() - iWidth - iHalfHeightDiff, iHalfHeightDiff, iWidth, iWidth);
142#else
143 int iFrameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
144 int iSize = height() - 2 * iFrameWidth;
145 m_pTextVisibilityButton->setGeometry(width() - iSize, iFrameWidth, iSize, iSize);
146#endif
147}
148
149void UIPasswordLineEdit::resizeEvent(QResizeEvent *pEvent)
150{
151 /* Call to base-class: */
152 QLineEdit::resizeEvent(pEvent);
153 adjustTextVisibilityButtonGeometry();
154
155 /* Update error label position: */
156 if (m_pErrorIconLabel)
157 {
158 const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) * .625;
159 const int iShift = height() > iIconMetric ? (height() - iIconMetric) / 2 : 0;
160 int iIconX = width() - iIconMetric - iShift;
161 if (m_pTextVisibilityButton)
162 iIconX -= m_pTextVisibilityButton->width() - iShift;
163 m_pErrorIconLabel->move(iIconX, iShift);
164 }
165}
166
167void UIPasswordLineEdit::sltHandleTextVisibilityChange()
168{
169 bool fTextVisible = false;
170 if (echoMode() == QLineEdit::Normal)
171 fTextVisible = false;
172 else
173 fTextVisible = true;
174 toggleTextVisibility(fTextVisible);
175 emit sigTextVisibilityToggled(fTextVisible);
176}
177
178
179/*********************************************************************************************************************************
180* UIUserNamePasswordEditor implementation. *
181*********************************************************************************************************************************/
182
183UIUserNamePasswordEditor::UIUserNamePasswordEditor(QWidget *pParent /* = 0 */)
184 : QIWithRetranslateUI<QWidget>(pParent)
185 , m_pUserNameLineEdit(0)
186 , m_pPasswordLineEdit(0)
187 , m_pPasswordRepeatLineEdit(0)
188 , m_pUserNameLabel(0)
189 , m_pPasswordLabel(0)
190 , m_pPasswordRepeatLabel(0)
191 , m_fShowPlaceholderText(true)
192 , m_fLabelsVisible(true)
193{
194 prepare();
195}
196
197QString UIUserNamePasswordEditor::userName() const
198{
199 if (m_pUserNameLineEdit)
200 return m_pUserNameLineEdit->text();
201 return QString();
202}
203
204void UIUserNamePasswordEditor::setUserName(const QString &strUserName)
205{
206 if (m_pUserNameLineEdit)
207 return m_pUserNameLineEdit->setText(strUserName);
208}
209
210QString UIUserNamePasswordEditor::password() const
211{
212 if (m_pPasswordLineEdit)
213 return m_pPasswordLineEdit->text();
214 return QString();
215}
216
217void UIUserNamePasswordEditor::setPassword(const QString &strPassword)
218{
219 if (m_pPasswordLineEdit)
220 m_pPasswordLineEdit->setText(strPassword);
221 if (m_pPasswordRepeatLineEdit)
222 m_pPasswordRepeatLineEdit->setText(strPassword);
223}
224
225bool UIUserNamePasswordEditor::isUserNameComplete()
226{
227 bool fComplete = (m_pUserNameLineEdit && !m_pUserNameLineEdit->text().isEmpty());
228 if (m_pUserNameLineEdit)
229 m_pUserNameLineEdit->mark(!fComplete, UIUserNamePasswordEditor::tr("Invalid username"));
230 return fComplete;
231}
232
233bool UIUserNamePasswordEditor::isPasswordComplete()
234{
235 bool fPasswordOK = true;
236 if (m_pPasswordLineEdit && m_pPasswordRepeatLineEdit)
237 {
238 if (m_pPasswordLineEdit->text() != m_pPasswordRepeatLineEdit->text())
239 fPasswordOK = false;
240 if (m_pPasswordLineEdit->text().isEmpty())
241 fPasswordOK = false;
242 m_pPasswordLineEdit->mark(!fPasswordOK, m_strPasswordError);
243 m_pPasswordRepeatLineEdit->mark(!fPasswordOK, m_strPasswordError);
244 }
245 return fPasswordOK;
246}
247
248bool UIUserNamePasswordEditor::isComplete()
249{
250 bool fUserNameField = isUserNameComplete();
251 bool fPasswordField = isPasswordComplete();
252 return fUserNameField && fPasswordField;
253}
254
255void UIUserNamePasswordEditor::setPlaceholderTextEnabled(bool fEnabled)
256{
257 if (m_fShowPlaceholderText == fEnabled)
258 return;
259 m_fShowPlaceholderText = fEnabled;
260 retranslateUi();
261}
262
263void UIUserNamePasswordEditor::setLabelsVisible(bool fVisible)
264{
265 if (m_fLabelsVisible == fVisible)
266 return;
267 m_fLabelsVisible = fVisible;
268 m_pUserNameLabel->setVisible(fVisible);
269 m_pPasswordLabel->setVisible(fVisible);
270 m_pPasswordRepeatLabel->setVisible(fVisible);
271
272}
273
274void UIUserNamePasswordEditor::retranslateUi()
275{
276 QString strPassword = tr("Pass&word");
277 QString strRepeatPassword = tr("&Repeat Password");
278 QString strUsername = tr("U&sername");
279 if (m_pUserNameLabel)
280 m_pUserNameLabel->setText(QString("%1%2").arg(strUsername).arg(":"));
281
282 if (m_pPasswordLabel)
283 m_pPasswordLabel->setText(QString("%1%2").arg(strPassword).arg(":"));
284
285 if (m_pPasswordRepeatLabel)
286 m_pPasswordRepeatLabel->setText(QString("%1%2").arg(strRepeatPassword).arg(":"));
287
288 if (m_fShowPlaceholderText)
289 {
290 if(m_pUserNameLineEdit)
291 m_pUserNameLineEdit->setPlaceholderText(strUsername.remove('&'));
292 if (m_pPasswordLineEdit)
293 m_pPasswordLineEdit->setPlaceholderText(strPassword.remove('&'));
294 if (m_pPasswordRepeatLineEdit)
295 m_pPasswordRepeatLineEdit->setPlaceholderText(strRepeatPassword.remove('&'));
296 }
297 else
298 {
299 if(m_pUserNameLineEdit)
300 m_pUserNameLineEdit->setPlaceholderText(QString());
301 if (m_pPasswordLineEdit)
302 m_pPasswordLineEdit->setPlaceholderText(QString());
303 if (m_pPasswordRepeatLineEdit)
304 m_pPasswordRepeatLineEdit->setPlaceholderText(QString());
305 }
306 if(m_pUserNameLineEdit)
307 m_pUserNameLineEdit->setToolTip(tr("Holds username."));
308 if (m_pPasswordLineEdit)
309 m_pPasswordLineEdit->setToolTip(tr("Holds password."));
310 if (m_pPasswordRepeatLineEdit)
311 m_pPasswordRepeatLineEdit->setToolTip(tr("Holds the repeated password."));
312 m_strPasswordError = tr("Invalid password pair");
313}
314
315template <class T>
316void UIUserNamePasswordEditor::addLineEdit(int &iRow, QLabel *&pLabel, T *&pLineEdit, QGridLayout *pLayout)
317{
318 if (!pLayout || pLabel || pLineEdit)
319 return;
320 pLabel = new QLabel;
321 if (!pLabel)
322 return;
323 pLabel->setAlignment(Qt::AlignRight);
324 pLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
325
326 pLayout->addWidget(pLabel, iRow, 0, 1, 1);
327
328 pLineEdit = new T;
329 if (!pLineEdit)
330 return;
331 pLayout->addWidget(pLineEdit, iRow, 1, 1, 3);
332
333 pLabel->setBuddy(pLineEdit);
334 ++iRow;
335 return;
336}
337
338void UIUserNamePasswordEditor::prepare()
339{
340 QGridLayout *pMainLayout = new QGridLayout;
341 pMainLayout->setColumnStretch(0, 0);
342 pMainLayout->setColumnStretch(1, 1);
343 if (!pMainLayout)
344 return;
345 setLayout(pMainLayout);
346 int iRow = 0;
347 addLineEdit<UIMarkableLineEdit>(iRow, m_pUserNameLabel, m_pUserNameLineEdit, pMainLayout);
348 addLineEdit<UIPasswordLineEdit>(iRow, m_pPasswordLabel, m_pPasswordLineEdit, pMainLayout);
349 addLineEdit<UIPasswordLineEdit>(iRow, m_pPasswordRepeatLabel, m_pPasswordRepeatLineEdit, pMainLayout);
350
351 connect(m_pPasswordLineEdit, &UIPasswordLineEdit::sigTextVisibilityToggled,
352 this, &UIUserNamePasswordEditor::sltHandlePasswordVisibility);
353 connect(m_pPasswordRepeatLineEdit, &UIPasswordLineEdit::sigTextVisibilityToggled,
354 this, &UIUserNamePasswordEditor::sltHandlePasswordVisibility);
355 connect(m_pPasswordLineEdit, &UIPasswordLineEdit::textChanged,
356 this, &UIUserNamePasswordEditor::sltPasswordChanged);
357 connect(m_pPasswordRepeatLineEdit, &UIPasswordLineEdit::textChanged,
358 this, &UIUserNamePasswordEditor::sltPasswordChanged);
359 connect(m_pUserNameLineEdit, &UIMarkableLineEdit::textChanged,
360 this, &UIUserNamePasswordEditor::sltUserNameChanged);
361
362 retranslateUi();
363}
364
365void UIUserNamePasswordEditor::sltHandlePasswordVisibility(bool fPasswordVisible)
366{
367 if (m_pPasswordLineEdit)
368 m_pPasswordLineEdit->toggleTextVisibility(fPasswordVisible);
369 if (m_pPasswordRepeatLineEdit)
370 m_pPasswordRepeatLineEdit->toggleTextVisibility(fPasswordVisible);
371}
372
373void UIUserNamePasswordEditor::sltUserNameChanged()
374{
375 isUserNameComplete();
376 emit sigUserNameChanged(m_pUserNameLineEdit->text());
377}
378
379void UIUserNamePasswordEditor::sltPasswordChanged()
380{
381 isPasswordComplete();
382 emit sigPasswordChanged(m_pPasswordLineEdit->text());
383}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette