mirror of
https://github.com/monero-project/monero-gui.git
synced 2024-12-23 03:59:38 +00:00
Merge pull request #2240
35a0f25
PasswordDialog: merge components and bug fixes (selsta)
This commit is contained in:
commit
3a9f0e1100
13 changed files with 369 additions and 713 deletions
|
@ -1,287 +0,0 @@
|
||||||
// Copyright (c) 2014-2019, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
import QtQuick 2.9
|
|
||||||
import QtQuick.Controls 2.0
|
|
||||||
import QtQuick.Dialogs 1.2
|
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
import QtQuick.Controls.Styles 1.4
|
|
||||||
import QtQuick.Window 2.0
|
|
||||||
import FontAwesome 1.0
|
|
||||||
|
|
||||||
import "../components" as MoneroComponents
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
visible: false
|
|
||||||
z: parent.z + 2
|
|
||||||
|
|
||||||
property bool isHidden: true
|
|
||||||
property alias password: passwordInput1.text
|
|
||||||
|
|
||||||
// same signals as Dialog has
|
|
||||||
signal accepted()
|
|
||||||
signal rejected()
|
|
||||||
signal closeCallback()
|
|
||||||
|
|
||||||
function open() {
|
|
||||||
isHidden = true
|
|
||||||
passwordInput1.echoMode = TextInput.Password;
|
|
||||||
passwordInput2.echoMode = TextInput.Password;
|
|
||||||
inactiveOverlay.visible = true
|
|
||||||
leftPanel.enabled = false
|
|
||||||
middlePanel.enabled = false
|
|
||||||
titleBar.state = "essentials"
|
|
||||||
root.visible = true;
|
|
||||||
passwordInput1.text = "";
|
|
||||||
passwordInput2.text = "";
|
|
||||||
passwordInput1.focus = true
|
|
||||||
}
|
|
||||||
|
|
||||||
function close() {
|
|
||||||
inactiveOverlay.visible = false
|
|
||||||
leftPanel.enabled = true
|
|
||||||
middlePanel.enabled = true
|
|
||||||
titleBar.state = "default"
|
|
||||||
root.visible = false;
|
|
||||||
closeCallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleIsHidden() {
|
|
||||||
passwordInput1.echoMode = isHidden ? TextInput.Normal : TextInput.Password;
|
|
||||||
passwordInput2.echoMode = isHidden ? TextInput.Normal : TextInput.Password;
|
|
||||||
isHidden = !isHidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: implement without hardcoding sizes
|
|
||||||
width: 480
|
|
||||||
height: 360
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
z: inactiveOverlay.z + 1
|
|
||||||
id: mainLayout
|
|
||||||
spacing: 10
|
|
||||||
anchors { fill: parent; margins: 35 }
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: column
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.maximumWidth: 400
|
|
||||||
|
|
||||||
Label {
|
|
||||||
text: qsTr("Please enter new password") + translationManager.emptyString
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
font.pixelSize: 16
|
|
||||||
font.family: MoneroComponents.Style.fontLight.name
|
|
||||||
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
}
|
|
||||||
|
|
||||||
TextField {
|
|
||||||
id : passwordInput1
|
|
||||||
Layout.topMargin: 6
|
|
||||||
Layout.fillWidth: true
|
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
|
||||||
font.family: MoneroComponents.Style.fontLight.name
|
|
||||||
font.pixelSize: 24
|
|
||||||
echoMode: TextInput.Password
|
|
||||||
bottomPadding: 10
|
|
||||||
leftPadding: 10
|
|
||||||
topPadding: 10
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
selectionColor: MoneroComponents.Style.textSelectionColor
|
|
||||||
selectedTextColor: MoneroComponents.Style.textSelectedColor
|
|
||||||
KeyNavigation.tab: passwordInput2
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
radius: 2
|
|
||||||
border.color: MoneroComponents.Style.inputBorderColorInActive
|
|
||||||
border.width: 1
|
|
||||||
color: MoneroComponents.Style.blackTheme ? "black" : "#A9FFFFFF"
|
|
||||||
|
|
||||||
MoneroComponents.Label {
|
|
||||||
fontSize: 20
|
|
||||||
text: isHidden ? FontAwesome.eye : FontAwesome.eyeSlash
|
|
||||||
opacity: 0.7
|
|
||||||
fontFamily: FontAwesome.fontFamily
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 15
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.verticalCenterOffset: 1
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: {
|
|
||||||
toggleIsHidden()
|
|
||||||
}
|
|
||||||
onEntered: {
|
|
||||||
parent.opacity = 0.9
|
|
||||||
parent.fontSize = 24
|
|
||||||
}
|
|
||||||
onExited: {
|
|
||||||
parent.opacity = 0.7
|
|
||||||
parent.fontSize = 20
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onEscapePressed: {
|
|
||||||
root.close()
|
|
||||||
root.rejected()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// padding
|
|
||||||
Rectangle {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
height: 10
|
|
||||||
opacity: 0
|
|
||||||
color: "black"
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
text: qsTr("Please confirm new password") + translationManager.emptyString
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
font.pixelSize: 16
|
|
||||||
font.family: MoneroComponents.Style.fontLight.name
|
|
||||||
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
}
|
|
||||||
|
|
||||||
TextField {
|
|
||||||
id : passwordInput2
|
|
||||||
Layout.topMargin: 6
|
|
||||||
Layout.fillWidth: true
|
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
|
||||||
font.family: MoneroComponents.Style.fontLight.name
|
|
||||||
font.pixelSize: 24
|
|
||||||
echoMode: TextInput.Password
|
|
||||||
KeyNavigation.tab: okButton
|
|
||||||
bottomPadding: 10
|
|
||||||
leftPadding: 10
|
|
||||||
topPadding: 10
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
selectionColor: MoneroComponents.Style.textSelectionColor
|
|
||||||
selectedTextColor: MoneroComponents.Style.textSelectedColor
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
radius: 2
|
|
||||||
border.color: MoneroComponents.Style.inputBorderColorInActive
|
|
||||||
border.width: 1
|
|
||||||
color: MoneroComponents.Style.blackTheme ? "black" : "#A9FFFFFF"
|
|
||||||
|
|
||||||
MoneroComponents.Label {
|
|
||||||
fontSize: 20
|
|
||||||
text: isHidden ? FontAwesome.eye : FontAwesome.eyeSlash
|
|
||||||
opacity: 0.7
|
|
||||||
fontFamily: FontAwesome.fontFamily
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 15
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.verticalCenterOffset: 1
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: {
|
|
||||||
toggleIsHidden()
|
|
||||||
}
|
|
||||||
onEntered: {
|
|
||||||
parent.opacity = 0.9
|
|
||||||
parent.fontSize = 24
|
|
||||||
}
|
|
||||||
onExited: {
|
|
||||||
parent.opacity = 0.7
|
|
||||||
parent.fontSize = 20
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onReturnPressed: {
|
|
||||||
if (passwordInput1.text === passwordInput2.text) {
|
|
||||||
root.close()
|
|
||||||
root.accepted()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Keys.onEscapePressed: {
|
|
||||||
root.close()
|
|
||||||
root.rejected()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// padding
|
|
||||||
Rectangle {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
height: 10
|
|
||||||
opacity: 0
|
|
||||||
color: "black"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ok/Cancel buttons
|
|
||||||
RowLayout {
|
|
||||||
id: buttons
|
|
||||||
spacing: 16
|
|
||||||
Layout.topMargin: 16
|
|
||||||
Layout.alignment: Qt.AlignRight
|
|
||||||
|
|
||||||
MoneroComponents.StandardButton {
|
|
||||||
id: cancelButton
|
|
||||||
text: qsTr("Cancel") + translationManager.emptyString
|
|
||||||
KeyNavigation.tab: passwordInput1
|
|
||||||
onClicked: {
|
|
||||||
root.close()
|
|
||||||
root.rejected()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MoneroComponents.StandardButton {
|
|
||||||
id: okButton
|
|
||||||
text: qsTr("Continue") + translationManager.emptyString
|
|
||||||
KeyNavigation.tab: cancelButton
|
|
||||||
enabled: passwordInput1.text === passwordInput2.text
|
|
||||||
onClicked: {
|
|
||||||
root.close()
|
|
||||||
root.accepted()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,321 +0,0 @@
|
||||||
// Copyright (c) 2014-2019, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
import QtQuick 2.7
|
|
||||||
import QtQuick.Controls 2.0
|
|
||||||
import QtQuick.Dialogs 1.2
|
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
import QtQuick.Controls.Styles 1.4
|
|
||||||
import QtQuick.Window 2.0
|
|
||||||
import FontAwesome 1.0
|
|
||||||
|
|
||||||
import "../components" as MoneroComponents
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
visible: false
|
|
||||||
z: parent.z + 2
|
|
||||||
|
|
||||||
property bool isHidden: true
|
|
||||||
property alias passphrase: passphaseInput1.text
|
|
||||||
property string walletName
|
|
||||||
property string errorText
|
|
||||||
|
|
||||||
// same signals as Dialog has
|
|
||||||
signal accepted()
|
|
||||||
signal rejected()
|
|
||||||
signal closeCallback()
|
|
||||||
|
|
||||||
function open(walletName, errorText) {
|
|
||||||
isHidden = true
|
|
||||||
passphaseInput1.echoMode = TextInput.Password;
|
|
||||||
passphaseInput2.echoMode = TextInput.Password;
|
|
||||||
|
|
||||||
inactiveOverlay.visible = true
|
|
||||||
|
|
||||||
root.walletName = walletName ? walletName : ""
|
|
||||||
root.errorText = errorText ? errorText : "";
|
|
||||||
|
|
||||||
leftPanel.enabled = false
|
|
||||||
middlePanel.enabled = false
|
|
||||||
titleBar.state = "essentials"
|
|
||||||
|
|
||||||
root.visible = true;
|
|
||||||
passphaseInput1.text = "";
|
|
||||||
passphaseInput2.text = "";
|
|
||||||
passphaseInput1.focus = true
|
|
||||||
}
|
|
||||||
|
|
||||||
function close() {
|
|
||||||
inactiveOverlay.visible = false
|
|
||||||
leftPanel.enabled = true
|
|
||||||
middlePanel.enabled = true
|
|
||||||
titleBar.state = "default"
|
|
||||||
root.visible = false;
|
|
||||||
closeCallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleIsHidden() {
|
|
||||||
passphaseInput1.echoMode = isHidden ? TextInput.Normal : TextInput.Password;
|
|
||||||
passphaseInput2.echoMode = isHidden ? TextInput.Normal : TextInput.Password;
|
|
||||||
isHidden = !isHidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
function showError(errorText) {
|
|
||||||
open(root.walletName, errorText);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: implement without hardcoding sizes
|
|
||||||
width: 480
|
|
||||||
height: 360
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
z: inactiveOverlay.z + 1
|
|
||||||
id: mainLayout
|
|
||||||
spacing: 10
|
|
||||||
anchors { fill: parent; margins: 35 }
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: column
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.maximumWidth: 400
|
|
||||||
|
|
||||||
Label {
|
|
||||||
text: (root.walletName.length > 0 ? qsTr("Please enter wallet device passphrase for: ") + root.walletName : qsTr("Please enter wallet device passphrase")) + translationManager.emptyString
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
font.pixelSize: 16
|
|
||||||
font.family: MoneroComponents.Style.fontLight.name
|
|
||||||
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
text: qsTr("Warning: passphrase entry on host is a security risk as it can be captured by malware. It is advised to prefer device-based passphrase entry.") + translationManager.emptyString
|
|
||||||
Layout.fillWidth: true
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
|
|
||||||
font.pixelSize: 14
|
|
||||||
font.family: MoneroComponents.Style.fontLight.name
|
|
||||||
|
|
||||||
color: MoneroComponents.Style.warningColor
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
text: root.errorText
|
|
||||||
visible: root.errorText
|
|
||||||
|
|
||||||
color: MoneroComponents.Style.errorColor
|
|
||||||
font.pixelSize: 16
|
|
||||||
font.family: MoneroComponents.Style.fontLight.name
|
|
||||||
Layout.fillWidth: true
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
}
|
|
||||||
|
|
||||||
TextField {
|
|
||||||
id : passphaseInput1
|
|
||||||
Layout.topMargin: 6
|
|
||||||
Layout.fillWidth: true
|
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
|
||||||
font.family: MoneroComponents.Style.fontLight.name
|
|
||||||
font.pixelSize: 24
|
|
||||||
echoMode: TextInput.Password
|
|
||||||
bottomPadding: 10
|
|
||||||
leftPadding: 10
|
|
||||||
topPadding: 10
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
selectionColor: MoneroComponents.Style.textSelectionColor
|
|
||||||
selectedTextColor: MoneroComponents.Style.textSelectedColor
|
|
||||||
KeyNavigation.tab: passphaseInput2
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
radius: 2
|
|
||||||
border.color: MoneroComponents.Style.inputBorderColorInActive
|
|
||||||
border.width: 1
|
|
||||||
color: MoneroComponents.Style.blackTheme ? "black" : "#A9FFFFFF"
|
|
||||||
|
|
||||||
MoneroComponents.Label {
|
|
||||||
fontSize: 20
|
|
||||||
text: isHidden ? FontAwesome.eye : FontAwesome.eyeSlash
|
|
||||||
opacity: 0.7
|
|
||||||
fontFamily: FontAwesome.fontFamily
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 15
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.verticalCenterOffset: 1
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: {
|
|
||||||
toggleIsHidden()
|
|
||||||
}
|
|
||||||
onEntered: {
|
|
||||||
parent.opacity = 0.9
|
|
||||||
parent.fontSize = 24
|
|
||||||
}
|
|
||||||
onExited: {
|
|
||||||
parent.opacity = 0.7
|
|
||||||
parent.fontSize = 20
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onEscapePressed: {
|
|
||||||
root.close()
|
|
||||||
root.rejected()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// padding
|
|
||||||
Rectangle {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
height: 10
|
|
||||||
opacity: 0
|
|
||||||
color: "transparent"
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
text: qsTr("Please re-enter") + translationManager.emptyString
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
font.pixelSize: 16
|
|
||||||
font.family: MoneroComponents.Style.fontLight.name
|
|
||||||
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
}
|
|
||||||
|
|
||||||
TextField {
|
|
||||||
id : passphaseInput2
|
|
||||||
Layout.topMargin: 6
|
|
||||||
Layout.fillWidth: true
|
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
|
||||||
font.family: MoneroComponents.Style.fontLight.name
|
|
||||||
font.pixelSize: 24
|
|
||||||
echoMode: TextInput.Password
|
|
||||||
KeyNavigation.tab: okButton
|
|
||||||
bottomPadding: 10
|
|
||||||
leftPadding: 10
|
|
||||||
topPadding: 10
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
selectionColor: MoneroComponents.Style.dimmedFontColor
|
|
||||||
selectedTextColor: MoneroComponents.Style.defaultFontColor
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
radius: 2
|
|
||||||
border.color: MoneroComponents.Style.inputBorderColorInActive
|
|
||||||
border.width: 1
|
|
||||||
color: MoneroComponents.Style.blackTheme ? "black" : "#A9FFFFFF"
|
|
||||||
|
|
||||||
MoneroComponents.Label {
|
|
||||||
fontSize: 20
|
|
||||||
text: isHidden ? FontAwesome.eye : FontAwesome.eyeSlash
|
|
||||||
opacity: 0.7
|
|
||||||
fontFamily: FontAwesome.fontFamily
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 15
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.verticalCenterOffset: 1
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: {
|
|
||||||
toggleIsHidden()
|
|
||||||
}
|
|
||||||
onEntered: {
|
|
||||||
parent.opacity = 0.9
|
|
||||||
parent.fontSize = 24
|
|
||||||
}
|
|
||||||
onExited: {
|
|
||||||
parent.opacity = 0.7
|
|
||||||
parent.fontSize = 20
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onReturnPressed: {
|
|
||||||
if (passphaseInput1.text === passphaseInput2.text) {
|
|
||||||
root.close()
|
|
||||||
root.accepted()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Keys.onEscapePressed: {
|
|
||||||
root.close()
|
|
||||||
root.rejected()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// padding
|
|
||||||
Rectangle {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
height: 10
|
|
||||||
opacity: 0
|
|
||||||
color: "black"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ok/Cancel buttons
|
|
||||||
RowLayout {
|
|
||||||
id: buttons
|
|
||||||
spacing: 16
|
|
||||||
Layout.topMargin: 16
|
|
||||||
Layout.alignment: Qt.AlignRight
|
|
||||||
|
|
||||||
MoneroComponents.StandardButton {
|
|
||||||
id: cancelButton
|
|
||||||
text: qsTr("Cancel") + translationManager.emptyString
|
|
||||||
KeyNavigation.tab: passphaseInput1
|
|
||||||
onClicked: {
|
|
||||||
root.close()
|
|
||||||
root.rejected()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MoneroComponents.StandardButton {
|
|
||||||
id: okButton
|
|
||||||
text: qsTr("Continue") + translationManager.emptyString
|
|
||||||
KeyNavigation.tab: cancelButton
|
|
||||||
enabled: passphaseInput1.text === passphaseInput2.text
|
|
||||||
onClicked: {
|
|
||||||
root.close()
|
|
||||||
root.accepted()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -44,34 +44,63 @@ Item {
|
||||||
z: parent.z + 2
|
z: parent.z + 2
|
||||||
|
|
||||||
property bool isHidden: true
|
property bool isHidden: true
|
||||||
property alias password: passwordInput.text
|
property alias password: passwordInput1.text
|
||||||
property string walletName
|
property string walletName
|
||||||
property string errorText
|
property string errorText
|
||||||
property bool shiftIsPressed: false
|
property bool passwordDialogMode
|
||||||
property bool isCapsLocksActive: false
|
property bool passphraseDialogMode
|
||||||
property bool backspaceIsPressed: false
|
property bool newPasswordDialogMode
|
||||||
|
|
||||||
// same signals as Dialog has
|
// same signals as Dialog has
|
||||||
signal accepted()
|
signal accepted()
|
||||||
|
signal acceptedNewPassword()
|
||||||
|
signal acceptedPassphrase()
|
||||||
signal rejected()
|
signal rejected()
|
||||||
|
signal rejectedNewPassword()
|
||||||
|
signal rejectedPassphrase()
|
||||||
signal closeCallback()
|
signal closeCallback()
|
||||||
|
|
||||||
function open(walletName, errorText) {
|
function _openInit(walletName, errorText) {
|
||||||
isHidden = true
|
isHidden = true
|
||||||
passwordInput.echoMode = TextInput.Password
|
capsLockTextLabel.visible = oshelper.isCapsLock();
|
||||||
passwordInput.text = ""
|
passwordInput1.echoMode = TextInput.Password
|
||||||
passwordInput.forceActiveFocus();
|
passwordInput2.echoMode = TextInput.Password
|
||||||
|
passwordInput1.text = ""
|
||||||
|
passwordInput2.text = ""
|
||||||
|
passwordInput1.forceActiveFocus();
|
||||||
inactiveOverlay.visible = true // draw appwindow inactive
|
inactiveOverlay.visible = true // draw appwindow inactive
|
||||||
root.walletName = walletName ? walletName : ""
|
root.walletName = walletName ? walletName : ""
|
||||||
errorTextLabel.text = errorText ? errorText : "";
|
errorTextLabel.text = errorText ? errorText : "";
|
||||||
leftPanel.enabled = false
|
leftPanel.enabled = false
|
||||||
middlePanel.enabled = false
|
middlePanel.enabled = false
|
||||||
|
wizard.enabled = false
|
||||||
titleBar.state = "essentials"
|
titleBar.state = "essentials"
|
||||||
root.visible = true;
|
root.visible = true;
|
||||||
appWindow.hideBalanceForced = true;
|
appWindow.hideBalanceForced = true;
|
||||||
appWindow.updateBalance();
|
appWindow.updateBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function open(walletName, errorText) {
|
||||||
|
passwordDialogMode = true;
|
||||||
|
passphraseDialogMode = false;
|
||||||
|
newPasswordDialogMode = false;
|
||||||
|
_openInit(walletName, errorText);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openPassphraseDialog() {
|
||||||
|
passwordDialogMode = false;
|
||||||
|
passphraseDialogMode = true;
|
||||||
|
newPasswordDialogMode = false;
|
||||||
|
_openInit("", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function openNewPasswordDialog() {
|
||||||
|
passwordDialogMode = false;
|
||||||
|
passphraseDialogMode = false;
|
||||||
|
newPasswordDialogMode = true;
|
||||||
|
_openInit("", "");
|
||||||
|
}
|
||||||
|
|
||||||
function showError(errorText) {
|
function showError(errorText) {
|
||||||
open(root.walletName, errorText);
|
open(root.walletName, errorText);
|
||||||
}
|
}
|
||||||
|
@ -80,6 +109,7 @@ Item {
|
||||||
inactiveOverlay.visible = false
|
inactiveOverlay.visible = false
|
||||||
leftPanel.enabled = true
|
leftPanel.enabled = true
|
||||||
middlePanel.enabled = true
|
middlePanel.enabled = true
|
||||||
|
wizard.enabled = true
|
||||||
titleBar.state = "default"
|
titleBar.state = "default"
|
||||||
|
|
||||||
root.visible = false;
|
root.visible = false;
|
||||||
|
@ -88,6 +118,12 @@ Item {
|
||||||
closeCallback();
|
closeCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleIsHidden() {
|
||||||
|
passwordInput1.echoMode = isHidden ? TextInput.Normal : TextInput.Password;
|
||||||
|
passwordInput2.echoMode = isHidden ? TextInput.Normal : TextInput.Password;
|
||||||
|
isHidden = !isHidden;
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
z: inactiveOverlay.z + 1
|
z: inactiveOverlay.z + 1
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
|
@ -102,7 +138,11 @@ Item {
|
||||||
Layout.maximumWidth: 400
|
Layout.maximumWidth: 400
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: (root.walletName.length > 0 ? qsTr("Please enter wallet password for: ") + root.walletName : qsTr("Please enter wallet password")) + translationManager.emptyString
|
text: {
|
||||||
|
var device = passwordDialogMode ? qsTr("wallet password") : qsTr("wallet device passphrase");
|
||||||
|
(root.walletName.length > 0 ? qsTr("Please enter %1 for: ").arg(device) + root.walletName : qsTr("Please enter %1").arg(device)) + translationManager.emptyString;
|
||||||
|
}
|
||||||
|
visible: !newPasswordDialogMode
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
font.pixelSize: 16
|
font.pixelSize: 16
|
||||||
|
@ -111,19 +151,41 @@ Item {
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Warning: passphrase entry on host is a security risk as it can be captured by malware. It is advised to prefer device-based passphrase entry.") + translationManager.emptyString
|
||||||
|
visible: passphraseDialogMode
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
|
||||||
|
font.pixelSize: 14
|
||||||
|
font.family: MoneroComponents.Style.fontLight.name
|
||||||
|
|
||||||
|
color: MoneroComponents.Style.warningColor
|
||||||
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
id: errorTextLabel
|
id: errorTextLabel
|
||||||
visible: root.errorText || text !== ""
|
visible: root.errorText || text !== ""
|
||||||
|
|
||||||
color: MoneroComponents.Style.errorColor
|
color: MoneroComponents.Style.errorColor
|
||||||
font.pixelSize: 16
|
font.pixelSize: 16
|
||||||
font.family: MoneroComponents.Style.fontLight.name
|
font.family: MoneroComponents.Style.fontLight.name
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: capsLockTextLabel
|
||||||
|
visible: false
|
||||||
|
color: MoneroComponents.Style.errorColor
|
||||||
|
font.pixelSize: 16
|
||||||
|
font.family: MoneroComponents.Style.fontLight.name
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
text: qsTr("CAPSLOCKS IS ON.") + translationManager.emptyString;
|
||||||
|
}
|
||||||
|
|
||||||
TextField {
|
TextField {
|
||||||
id : passwordInput
|
id: passwordInput1
|
||||||
Layout.topMargin: 6
|
Layout.topMargin: 6
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
horizontalAlignment: TextInput.AlignLeft
|
||||||
|
@ -131,24 +193,20 @@ Item {
|
||||||
font.family: MoneroComponents.Style.fontLight.name
|
font.family: MoneroComponents.Style.fontLight.name
|
||||||
font.pixelSize: 24
|
font.pixelSize: 24
|
||||||
echoMode: TextInput.Password
|
echoMode: TextInput.Password
|
||||||
KeyNavigation.tab: okButton
|
KeyNavigation.tab: {
|
||||||
|
if (passwordDialogMode) {
|
||||||
|
return okButton
|
||||||
|
} else {
|
||||||
|
return passwordInput2
|
||||||
|
}
|
||||||
|
}
|
||||||
bottomPadding: 10
|
bottomPadding: 10
|
||||||
leftPadding: 10
|
leftPadding: 10
|
||||||
topPadding: 10
|
topPadding: 10
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
selectionColor: MoneroComponents.Style.textSelectionColor
|
selectionColor: MoneroComponents.Style.textSelectionColor
|
||||||
selectedTextColor: MoneroComponents.Style.textSelectedColor
|
selectedTextColor: MoneroComponents.Style.textSelectedColor
|
||||||
|
onTextChanged: capsLockTextLabel.visible = oshelper.isCapsLock();
|
||||||
onTextChanged: {
|
|
||||||
var letter = text[passwordInput.text.length - 1];
|
|
||||||
isCapsLocksActive = Utils.isUpperLock(shiftIsPressed, letter);
|
|
||||||
if(isCapsLocksActive && !backspaceIsPressed){
|
|
||||||
errorTextLabel.text = qsTr("CAPSLOCKS IS ON.") + translationManager.emptyString;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
errorTextLabel.text = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
radius: 2
|
radius: 2
|
||||||
|
@ -177,8 +235,7 @@ Item {
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onClicked: {
|
onClicked: {
|
||||||
passwordInput.echoMode = isHidden ? TextInput.Normal : TextInput.Password;
|
toggleIsHidden();
|
||||||
isHidden = !isHidden;
|
|
||||||
}
|
}
|
||||||
onEntered: {
|
onEntered: {
|
||||||
parent.opacity = 0.9
|
parent.opacity = 0.9
|
||||||
|
@ -195,28 +252,129 @@ Item {
|
||||||
Keys.enabled: root.visible
|
Keys.enabled: root.visible
|
||||||
Keys.onReturnPressed: {
|
Keys.onReturnPressed: {
|
||||||
root.close()
|
root.close()
|
||||||
root.accepted()
|
if (passwordDialogMode) {
|
||||||
|
root.accepted()
|
||||||
|
} else if (newPasswordDialogMode) {
|
||||||
|
root.acceptedNewPassword()
|
||||||
|
} else if (passphraseDialogMode) {
|
||||||
|
root.acceptedPassphrase()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Keys.onEscapePressed: {
|
Keys.onEscapePressed: {
|
||||||
root.close()
|
root.close()
|
||||||
root.rejected()
|
if (passwordDialogMode) {
|
||||||
}
|
root.rejected()
|
||||||
Keys.onPressed: {
|
} else if (newPasswordDialogMode) {
|
||||||
if(event.key === Qt.Key_Shift){
|
root.rejectedNewPassword()
|
||||||
shiftIsPressed = true;
|
} else if (passphraseDialogMode) {
|
||||||
}
|
root.rejectedPassphrase()
|
||||||
if(event.key === Qt.Key_Backspace){
|
|
||||||
backspaceIsPressed = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Keys.onReleased: {
|
}
|
||||||
if(event.key === Qt.Key_Shift){
|
|
||||||
shiftIsPressed = false;
|
// padding
|
||||||
}
|
Rectangle {
|
||||||
if(event.key === Qt.Key_Backspace){
|
visible: !passwordDialogMode
|
||||||
backspaceIsPressed =false;
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
height: 10
|
||||||
|
opacity: 0
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
visible: !passwordDialogMode
|
||||||
|
text: qsTr("Please confirm new password") + translationManager.emptyString
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
font.pixelSize: 16
|
||||||
|
font.family: MoneroComponents.Style.fontLight.name
|
||||||
|
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: passwordInput2
|
||||||
|
visible: !passwordDialogMode
|
||||||
|
Layout.topMargin: 6
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: TextInput.AlignLeft
|
||||||
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
|
font.family: MoneroComponents.Style.fontLight.name
|
||||||
|
font.pixelSize: 24
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
KeyNavigation.tab: okButton
|
||||||
|
bottomPadding: 10
|
||||||
|
leftPadding: 10
|
||||||
|
topPadding: 10
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
selectionColor: MoneroComponents.Style.textSelectionColor
|
||||||
|
selectedTextColor: MoneroComponents.Style.textSelectedColor
|
||||||
|
onTextChanged: capsLockTextLabel.visible = oshelper.isCapsLock();
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
radius: 2
|
||||||
|
border.color: MoneroComponents.Style.inputBorderColorInActive
|
||||||
|
border.width: 1
|
||||||
|
color: MoneroComponents.Style.blackTheme ? "black" : "#A9FFFFFF"
|
||||||
|
|
||||||
|
MoneroComponents.Label {
|
||||||
|
fontSize: 20
|
||||||
|
text: isHidden ? FontAwesome.eye : FontAwesome.eyeSlash
|
||||||
|
opacity: 0.7
|
||||||
|
fontFamily: FontAwesome.fontFamily
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 15
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.verticalCenterOffset: 1
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: {
|
||||||
|
toggleIsHidden()
|
||||||
|
}
|
||||||
|
onEntered: {
|
||||||
|
parent.opacity = 0.9
|
||||||
|
parent.fontSize = 24
|
||||||
|
}
|
||||||
|
onExited: {
|
||||||
|
parent.opacity = 0.7
|
||||||
|
parent.fontSize = 20
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
if (passwordInput1.text === passwordInput2.text) {
|
||||||
|
root.close()
|
||||||
|
if (newPasswordDialogMode) {
|
||||||
|
root.acceptedNewPassword()
|
||||||
|
} else if (passphraseDialogMode) {
|
||||||
|
root.acceptedPassphrase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Keys.onEscapePressed: {
|
||||||
|
root.close()
|
||||||
|
if (newPasswordDialogMode) {
|
||||||
|
root.rejectedNewPassword()
|
||||||
|
} else if (passphraseDialogMode) {
|
||||||
|
root.rejectedPassphrase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// padding
|
||||||
|
Rectangle {
|
||||||
|
visible: !passwordDialogMode
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
height: 10
|
||||||
|
opacity: 0
|
||||||
|
color: "black"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ok/Cancel buttons
|
// Ok/Cancel buttons
|
||||||
|
@ -230,10 +388,16 @@ Item {
|
||||||
id: cancelButton
|
id: cancelButton
|
||||||
small: true
|
small: true
|
||||||
text: root.walletName.length > 0 ? qsTr("Change wallet") + translationManager.emptyString : qsTr("Cancel") + translationManager.emptyString
|
text: root.walletName.length > 0 ? qsTr("Change wallet") + translationManager.emptyString : qsTr("Cancel") + translationManager.emptyString
|
||||||
KeyNavigation.tab: passwordInput
|
KeyNavigation.tab: passwordInput1
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.close()
|
root.close()
|
||||||
root.rejected()
|
if (passwordDialogMode) {
|
||||||
|
root.rejected()
|
||||||
|
} else if (newPasswordDialogMode) {
|
||||||
|
root.rejectedNewPassword()
|
||||||
|
} else if (passphraseDialogMode) {
|
||||||
|
root.rejectedPassphrase()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,13 +406,19 @@ Item {
|
||||||
small: true
|
small: true
|
||||||
text: qsTr("Continue") + translationManager.emptyString
|
text: qsTr("Continue") + translationManager.emptyString
|
||||||
KeyNavigation.tab: cancelButton
|
KeyNavigation.tab: cancelButton
|
||||||
|
enabled: (passwordDialogMode == true) ? true : passwordInput1.text === passwordInput2.text
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.close()
|
root.close()
|
||||||
root.accepted()
|
if (passwordDialogMode) {
|
||||||
|
root.accepted()
|
||||||
|
} else if (newPasswordDialogMode) {
|
||||||
|
root.acceptedNewPassword()
|
||||||
|
} else if (passphraseDialogMode) {
|
||||||
|
root.acceptedPassphrase()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
19
js/Utils.js
19
js/Utils.js
|
@ -112,25 +112,6 @@ function roundDownToNearestThousand(_num){
|
||||||
return Math.floor(_num/1000.0)*1000
|
return Math.floor(_num/1000.0)*1000
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAlpha(letter){ return letter.match(/^[A-Za-z0-9]+$/) !== null; }
|
|
||||||
|
|
||||||
function isLowerCaseChar(letter){ return letter === letter.toLowerCase(); }
|
|
||||||
|
|
||||||
function isUpperLock(shift, letter){
|
|
||||||
if(!isAlpha((letter))) return false;
|
|
||||||
if(shift) {
|
|
||||||
if(isLowerCaseChar(letter))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
if(isLowerCaseChar(letter))
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function qmlEach(item, properties, ignoredObjectNames, arr){
|
function qmlEach(item, properties, ignoredObjectNames, arr){
|
||||||
// Traverse QML object tree and return components that match
|
// Traverse QML object tree and return components that match
|
||||||
// via property names. Similar to jQuery("myclass").each(...
|
// via property names. Similar to jQuery("myclass").each(...
|
||||||
|
|
49
main.qml
49
main.qml
|
@ -573,15 +573,15 @@ ApplicationWindow {
|
||||||
hideProcessingSplash();
|
hideProcessingSplash();
|
||||||
|
|
||||||
console.log(">>> wallet passphrase needed: ")
|
console.log(">>> wallet passphrase needed: ")
|
||||||
passphraseDialog.onAcceptedCallback = function() {
|
passwordDialog.onAcceptedPassphraseCallback = function() {
|
||||||
walletManager.onPassphraseEntered(passphraseDialog.passphrase);
|
walletManager.onPassphraseEntered(passwordDialog.password);
|
||||||
this.onWalletOpening();
|
this.onWalletOpening();
|
||||||
}
|
}
|
||||||
passphraseDialog.onRejectedCallback = function() {
|
passwordDialog.onRejectedPassphraseCallback = function() {
|
||||||
walletManager.onPassphraseEntered("", true);
|
walletManager.onPassphraseEntered("", true);
|
||||||
this.onWalletOpening();
|
this.onWalletOpening();
|
||||||
}
|
}
|
||||||
passphraseDialog.open()
|
passwordDialog.openPassphraseDialog()
|
||||||
}
|
}
|
||||||
|
|
||||||
function onWalletUpdate() {
|
function onWalletUpdate() {
|
||||||
|
@ -1498,23 +1498,6 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PassphraseDialog {
|
|
||||||
id: passphraseDialog
|
|
||||||
visible: false
|
|
||||||
z: parent.z + 1
|
|
||||||
anchors.fill: parent
|
|
||||||
property var onAcceptedCallback
|
|
||||||
property var onRejectedCallback
|
|
||||||
onAccepted: {
|
|
||||||
if (onAcceptedCallback)
|
|
||||||
onAcceptedCallback();
|
|
||||||
}
|
|
||||||
onRejected: {
|
|
||||||
if (onRejectedCallback)
|
|
||||||
onRejectedCallback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PasswordDialog {
|
PasswordDialog {
|
||||||
id: passwordDialog
|
id: passwordDialog
|
||||||
visible: false
|
visible: false
|
||||||
|
@ -1522,6 +1505,8 @@ ApplicationWindow {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
property var onAcceptedCallback
|
property var onAcceptedCallback
|
||||||
property var onRejectedCallback
|
property var onRejectedCallback
|
||||||
|
property var onAcceptedPassphraseCallback
|
||||||
|
property var onRejectedPassphraseCallback
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
if (onAcceptedCallback)
|
if (onAcceptedCallback)
|
||||||
onAcceptedCallback();
|
onAcceptedCallback();
|
||||||
|
@ -1530,16 +1515,9 @@ ApplicationWindow {
|
||||||
if (onRejectedCallback)
|
if (onRejectedCallback)
|
||||||
onRejectedCallback();
|
onRejectedCallback();
|
||||||
}
|
}
|
||||||
}
|
onAcceptedNewPassword: {
|
||||||
|
if (currentWallet.setPassword(passwordDialog.password)) {
|
||||||
NewPasswordDialog {
|
appWindow.walletPassword = passwordDialog.password;
|
||||||
id: newPasswordDialog
|
|
||||||
z: parent.z + 1
|
|
||||||
visible:false
|
|
||||||
anchors.fill: parent
|
|
||||||
onAccepted: {
|
|
||||||
if (currentWallet.setPassword(newPasswordDialog.password)) {
|
|
||||||
appWindow.walletPassword = newPasswordDialog.password;
|
|
||||||
informationPopup.title = qsTr("Information") + translationManager.emptyString;
|
informationPopup.title = qsTr("Information") + translationManager.emptyString;
|
||||||
informationPopup.text = qsTr("Password changed successfully") + translationManager.emptyString;
|
informationPopup.text = qsTr("Password changed successfully") + translationManager.emptyString;
|
||||||
informationPopup.icon = StandardIcon.Information;
|
informationPopup.icon = StandardIcon.Information;
|
||||||
|
@ -1551,7 +1529,14 @@ ApplicationWindow {
|
||||||
informationPopup.onCloseCallback = null;
|
informationPopup.onCloseCallback = null;
|
||||||
informationPopup.open();
|
informationPopup.open();
|
||||||
}
|
}
|
||||||
onRejected: {
|
onRejectedNewPassword: {}
|
||||||
|
onAcceptedPassphrase: {
|
||||||
|
if (onAcceptedPassphraseCallback)
|
||||||
|
onAcceptedPassphraseCallback();
|
||||||
|
}
|
||||||
|
onRejectedPassphrase: {
|
||||||
|
if (onRejectedPassphraseCallback)
|
||||||
|
onRejectedPassphraseCallback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,8 @@ HEADERS += \
|
||||||
src/qt/mime.h \
|
src/qt/mime.h \
|
||||||
src/qt/KeysFiles.h \
|
src/qt/KeysFiles.h \
|
||||||
src/qt/utils.h \
|
src/qt/utils.h \
|
||||||
src/qt/prices.h
|
src/qt/prices.h \
|
||||||
|
src/qt/macoshelper.h
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
SOURCES += main.cpp \
|
||||||
filter.cpp \
|
filter.cpp \
|
||||||
|
@ -334,7 +335,8 @@ linux {
|
||||||
-llmdb \
|
-llmdb \
|
||||||
-lsodium \
|
-lsodium \
|
||||||
-lhidapi-libusb \
|
-lhidapi-libusb \
|
||||||
-lcrypto $$TREZOR_LINKER
|
-lcrypto $$TREZOR_LINKER \
|
||||||
|
-lX11
|
||||||
|
|
||||||
if(!android) {
|
if(!android) {
|
||||||
LIBS+= \
|
LIBS+= \
|
||||||
|
@ -359,6 +361,8 @@ macx {
|
||||||
# message("using static libraries")
|
# message("using static libraries")
|
||||||
# LIBS+= -Wl,-Bstatic
|
# LIBS+= -Wl,-Bstatic
|
||||||
# }
|
# }
|
||||||
|
QT += macextras
|
||||||
|
OBJECTIVE_SOURCES += src/qt/macoshelper.mm
|
||||||
LIBS+= \
|
LIBS+= \
|
||||||
-L/usr/local/lib \
|
-L/usr/local/lib \
|
||||||
-L/usr/local/opt/openssl/lib \
|
-L/usr/local/opt/openssl/lib \
|
||||||
|
@ -372,6 +376,7 @@ macx {
|
||||||
-lboost_chrono \
|
-lboost_chrono \
|
||||||
-lboost_program_options \
|
-lboost_program_options \
|
||||||
-framework CoreFoundation \
|
-framework CoreFoundation \
|
||||||
|
-framework AppKit \
|
||||||
-lhidapi \
|
-lhidapi \
|
||||||
-lssl \
|
-lssl \
|
||||||
-lsodium \
|
-lsodium \
|
||||||
|
|
35
oshelper.cpp
35
oshelper.cpp
|
@ -31,6 +31,20 @@
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
#include "qt/macoshelper.h"
|
||||||
|
#endif
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
|
#undef KeyPress
|
||||||
|
#undef KeyRelease
|
||||||
|
#undef FocusIn
|
||||||
|
#undef FocusOut
|
||||||
|
// #undef those Xlib #defines that conflict with QEvent::Type enum
|
||||||
|
#endif
|
||||||
|
|
||||||
OSHelper::OSHelper(QObject *parent) : QObject(parent)
|
OSHelper::OSHelper(QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
|
@ -58,6 +72,27 @@ bool OSHelper::removeTemporaryWallet(const QString &fileName) const
|
||||||
return cache_deleted && address_deleted && keys_deleted;
|
return cache_deleted && address_deleted && keys_deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/a/3006934
|
||||||
|
bool OSHelper::isCapsLock() const
|
||||||
|
{
|
||||||
|
// platform dependent method of determining if CAPS LOCK is on
|
||||||
|
#if defined(Q_OS_WIN32) // MS Windows version
|
||||||
|
return GetKeyState(VK_CAPITAL) == 1;
|
||||||
|
#elif defined(Q_OS_LINUX) // X11 version
|
||||||
|
Display * d = XOpenDisplay((char*)0);
|
||||||
|
bool caps_state = false;
|
||||||
|
if (d) {
|
||||||
|
unsigned n;
|
||||||
|
XkbGetIndicatorState(d, XkbUseCoreKbd, &n);
|
||||||
|
caps_state = (n & 0x01) == 1;
|
||||||
|
}
|
||||||
|
return caps_state;
|
||||||
|
#elif defined(Q_OS_MAC)
|
||||||
|
return MacOSHelper::isCapsLock();
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QString OSHelper::temporaryPath() const
|
QString OSHelper::temporaryPath() const
|
||||||
{
|
{
|
||||||
return QDir::tempPath();
|
return QDir::tempPath();
|
||||||
|
|
|
@ -42,6 +42,7 @@ public:
|
||||||
Q_INVOKABLE QString temporaryFilename() const;
|
Q_INVOKABLE QString temporaryFilename() const;
|
||||||
Q_INVOKABLE QString temporaryPath() const;
|
Q_INVOKABLE QString temporaryPath() const;
|
||||||
Q_INVOKABLE bool removeTemporaryWallet(const QString &walletName) const;
|
Q_INVOKABLE bool removeTemporaryWallet(const QString &walletName) const;
|
||||||
|
Q_INVOKABLE bool isCapsLock() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
|
|
@ -339,7 +339,7 @@ Rectangle {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
passwordDialog.onAcceptedCallback = function() {
|
passwordDialog.onAcceptedCallback = function() {
|
||||||
if(appWindow.walletPassword === passwordDialog.password){
|
if(appWindow.walletPassword === passwordDialog.password){
|
||||||
newPasswordDialog.open()
|
passwordDialog.openNewPasswordDialog()
|
||||||
} else {
|
} else {
|
||||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||||
informationPopup.text = qsTr("Wrong password") + translationManager.emptyString;
|
informationPopup.text = qsTr("Wrong password") + translationManager.emptyString;
|
||||||
|
|
2
qml.qrc
2
qml.qrc
|
@ -96,9 +96,7 @@
|
||||||
<file>pages/SharedRingDB.qml</file>
|
<file>pages/SharedRingDB.qml</file>
|
||||||
<file>components/effects/ImageMask.qml</file>
|
<file>components/effects/ImageMask.qml</file>
|
||||||
<file>components/IconButton.qml</file>
|
<file>components/IconButton.qml</file>
|
||||||
<file>components/PassphraseDialog.qml</file>
|
|
||||||
<file>components/PasswordDialog.qml</file>
|
<file>components/PasswordDialog.qml</file>
|
||||||
<file>components/NewPasswordDialog.qml</file>
|
|
||||||
<file>components/InputDialog.qml</file>
|
<file>components/InputDialog.qml</file>
|
||||||
<file>components/ProcessingSplash.qml</file>
|
<file>components/ProcessingSplash.qml</file>
|
||||||
<file>components/ProgressBar.qml</file>
|
<file>components/ProgressBar.qml</file>
|
||||||
|
|
40
src/qt/macoshelper.h
Normal file
40
src/qt/macoshelper.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef MACOSHELPER_H
|
||||||
|
#define MACOSHELPER_H
|
||||||
|
|
||||||
|
class MacOSHelper
|
||||||
|
{
|
||||||
|
MacOSHelper() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static bool isCapsLock();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //MACOSHELPER_H
|
49
src/qt/macoshelper.mm
Normal file
49
src/qt/macoshelper.mm
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include <QtCore>
|
||||||
|
#include <QtGui>
|
||||||
|
#include <QtMac>
|
||||||
|
#include "macoshelper.h"
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
#include <Availability.h>
|
||||||
|
|
||||||
|
bool MacOSHelper::isCapsLock()
|
||||||
|
{
|
||||||
|
#ifdef __MAC_10_12
|
||||||
|
NSUInteger flags = [NSEvent modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
|
||||||
|
return (flags == NSEventModifierFlagCapsLock);
|
||||||
|
#else
|
||||||
|
NSUInteger flags = [NSEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask;
|
||||||
|
return (flags & NSAlphaShiftKeyMask);
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -498,15 +498,15 @@ Rectangle {
|
||||||
splash.close()
|
splash.close()
|
||||||
|
|
||||||
console.log(">>> wallet passphrase needed: ");
|
console.log(">>> wallet passphrase needed: ");
|
||||||
passphraseDialog.onAcceptedCallback = function() {
|
passwordDialog.onAcceptedPassphraseCallback = function() {
|
||||||
walletManager.onPassphraseEntered(passphraseDialog.passphrase);
|
walletManager.onPassphraseEntered(passwordDialog.password);
|
||||||
creatingWalletDeviceSplash();
|
creatingWalletDeviceSplash();
|
||||||
}
|
}
|
||||||
passphraseDialog.onRejectedCallback = function() {
|
passwordDialog.onRejectedPassphraseCallback = function() {
|
||||||
walletManager.onPassphraseEntered("", true);
|
walletManager.onPassphraseEntered("", true);
|
||||||
creatingWalletDeviceSplash();
|
creatingWalletDeviceSplash();
|
||||||
}
|
}
|
||||||
passphraseDialog.open()
|
passwordDialog.openPassphraseDialog()
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDeviceButtonRequest(code){
|
function onDeviceButtonRequest(code){
|
||||||
|
|
Loading…
Reference in a new issue