From f3612f39ff5fb07f83b89732e8b7a643ee6d5cd3 Mon Sep 17 00:00:00 2001
From: Mitch Curtis <mitch.curtis@digia.com>
Date: Wed, 13 Mar 2013 14:32:08 +0100
Subject: [PATCH] Make password mask characters themeable.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Task-number: QTBUG-29871

Change-Id: I3cf739a321d7917f8f8431992e29bba0871b1934
Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
---
 src/gui/kernel/qplatformintegration.cpp          |  2 ++
 src/gui/kernel/qplatformintegration.h            |  3 ++-
 src/gui/kernel/qplatformtheme.cpp                |  2 ++
 src/gui/kernel/qplatformtheme.h                  |  3 ++-
 src/gui/kernel/qstylehints.cpp                   |  9 +++++++++
 src/gui/kernel/qstylehints.h                     |  1 +
 .../themes/genericunix/qgenericunixthemes.cpp    |  2 ++
 src/plugins/platforms/cocoa/qcocoatheme.mm       |  2 ++
 src/widgets/styles/qcommonstyle.cpp              | 16 ++++------------
 src/widgets/styles/qmacstyle_mac.mm              |  3 ---
 src/widgets/styles/qwindowsstyle.cpp             | 15 ---------------
 src/widgets/widgets/qlineedit.cpp                | 13 +++++++------
 12 files changed, 33 insertions(+), 38 deletions(-)

diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index 8a0540efc2e..e82e30df808 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -313,6 +313,8 @@ QVariant QPlatformIntegration::styleHint(StyleHint hint) const
         return false;
     case PasswordMaskDelay:
         return QPlatformTheme::defaultThemeHint(QPlatformTheme::PasswordMaskDelay);
+    case PasswordMaskCharacter:
+        return QPlatformTheme::defaultThemeHint(QPlatformTheme::PasswordMaskCharacter);
     case FontSmoothingGamma:
         return qreal(1.7);
     case StartDragVelocity:
diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h
index bee2ba0caf1..b7a44b13de2 100644
--- a/src/gui/kernel/qplatformintegration.h
+++ b/src/gui/kernel/qplatformintegration.h
@@ -140,7 +140,8 @@ public:
         FontSmoothingGamma,
         StartDragVelocity,
         UseRtlExtensions,
-        SynthesizeMouseFromTouchEvents
+        SynthesizeMouseFromTouchEvents,
+        PasswordMaskCharacter
     };
 
     virtual QVariant styleHint(StyleHint hint) const;
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index b8bc72cf735..02b69bcb4d0 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -238,6 +238,8 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
         return QVariant(500);
     case QPlatformTheme::PasswordMaskDelay:
         return QVariant(int(0));
+    case QPlatformTheme::PasswordMaskCharacter:
+        return QVariant(QChar(0x25CF));
     case QPlatformTheme::StartDragVelocity:
         return QVariant(int(0)); // no limit
     case QPlatformTheme::UseFullScreenForPopupMenu:
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index ee127925471..80ba29a0281 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -103,7 +103,8 @@ public:
         UiEffects,
         SpellCheckUnderlineStyle,
         TabAllWidgets,
-        IconPixmapSizes
+        IconPixmapSizes,
+        PasswordMaskCharacter
     };
 
     enum DialogType {
diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp
index 23bc165edd5..30b12835f71 100644
--- a/src/gui/kernel/qstylehints.cpp
+++ b/src/gui/kernel/qstylehints.cpp
@@ -192,6 +192,15 @@ int QStyleHints::passwordMaskDelay() const
     return themeableHint(QPlatformTheme::PasswordMaskDelay, QPlatformIntegration::PasswordMaskDelay).toInt();
 }
 
+/*!
+    Returns the character used to mask the characters typed into text input
+    fields in password mode.
+*/
+QChar QStyleHints::passwordMaskCharacter() const
+{
+    return themeableHint(QPlatformTheme::PasswordMaskCharacter, QPlatformIntegration::PasswordMaskCharacter).toChar();
+}
+
 /*!
     Returns the gamma value used in font smoothing.
 */
diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h
index 7a447aae677..64ef182aabb 100644
--- a/src/gui/kernel/qstylehints.h
+++ b/src/gui/kernel/qstylehints.h
@@ -62,6 +62,7 @@ public:
     int cursorFlashTime() const;
     bool showIsFullScreen() const;
     int passwordMaskDelay() const;
+    QChar passwordMaskCharacter() const;
     qreal fontSmoothingGamma() const;
     bool useRtlExtensions() const;
 
diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
index 4fc542c39ae..cabddcc8155 100644
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
@@ -448,6 +448,8 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
     }
     case QPlatformTheme::KeyboardScheme:
         return QVariant(int(GnomeKeyboardScheme));
+    case QPlatformTheme::PasswordMaskCharacter:
+        return QVariant(QChar(0x2022));
     default:
         break;
     }
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index f8eed0ebf17..8337e00eb6d 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -290,6 +290,8 @@ QVariant QCocoaTheme::themeHint(ThemeHint hint) const
         sizes << 16 << 32 << 64 << 128;
         return QVariant::fromValue(sizes);
     }
+    case QPlatformTheme::PasswordMaskDelay:
+        return QVariant(QChar(kBulletUnicode));
     default:
         break;
     }
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index f7ae667a825..c6edbee67d0 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -4905,20 +4905,12 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
             ret = -1;
         break;
     case SH_LineEdit_PasswordCharacter: {
-        const QFontMetrics &fm = opt ? opt->fontMetrics
-                                     : (widget ? widget->fontMetrics() : QFontMetrics(QFont()));
-        ret = 0;
-        if (fm.inFont(QChar(0x25CF))) {
-            ret = 0x25CF;
-        } else if (fm.inFont(QChar(0x2022))) {
-            ret = 0x2022;
-        } else {
-            ret = '*';
-        }
+        const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
+        const QPlatformTheme::ThemeHint hintType = QPlatformTheme::PasswordMaskCharacter;
+        const QVariant hint = theme ? theme->themeHint(hintType) : QPlatformTheme::defaultThemeHint(hintType);
+        ret = hint.toChar().unicode();
         break;
     }
-
-
     case SH_ToolBox_SelectedPageTitleBold:
         ret = 1;
         break;
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index ed721e06c41..b2bf2c55656 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -2466,9 +2466,6 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w
     case SH_TabBar_PreferNoArrows:
         ret = true;
         break;
-    case SH_LineEdit_PasswordCharacter:
-        ret = kBulletUnicode;
-        break;
         /*
     case SH_DialogButtons_DefaultButton:
         ret = QDialogButtons::Reject;
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
index 86fccabcbcb..0acd6052c8d 100644
--- a/src/widgets/styles/qwindowsstyle.cpp
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -602,21 +602,6 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid
         }
         break;
 #endif // QT_NO_RUBBERBAND
-    case SH_LineEdit_PasswordCharacter:
-        {
-#ifdef Q_OS_WIN
-            if (widget && (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based))) {
-                const QFontMetrics &fm = widget->fontMetrics();
-                if (fm.inFont(QChar(0x25CF)))
-                    ret = 0x25CF;
-                else if (fm.inFont(QChar(0x2022)))
-                    ret = 0x2022;
-            }
-#endif
-            if (!ret)
-                ret = '*';
-        }
-        break;
 #ifndef QT_NO_WIZARD
     case SH_WizardStyle:
         ret = QWizard::ModernStyle;
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index ea58ec1429c..abef6e88321 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -360,9 +360,9 @@ void QLineEdit::setPlaceholderText(const QString& placeholderText)
     \brief the displayed text
 
     If \l echoMode is \l Normal this returns the same as text(); if
-    \l EchoMode is \l Password or \l PasswordEchoOnEdit it returns a string of asterisks
-    text().length() characters long, e.g. "******"; if \l EchoMode is
-    \l NoEcho returns an empty string, "".
+    \l EchoMode is \l Password or \l PasswordEchoOnEdit it returns a string of
+    platform-dependent password mask characters text().length() in size,
+    e.g. "******"; if \l EchoMode is \l NoEcho returns an empty string, "".
 
     By default, this property contains an empty string.
 
@@ -440,10 +440,11 @@ void QLineEdit::setFrame(bool enable)
     \value NoEcho   Do not display anything. This may be appropriate
                     for passwords where even the length of the
                     password should be kept secret.
-    \value Password  Display asterisks instead of the characters
-                    actually entered.
+    \value Password  Display platform-dependent password mask characters instead
+                    of the characters actually entered.
     \value PasswordEchoOnEdit Display characters as they are entered
-                    while editing otherwise display asterisks.
+                    while editing otherwise display characters as with
+                    \c Password.
 
     \sa setEchoMode(), echoMode()
 */
-- 
GitLab