Delay masking the last character in Password echo mode.
If QT_GUI_PASSWORD_ECHO_DELAY is defined in qplatformdefs.h with an integer value in milliseconds, QLineEdit and TextInput will display the last character entered unmasked for that delay period and then mask the character as normal. If QT_GUI_PASSWORD_ECHO_DELAY is not defined then the behaviour is unchanged. Task-number: QTBUG-17003 Task-number: QTBUG-20719 Reviewed-by: Martin Jones (cherry picked from commit f9e7aee2019d321edd655bfde7de43f20a106971) Change-Id: If69b384636e3775ad7898b8ffc441011c21abe98 Reviewed-by: Joona Petrell <joona.t.petrell@nokia.com>
This commit is contained in:
parent
6e0e834e03
commit
d6fb4463b8
@ -56,6 +56,22 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
#ifdef QT_GUI_PASSWORD_ECHO_DELAY
|
||||||
|
static const int qt_passwordEchoDelay = QT_GUI_PASSWORD_ECHO_DELAY;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\macro QT_GUI_PASSWORD_ECHO_DELAY
|
||||||
|
|
||||||
|
\internal
|
||||||
|
|
||||||
|
Defines the amount of time in milliseconds the last entered character
|
||||||
|
should be displayed unmasked in the Password echo mode.
|
||||||
|
|
||||||
|
If not defined in qplatformdefs.h there will be no delay in masking
|
||||||
|
password characters.
|
||||||
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
|
|
||||||
@ -93,9 +109,25 @@ void QWidgetLineControl::updateDisplayText(bool forceUpdate)
|
|||||||
else
|
else
|
||||||
str = m_text;
|
str = m_text;
|
||||||
|
|
||||||
if (m_echoMode == QLineEdit::Password || (m_echoMode == QLineEdit::PasswordEchoOnEdit
|
if (m_echoMode == QLineEdit::Password) {
|
||||||
&& !m_passwordEchoEditing))
|
|
||||||
str.fill(m_passwordCharacter);
|
str.fill(m_passwordCharacter);
|
||||||
|
#ifdef QT_GUI_PASSWORD_ECHO_DELAY
|
||||||
|
if (m_passwordEchoTimer != 0 && m_cursor > 0 && m_cursor <= m_text.length()) {
|
||||||
|
int cursor = m_cursor - 1;
|
||||||
|
QChar uc = m_text.at(cursor);
|
||||||
|
str[cursor] = uc;
|
||||||
|
if (cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) {
|
||||||
|
// second half of a surrogate, check if we have the first half as well,
|
||||||
|
// if yes restore both at once
|
||||||
|
uc = m_text.at(cursor - 1);
|
||||||
|
if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00)
|
||||||
|
str[cursor - 1] = uc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else if (m_echoMode == QLineEdit::PasswordEchoOnEdit && !m_passwordEchoEditing) {
|
||||||
|
str.fill(m_passwordCharacter);
|
||||||
|
}
|
||||||
|
|
||||||
// replace certain non-printable characters with spaces (to avoid
|
// replace certain non-printable characters with spaces (to avoid
|
||||||
// drawing boxes when using fonts that don't have glyphs for such
|
// drawing boxes when using fonts that don't have glyphs for such
|
||||||
@ -354,6 +386,7 @@ void QWidgetLineControl::init(const QString &txt)
|
|||||||
*/
|
*/
|
||||||
void QWidgetLineControl::updatePasswordEchoEditing(bool editing)
|
void QWidgetLineControl::updatePasswordEchoEditing(bool editing)
|
||||||
{
|
{
|
||||||
|
cancelPasswordEchoTimer();
|
||||||
m_passwordEchoEditing = editing;
|
m_passwordEchoEditing = editing;
|
||||||
updateDisplayText();
|
updateDisplayText();
|
||||||
}
|
}
|
||||||
@ -707,6 +740,7 @@ bool QWidgetLineControl::finishChange(int validateFromState, bool update, bool e
|
|||||||
*/
|
*/
|
||||||
void QWidgetLineControl::internalSetText(const QString &txt, int pos, bool edited)
|
void QWidgetLineControl::internalSetText(const QString &txt, int pos, bool edited)
|
||||||
{
|
{
|
||||||
|
cancelPasswordEchoTimer();
|
||||||
internalDeselect();
|
internalDeselect();
|
||||||
emit resetInputContext();
|
emit resetInputContext();
|
||||||
QString oldText = m_text;
|
QString oldText = m_text;
|
||||||
@ -759,6 +793,13 @@ void QWidgetLineControl::addCommand(const Command &cmd)
|
|||||||
*/
|
*/
|
||||||
void QWidgetLineControl::internalInsert(const QString &s)
|
void QWidgetLineControl::internalInsert(const QString &s)
|
||||||
{
|
{
|
||||||
|
#ifdef QT_GUI_PASSWORD_ECHO_DELAY
|
||||||
|
if (m_echoMode == QLineEdit::Password) {
|
||||||
|
if (m_passwordEchoTimer != 0)
|
||||||
|
killTimer(m_passwordEchoTimer);
|
||||||
|
m_passwordEchoTimer = startTimer(qt_passwordEchoDelay);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (hasSelectedText())
|
if (hasSelectedText())
|
||||||
addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
|
addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
|
||||||
if (m_maskData) {
|
if (m_maskData) {
|
||||||
@ -796,6 +837,7 @@ void QWidgetLineControl::internalInsert(const QString &s)
|
|||||||
void QWidgetLineControl::internalDelete(bool wasBackspace)
|
void QWidgetLineControl::internalDelete(bool wasBackspace)
|
||||||
{
|
{
|
||||||
if (m_cursor < (int) m_text.length()) {
|
if (m_cursor < (int) m_text.length()) {
|
||||||
|
cancelPasswordEchoTimer();
|
||||||
if (hasSelectedText())
|
if (hasSelectedText())
|
||||||
addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
|
addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
|
||||||
addCommand(Command((CommandType)((m_maskData ? 2 : 0) + (wasBackspace ? Remove : Delete)),
|
addCommand(Command((CommandType)((m_maskData ? 2 : 0) + (wasBackspace ? Remove : Delete)),
|
||||||
@ -822,6 +864,7 @@ void QWidgetLineControl::internalDelete(bool wasBackspace)
|
|||||||
void QWidgetLineControl::removeSelectedText()
|
void QWidgetLineControl::removeSelectedText()
|
||||||
{
|
{
|
||||||
if (m_selstart < m_selend && m_selend <= (int) m_text.length()) {
|
if (m_selstart < m_selend && m_selend <= (int) m_text.length()) {
|
||||||
|
cancelPasswordEchoTimer();
|
||||||
separate();
|
separate();
|
||||||
int i ;
|
int i ;
|
||||||
addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
|
addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
|
||||||
@ -1220,6 +1263,7 @@ void QWidgetLineControl::internalUndo(int until)
|
|||||||
{
|
{
|
||||||
if (!isUndoAvailable())
|
if (!isUndoAvailable())
|
||||||
return;
|
return;
|
||||||
|
cancelPasswordEchoTimer();
|
||||||
internalDeselect();
|
internalDeselect();
|
||||||
while (m_undoState && m_undoState > until) {
|
while (m_undoState && m_undoState > until) {
|
||||||
Command& cmd = m_history[--m_undoState];
|
Command& cmd = m_history[--m_undoState];
|
||||||
@ -1424,6 +1468,12 @@ void QWidgetLineControl::timerEvent(QTimerEvent *event)
|
|||||||
} else if (event->timerId() == m_tripleClickTimer) {
|
} else if (event->timerId() == m_tripleClickTimer) {
|
||||||
killTimer(m_tripleClickTimer);
|
killTimer(m_tripleClickTimer);
|
||||||
m_tripleClickTimer = 0;
|
m_tripleClickTimer = 0;
|
||||||
|
#ifdef QT_GUI_PASSWORD_ECHO_DELAY
|
||||||
|
} else if (event->timerId() == m_passwordEchoTimer) {
|
||||||
|
killTimer(m_passwordEchoTimer);
|
||||||
|
m_passwordEchoTimer = 0;
|
||||||
|
updateDisplayText();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +68,8 @@
|
|||||||
|
|
||||||
#include "qplatformdefs.h"
|
#include "qplatformdefs.h"
|
||||||
|
|
||||||
|
#include "qplatformdefs.h"
|
||||||
|
|
||||||
QT_BEGIN_HEADER
|
QT_BEGIN_HEADER
|
||||||
|
|
||||||
#ifdef DrawText
|
#ifdef DrawText
|
||||||
@ -252,6 +254,7 @@ public:
|
|||||||
uint echoMode() const { return m_echoMode; }
|
uint echoMode() const { return m_echoMode; }
|
||||||
void setEchoMode(uint mode)
|
void setEchoMode(uint mode)
|
||||||
{
|
{
|
||||||
|
cancelPasswordEchoTimer();
|
||||||
m_echoMode = mode;
|
m_echoMode = mode;
|
||||||
m_passwordEchoEditing = false;
|
m_passwordEchoEditing = false;
|
||||||
updateDisplayText();
|
updateDisplayText();
|
||||||
@ -301,7 +304,13 @@ public:
|
|||||||
QString preeditAreaText() const { return m_textLayout.preeditAreaText(); }
|
QString preeditAreaText() const { return m_textLayout.preeditAreaText(); }
|
||||||
|
|
||||||
void updatePasswordEchoEditing(bool editing);
|
void updatePasswordEchoEditing(bool editing);
|
||||||
bool passwordEchoEditing() const { return m_passwordEchoEditing; }
|
bool passwordEchoEditing() const {
|
||||||
|
#ifdef QT_GUI_PASSWORD_ECHO_DELAY
|
||||||
|
if (m_passwordEchoTimer != 0)
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
return m_passwordEchoEditing ;
|
||||||
|
}
|
||||||
|
|
||||||
QChar passwordCharacter() const { return m_passwordCharacter; }
|
QChar passwordCharacter() const { return m_passwordCharacter; }
|
||||||
void setPasswordCharacter(const QChar &character) { m_passwordCharacter = character; updateDisplayText(); }
|
void setPasswordCharacter(const QChar &character) { m_passwordCharacter = character; updateDisplayText(); }
|
||||||
@ -474,6 +483,18 @@ private:
|
|||||||
|
|
||||||
bool m_passwordEchoEditing;
|
bool m_passwordEchoEditing;
|
||||||
QChar m_passwordCharacter;
|
QChar m_passwordCharacter;
|
||||||
|
#ifdef QT_GUI_PASSWORD_ECHO_DELAY
|
||||||
|
int m_passwordEchoTimer;
|
||||||
|
#endif
|
||||||
|
void cancelPasswordEchoTimer()
|
||||||
|
{
|
||||||
|
#ifdef QT_GUI_PASSWORD_ECHO_DELAY
|
||||||
|
if (m_passwordEchoTimer != 0) {
|
||||||
|
killTimer(m_passwordEchoTimer);
|
||||||
|
m_passwordEchoTimer = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int redoTextLayout() const;
|
int redoTextLayout() const;
|
||||||
#if defined(Q_WS_MAC)
|
#if defined(Q_WS_MAC)
|
||||||
|
Loading…
Reference in New Issue
Block a user