Index: sources/gui/qml/pages/UserConfirmation.qml =================================================================== diff -u -r934354462a353ff5e7fc2ddfe6f3a8f0121a8f3f -r88a09dc4b26cfdd5fd111d20adfb9cb60697186c --- sources/gui/qml/pages/UserConfirmation.qml (.../UserConfirmation.qml) (revision 934354462a353ff5e7fc2ddfe6f3a8f0121a8f3f) +++ sources/gui/qml/pages/UserConfirmation.qml (.../UserConfirmation.qml) (revision 88a09dc4b26cfdd5fd111d20adfb9cb60697186c) @@ -14,7 +14,7 @@ */ // Qt -import QtQuick 2.12 +import QtQuick 2.15 // Project @@ -27,8 +27,12 @@ * \brief Contains the message for user information or password entry for user to confirm. */ SettingsBase { id: _root - objectName : "UserConfirmation" // SquishQt testability + objectName : "UserConfirmation" // SquishQt testability + confirmEnabled : ! passwordChangeMode || + (vSettings.isPasswordHighStrength(_root.passwordUpdated) && + _root.passwordUpdated === _root.passwordConfirm) + property bool isPassword : false property bool passwordChangeMode : false readonly property string passwordCurrent : _passwordCurrent.textInput.text @@ -37,53 +41,77 @@ property int passwordLengthMax : 30 property alias message : _message.text - function clearPasswordCurrnet() { _passwordCurrent.textInput.text = "" } + readonly property string hidePassword : "qrc:/images/iEyeClosed" + readonly property string showPassword : "qrc:/images/iEye" + + function clearPasswordCurrent() { _passwordCurrent.textInput.text = "" } function clearPasswordUpdated() { _passwordUpdated.textInput.text = "" } function clearPasswordReEntry() { _passwordConfirm.textInput.text = "" } function clearPasswords () { - clearPasswordCurrnet() + clearPasswordCurrent() clearPasswordUpdated() clearPasswordReEntry() } firstFocusInput : isPassword ? _passwordCurrent : undefined - contentItem: Column { + contentItem: Item { visible: isPassword - PasswordEntry { id: _passwordCurrent - label.text : ! passwordChangeMode ? "" : qsTr("Current") - label.width : ! passwordChangeMode ? 0 : labelWidth - lengthMax : passwordLengthMax - nextInput : _passwordUpdated - anchors { - top : parent.top - topMargin : Variables.defaultMargin * 5 - horizontalCenter : parent.horizontalCenter + Column { id: _passwordEntries + anchors.horizontalCenter : parent.horizontalCenter + anchors.horizontalCenterOffset : passwordChangeMode ? Variables.defaultMargin * -4 : 0 + width : parent.width / 2.5 + + PasswordEntry { id: _passwordCurrent + visible : ! passwordChangeMode + label.text : "" + label.width : 0 + lengthMax : passwordLengthMax + nextInput : _passwordUpdated + anchors { + top : parent.top + topMargin : passwordChangeMode ? Variables.defaultMargin * 2 : Variables.defaultMargin * 5 + horizontalCenter : parent.horizontalCenter + } } - } - PasswordEntry { id: _passwordUpdated - visible : passwordChangeMode - label.text : qsTr("New") - nextInput : _passwordConfirm - lengthMax : passwordLengthMax - anchors { - top : _passwordCurrent.bottom - horizontalCenter : parent.horizontalCenter + PasswordEntry { id: _passwordUpdated + visible : passwordChangeMode + label.text : qsTr("New") + nextInput : _passwordConfirm + lengthMax : passwordLengthMax + anchors { + top : _passwordCurrent.bottom + horizontalCenter : parent.horizontalCenter + } } + + PasswordEntry { id: _passwordConfirm + visible : passwordChangeMode + label.text : qsTr("Confirm") + lengthMax : passwordLengthMax + anchors { + top : _passwordUpdated.bottom + horizontalCenter : parent.horizontalCenter + } + } } - PasswordEntry { id: _passwordConfirm - visible : passwordChangeMode - label.text : qsTr("Confirm") - lengthMax : passwordLengthMax + PasswordRequirements {id: _passwordRequirements anchors { - top : _passwordUpdated.bottom - horizontalCenter : parent.horizontalCenter + top : parent.top + topMargin : Variables.defaultMargin * 2 + left : _passwordEntries.right + leftMargin : Variables.defaultMargin * 2 } + visible : passwordChangeMode + height : parent.height / 2 + width : parent.width / 4 + password : passwordUpdated } } + component PasswordEntry : Item { property alias textInput : _passwordEntry.textInput property alias nextInput : _passwordEntry.nextInput @@ -95,23 +123,31 @@ label.width : labelWidth TextEntry { id: _passwordEntry - clip : true - textInput .width : 450 + clip : true + textInput .width : 450 textInput.inputMethodHints : Qt.ImhNone textInput.echoMode : TextInput.Password anchors.horizontalCenter : parent.horizontalCenter + + onTextChanged: { + // Replace non-ASCII characters as they are typed in + var filtered = text.replace(/[^\x00-\x7F]/g, "") + if (text !== filtered) { text = filtered } // revert invalid characters + } } Image { visible : _passwordEntry.visible anchors.left : _passwordEntry.right anchors.leftMargin : Variables.minVGap anchors.verticalCenter : _passwordEntry.verticalCenter - width : Variables.iconsDiameter - height : Variables.iconsDiameter - source : "qrc:/images/iEye" + width : 35 + height : 35 - MouseArea { + source : _mouseArea.pressed ? _root.showPassword : _root.hidePassword + fillMode : Image.PreserveAspectFit + + MouseArea { id: _mouseArea anchors.fill: parent anchors.margins: -20 onPressed : _passwordEntry.textInput.echoMode = TextInput.Normal