diff --git a/LeftPanel.qml b/LeftPanel.qml index 79206fb4..3136a5c2 100644 --- a/LeftPanel.qml +++ b/LeftPanel.qml @@ -27,6 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.2 +import QtQuick.Layouts 1.1 import QtGraphicalEffects 1.0 import moneroComponents.Wallet 1.0 import moneroComponents.NetworkType 1.0 @@ -36,12 +37,15 @@ Rectangle { id: panel property alias unlockedBalanceText: unlockedBalanceText.text + property alias unlockedBalanceVisible: unlockedBalanceText.visible + property alias unlockedBalanceLabelVisible: unlockedBalanceLabel.visible property alias balanceLabelText: balanceLabel.text property alias balanceText: balanceText.text property alias networkStatus : networkStatus property alias progressBar : progressBar property alias daemonProgressBar : daemonProgressBar property alias minutesToUnlockTxt: unlockedBalanceLabel.text + property int titleBarHeight: 50 signal dashboardClicked() signal historyClicked() @@ -72,178 +76,178 @@ Rectangle { menuColumn.previousButton.checked = true } - width: (isMobile)? appWindow.width : 260 - color: "#FFFFFF" + width: (isMobile)? appWindow.width : 300 + color: "transparent" anchors.bottom: parent.bottom anchors.top: parent.top - // Item with monero logo - Item { - visible: !isMobile - id: logoItem + Image { anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top - anchors.topMargin: (persistentSettings.customDecorations)? 66 : 36 - height: logo.implicitHeight - - Image { - id: logo - anchors.left: parent.left - anchors.leftMargin: 50 - source: "images/moneroLogo.png" - } - - Text { - id: viewOnlyLabel - visible: viewOnly - text: qsTr("View Only") + translationManager.emptyString - anchors.top: logo.bottom - anchors.topMargin: 5 - anchors.left: parent.left - anchors.leftMargin: 50 - font.bold: true - color: "blue" - } - - Text { - id: testnetLabel - visible: persistentSettings.nettype !== NetworkType.MAINNET - text: (persistentSettings.nettype === NetworkType.TESTNET ? qsTr("Testnet") : qsTr("Stagenet")) + translationManager.emptyString - anchors.top: logo.bottom - anchors.topMargin: 5 - anchors.left: viewOnly ? viewOnlyLabel.right : parent.left - anchors.leftMargin: viewOnly ? 10 : 50 - font.bold: true - color: "red" - } - - /* Disable twitter/news panel - Image { - anchors.left: parent.left - anchors.verticalCenter: logo.verticalCenter - anchors.leftMargin: 19 - source: appWindow.rightPanelExpanded ? "images/expandRightPanel.png" : - "images/collapseRightPanel.png" - } - - MouseArea { - anchors.fill: parent - onClicked: appWindow.rightPanelExpanded = !appWindow.rightPanelExpanded - } - */ + height: panel.height + source: "images/leftPanelBg.jpg" + z: 1 } - - + // card with monero logo Column { - visible: !isMobile + visible: true + z: 2 id: column1 + height: 200 anchors.left: parent.left anchors.right: parent.right - anchors.top: logoItem.bottom - anchors.topMargin: 26 - spacing: 5 + anchors.top: parent.top + anchors.topMargin: (persistentSettings.customDecorations)? 50 : 0 - Label { - visible: !isMobile - id: balanceLabel - text: qsTr("Balance") + translationManager.emptyString - anchors.left: parent.left - anchors.leftMargin: 50 - } - - Row { - visible: !isMobile + RowLayout { + visible: true Item { + anchors.left: parent.left + anchors.top: parent.top + anchors.topMargin: 20 + anchors.leftMargin: 20 anchors.verticalCenter: parent.verticalCenter - height: 26 * scaleRatio - width: 50 * scaleRatio + height: 490 * scaleRatio + width: 259 * scaleRatio Image { - anchors.centerIn: parent - source: "images/lockIcon.png" + width: 259; height: 170 + fillMode: Image.PreserveAspectFit + source: "images/card-background.png" + } + + Text { + id: testnetLabel + visible: persistentSettings.nettype != NetworkType.MAINNET + text: (persistentSettings.nettype == NetworkType.TESTNET ? qsTr("Testnet") : qsTr("Stagenet")) + translationManager.emptyString + anchors.top: parent.top + anchors.topMargin: 8 + anchors.left: parent.left + anchors.leftMargin: 192 + font.bold: true + font.pixelSize: 12 + color: "#f33434" + } + + Text { + id: viewOnlyLabel + visible: viewOnly + text: qsTr("View Only") + translationManager.emptyString + anchors.top: parent.top + anchors.topMargin: 8 + anchors.right: testnetLabel.visible ? testnetLabel.left : parent.right + anchors.rightMargin: 8 + font.pixelSize: 12 + font.bold: true + color: "#ff9323" } } - Text { - visible: !isMobile - id: balanceText + Item { + anchors.left: parent.left + anchors.top: parent.top + anchors.topMargin: 20 + anchors.leftMargin: 20 anchors.verticalCenter: parent.verticalCenter - font.family: "Arial" - color: "#000000" - text: "N/A" - // dynamically adjust text size - font.pixelSize: { - var digits = text.split('.')[0].length - var defaultSize = 25; - if(digits > 2) { - return defaultSize - 1.1*digits + height: 490 * scaleRatio + width: 50 * scaleRatio + + Text { + visible: !isMobile + id: balanceText + anchors.left: parent.left + anchors.leftMargin: 20 + anchors.top: parent.top + anchors.topMargin: 76 + font.family: "Arial" + color: "#FFFFFF" + text: "N/A" + // dynamically adjust text size + font.pixelSize: { + var digits = text.split('.')[0].length + var defaultSize = 22; + if(digits > 2) { + return defaultSize - 1.1*digits + } + return defaultSize; } - return defaultSize; } - } - } - Item { //separator - anchors.left: parent.left - anchors.right: parent.right - height: 1 - } - - Label { - id: unlockedBalanceLabel - text: qsTr("Unlocked balance") + translationManager.emptyString - anchors.left: parent.left - anchors.leftMargin: 50 - } - - Text { - id: unlockedBalanceText - anchors.left: parent.left - anchors.leftMargin: 50 - font.family: "Arial" - color: "#000000" - text: "N/A" - // dynamically adjust text size - font.pixelSize: { - var digits = text.split('.')[0].length - var defaultSize = 18; - if(digits > 3) { - return defaultSize - 0.6*digits + Text { + id: unlockedBalanceText + visible: false + anchors.left: parent.left + anchors.leftMargin: 20 + anchors.top: parent.top + anchors.topMargin: 126 + font.family: "Arial" + color: "#FFFFFF" + text: "N/A" + // dynamically adjust text size + font.pixelSize: { + var digits = text.split('.')[0].length + var defaultSize = 20; + if(digits > 3) { + return defaultSize - 0.6*digits + } + return defaultSize; + } } - return defaultSize; + + Label { + id: unlockedBalanceLabel + visible: false + text: qsTr("Unlocked balance") + translationManager.emptyString + anchors.left: parent.left + anchors.leftMargin: 20 + anchors.top: parent.top + anchors.topMargin: 110 + } + + Label { + visible: !isMobile + id: balanceLabel + text: qsTr("Balance") + translationManager.emptyString + fontSize: 14 + anchors.left: parent.left + anchors.leftMargin: 20 + anchors.top: parent.top + anchors.topMargin: 60 + } + Item { //separator + anchors.left: parent.left + anchors.right: parent.right + height: 1 + } + /* Disable twitter/news panel + Image { + anchors.left: parent.left + anchors.verticalCenter: logo.verticalCenter + anchors.leftMargin: 19 + source: appWindow.rightPanelExpanded ? "images/expandRightPanel.png" : + "images/collapseRightPanel.png" + } + + MouseArea { + anchors.fill: parent + onClicked: appWindow.rightPanelExpanded = !appWindow.rightPanelExpanded + } + */ } } } - - Rectangle { - anchors.top: parent.top - anchors.left: parent.left - anchors.bottom: menuRect.top - width: 1 - color: "#DBDBDB" - } - - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: 1 - color: "#DBDBDB" - } - - - Rectangle { id: menuRect + z: 2 anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom anchors.top: (isMobile)? parent.top : column1.bottom - anchors.topMargin: (isMobile)? 0 : 25 - color: "#1C1C1C" + anchors.topMargin: (isMobile)? 0 : 32 + color: "transparent" Flickable { @@ -285,11 +289,19 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 16 - color: dashboardButton.checked || transferButton.checked ? "#1C1C1C" : "#505050" + color: dashboardButton.checked || transferButton.checked ? "#1C1C1C" : "#313131" height: 1 } */ + // top border + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 16 + color: "#313131" + height: 1 + } // ------------- Transfer tab --------------- MenuButton { @@ -311,7 +323,7 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 16 - color: "#505050" + color: "#313131" height: 1 } @@ -337,7 +349,7 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 16 - color: "#505050" + color: "#313131" height: 1 } @@ -360,7 +372,7 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 16 - color: "#505050" + color: "#313131" height: 1 } @@ -384,7 +396,7 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 16 - color: "#505050" + color: "#313131" height: 1 } @@ -406,7 +418,7 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 16 - color: "#505050" + color: "#313131" height: 1 } @@ -432,7 +444,7 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 16 - color: miningButton.checked || settingsButton.checked ? "#1C1C1C" : "#505050" + color: miningButton.checked || settingsButton.checked ? "#1C1C1C" : "#313131" height: 1 } // ------------- TxKey tab --------------- @@ -455,7 +467,7 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 16 - color: "#505050" + color: "#313131" height: 1 } // ------------- Shared RingDB tab --------------- @@ -478,7 +490,7 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 16 - color: "#505050" + color: "#313131" height: 1 } @@ -503,7 +515,7 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 16 - color: "#505050" + color: "#313131" height: 1 } // ------------- Settings tab --------------- @@ -525,7 +537,7 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 16 - color: "#505050" + color: "#313131" height: 1 } // ------------- Sign/verify tab --------------- @@ -548,7 +560,7 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 16 - color: "#505050" + color: "#313131" height: 1 } @@ -560,6 +572,8 @@ Rectangle { id: networkStatus anchors.left: parent.left anchors.right: parent.right + anchors.leftMargin: 4 + anchors.rightMargin: 4 anchors.bottom: (progressBar.visible)? progressBar.top : parent.bottom; connected: Wallet.ConnectionStatus_Disconnected height: 58 * scaleRatio @@ -580,9 +594,9 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom - height: 35 * scaleRatio syncType: qsTr("Daemon") visible: networkStatus.connected + height: 62 * scaleRatio } } // menuRect diff --git a/MiddlePanel.qml b/MiddlePanel.qml index 38c9bb2c..680372c0 100644 --- a/MiddlePanel.qml +++ b/MiddlePanel.qml @@ -49,6 +49,7 @@ Rectangle { property string unlockedBalanceLabelText: qsTr("Unlocked Balance") + translationManager.emptyString property string unlockedBalanceText property int minHeight: (appWindow.height > 800) ? appWindow.height : 800 * scaleRatio + property alias contentHeight: mainFlickable.contentHeight // property int headerHeight: header.height property Transfer transferView: Transfer { } @@ -69,7 +70,13 @@ Rectangle { signal getProofClicked(string txid, string address, string message); signal checkProofClicked(string txid, string address, string message, string signature); - color: "#F0EEEE" + Image { + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + source: "../images/middlePanelBg.jpg" + } onCurrentViewChanged: { if (previousView) { @@ -105,7 +112,7 @@ Rectangle { name: "History" PropertyChanges { target: root; currentView: historyView } PropertyChanges { target: historyView; model: appWindow.currentWallet ? appWindow.currentWallet.historyModel : null } - PropertyChanges { target: mainFlickable; contentHeight: minHeight } + PropertyChanges { target: mainFlickable; contentHeight: historyView.tableHeight + 220 * scaleRatio } }, State { name: "Transfer" PropertyChanges { target: root; currentView: transferView } @@ -117,7 +124,7 @@ Rectangle { }, State { name: "TxKey" PropertyChanges { target: root; currentView: txkeyView } - PropertyChanges { target: mainFlickable; contentHeight: minHeight } + PropertyChanges { target: mainFlickable; contentHeight: 1200 * scaleRatio } }, State { name: "SharedRingDB" PropertyChanges { target: root; currentView: sharedringdbView } @@ -129,11 +136,11 @@ Rectangle { }, State { name: "Sign" PropertyChanges { target: root; currentView: signView } - PropertyChanges { target: mainFlickable; contentHeight: minHeight } + PropertyChanges { target: mainFlickable; contentHeight: 1200 * scaleRatio } }, State { name: "Settings" PropertyChanges { target: root; currentView: settingsView } - PropertyChanges { target: mainFlickable; contentHeight: 1200 * scaleRatio } + PropertyChanges { target: mainFlickable; contentHeight: 1400 * scaleRatio } }, State { name: "Mining" PropertyChanges { target: root; currentView: miningView } @@ -163,8 +170,8 @@ Rectangle { ColumnLayout { anchors.fill: parent - anchors.margins: 2 - anchors.topMargin: appWindow.persistentSettings.customDecorations ? 30 : 0 + anchors.margins: 18 + anchors.topMargin: appWindow.persistentSettings.customDecorations ? 50 : 0 spacing: 0 Flickable { @@ -212,30 +219,14 @@ Rectangle { }// flickable } + // border - Rectangle { - anchors.top: styledRow.bottom - anchors.bottom: parent.bottom - anchors.right: parent.right - width: 1 - color: "#DBDBDB" - } - Rectangle { anchors.top: styledRow.bottom anchors.bottom: parent.bottom anchors.left: parent.left width: 1 - color: "#DBDBDB" - } - - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: 1 - color: "#DBDBDB" - + color: "#313131" } /* connect "payment" click */ diff --git a/components/AddressBookTable.qml b/components/AddressBookTable.qml index e542900c..cae68d2f 100644 --- a/components/AddressBookTable.qml +++ b/components/AddressBookTable.qml @@ -37,13 +37,13 @@ ListView { footer: Rectangle { height: 127 width: listView.width - color: "#FFFFFF" + color: "transparent" Text { anchors.centerIn: parent font.family: "Arial" font.pixelSize: 14 - color: "#545454" + color: "#808080" text: qsTr("No more results") + translationManager.emptyString } } @@ -53,7 +53,7 @@ ListView { id: delegate height: 64 width: listView.width - color: index % 2 ? "#F8F8F8" : "#FFFFFF" + color: "transparent" z: listView.count - index function collapseDropdown() { dropdown.expanded = false } @@ -62,11 +62,11 @@ ListView { anchors.left: parent.left anchors.top: parent.top anchors.topMargin: 12 - width: text.length ? (descriptionArea.containsMouse ? dropdown.x - x - 12 : 139) : 0 + width: text.length ? (descriptionArea.containsMouse ? 139 : 139) : 0 font.family: "Arial" font.bold: true font.pixelSize: 19 - color: "#444444" + color: "#ffffff" elide: Text.ElideRight text: description @@ -87,8 +87,9 @@ ListView { anchors.rightMargin: 40 font.family: "Arial" font.pixelSize: 16 - color: "#545454" + color: "#ffffff" text: address + readOnly: true } Text { @@ -100,7 +101,7 @@ ListView { width: 139 font.family: "Arial" font.pixelSize: 12 - color: "#535353" + color: "#ffffff" text: qsTr("Payment ID:") + translationManager.emptyString } @@ -111,7 +112,7 @@ ListView { anchors.leftMargin: 12 anchors.rightMargin: 12 anchors.right: dropdown.left - + readOnly: true font.family: "Arial" font.pixelSize: 13 @@ -164,7 +165,7 @@ ListView { anchors.right: parent.right anchors.bottom: parent.bottom height: 1 - color: "#DBDBDB" + color: "#404040" } } } diff --git a/components/CheckBox.qml b/components/CheckBox.qml index 0ae8cb04..517917a3 100644 --- a/components/CheckBox.qml +++ b/components/CheckBox.qml @@ -28,11 +28,12 @@ import QtQuick 2.0 import QtQuick.Layouts 1.1 +import "." 1.0 RowLayout { id: checkBox property alias text: label.text - property string checkedIcon + property string checkedIcon: "../images/checkedIcon-black.png" property string uncheckedIcon property bool checked: false property alias background: backgroundRect.color @@ -52,9 +53,10 @@ RowLayout { anchors.left: parent.left width: 25 * scaleRatio height: checkBox.height - 1 - //radius: 4 + radius: 3 y: 0 - color: "#DBDBDB" + color: "transparent" + border.color: checkBox.checked ? Qt.rgba(1, 1, 1, 0.35) : Qt.rgba(1, 1, 1, 0.25) } Rectangle { @@ -64,16 +66,17 @@ RowLayout { height: checkBox.height - 1 //radius: 4 y: 1 - color: "#FFFFFF" + color: "transparent" Image { anchors.centerIn: parent - source: checkBox.checked ? checkBox.checkedIcon : - checkBox.uncheckedIcon + source: checkBox.checkedIcon + visible: checkBox.checked } MouseArea { anchors.fill: parent + cursorShape: Qt.PointingHandCursor onClicked: { toggle() } @@ -82,13 +85,16 @@ RowLayout { Text { id: label - font.family: "Arial" + font.family: Style.fontRegular.name font.pixelSize: checkBox.fontSize - color: "#525252" + color: Style.defaultFontColor wrapMode: Text.Wrap Layout.fillWidth: true + anchors.left: backgroundRect.right + anchors.leftMargin: !isMobile ? 10 : 8 MouseArea { anchors.fill: parent + cursorShape: Qt.PointingHandCursor onClicked: { toggle() } diff --git a/components/CheckBox2.qml b/components/CheckBox2.qml new file mode 100644 index 00000000..367037c2 --- /dev/null +++ b/components/CheckBox2.qml @@ -0,0 +1,98 @@ +// Copyright (c) 2014-2015, 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.0 +import QtQuick.Layouts 1.1 +import "." 1.0 + +RowLayout { + id: checkBox + property alias text: label.text + property string checkedIcon: "../images/checkedIcon-black.png" + property string uncheckedIcon + property bool checked: false + property string background: "backgroundRect.color" + property int fontSize: 14 * scaleRatio + property alias fontColor: label.color + property int textMargin: 8 * scaleRatio + signal clicked() + height: 25 * scaleRatio + + function toggle(){ + checkBox.checked = !checkBox.checked + checkBox.clicked() + } + + RowLayout { + Layout.fillWidth: true + + Rectangle{ + height: label.height + width: (label.width + indicatorRect.width + checkBox.textMargin) + color: "transparent" + anchors.left: parent.left + + Text { + id: label + font.family: Style.fontLight.name + font.pixelSize: checkBox.fontSize + color: Style.defaultFontColor + wrapMode: Text.Wrap + Layout.fillWidth: true + anchors.left: parent.left + } + + Rectangle { + id: indicatorRect + width: indicatorImage.width + height: label.height + anchors.left: label.right + anchors.leftMargin: textMargin + color: "transparent" + + Image { + id: indicatorImage + anchors.centerIn: parent + source: "../images/whiteDropIndicator.png" + rotation: checkBox.checked ? 180 * scaleRatio : 0 + } + } + + MouseArea{ + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + toggle(); + } + } + } + + + } +} diff --git a/components/DaemonConsole.qml b/components/DaemonConsole.qml index 8bcd8a23..2643a339 100644 --- a/components/DaemonConsole.qml +++ b/components/DaemonConsole.qml @@ -110,10 +110,6 @@ Window { id: okButton width: 120 fontSize: 14 - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" text: qsTr("Close") + translationManager.emptyString onClicked: { root.close() @@ -138,10 +134,6 @@ Window { // id: sendCommandButton // enabled: sendCommandText.text.length > 0 // fontSize: 14 -// shadowReleasedColor: "#FF4304" -// shadowPressedColor: "#B32D00" -// releasedColor: "#FF6C3C" -// pressedColor: "#FF4304" // text: qsTr("Send command") // onClicked: { // daemonManager.sendCommand(sendCommandText.text,currentWallet.testnet); diff --git a/components/DaemonManagerDialog.qml b/components/DaemonManagerDialog.qml index d760c317..07dec4a0 100644 --- a/components/DaemonManagerDialog.qml +++ b/components/DaemonManagerDialog.qml @@ -108,10 +108,6 @@ Window { id: okButton visible:false fontSize: 14 - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" text: qsTr("Start daemon (%1)").arg(countDown) KeyNavigation.tab: cancelButton onClicked: { @@ -125,10 +121,6 @@ Window { MoneroComponents.StandardButton { id: cancelButton fontSize: 14 - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" text: qsTr("Use custom settings") onClicked: { diff --git a/components/DatePicker.qml b/components/DatePicker.qml index dafba285..5d3c44bd 100644 --- a/components/DatePicker.qml +++ b/components/DatePicker.qml @@ -29,18 +29,23 @@ import QtQuick 2.2 import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 +import "../components" +import "." 1.0 + Item { id: datePicker property bool expanded: false property date currentDate property bool showCurrentDate: true - property color backgroundColor : "#FFFFFF" - property color errorColor : "#FFDDDD" + property color backgroundColor : "#404040" + property color errorColor : "red" property bool error: false + property alias inputLabel: inputLabel - height: 37 - width: 156 + signal dateChanged(); + + height: 50 onExpandedChanged: if(expanded) appWindow.currentItem = datePicker @@ -57,28 +62,49 @@ Item { return true } + Rectangle { + id: inputLabelRect + color: "transparent" + height: 22 + width: parent.width + + Text { + id: inputLabel + anchors.top: parent.top + anchors.topMargin: 2 + anchors.left: parent.left + font.family: Style.fontLight.name + font.pixelSize: 14 + font.bold: false + textFormat: Text.RichText + color: Style.defaultFontColor + + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.NoButton + cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor + } + } + } + Item { id: head - anchors.fill: parent - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - height: parent.height - //radius: 4 - y: 0 - color: "#DBDBDB" - - } + anchors.top: inputLabelRect.bottom + anchors.topMargin: 6 * scaleRatio + anchors.left: parent.left + anchors.right: parent.right + height: 28 Rectangle { + anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right height: parent.height - 1 anchors.leftMargin: datePicker.expanded ? 1 : 0 anchors.rightMargin: datePicker.expanded ? 1 : 0 - //radius: 4 + radius: 4 y: 1 - color: datePicker.error ? datePicker.errorColor : datePicker.backgroundColor + color: datePicker.backgroundColor } Item { @@ -89,28 +115,18 @@ Item { anchors.margins: 4 width: height - StandardButton { - id: button - anchors.fill: parent - shadowReleasedColor: "#DBDBDB" - shadowPressedColor: "#888888" - releasedColor: "#F0EEEE" - pressedColor: "#DBDBDB" - icon: "../images/datePicker.png" - visible: !datePicker.expanded - onClicked: datePicker.expanded = true - } - Image { + id: button anchors.centerIn: parent - source: "../images/datePicker.png" - visible: datePicker.expanded + source: "../images/whiteDropIndicator.png" + rotation: datePicker.expanded ? 180 : 0 } MouseArea { anchors.fill: parent - enabled: datePicker.expanded - onClicked: datePicker.expanded = false + onClicked: datePicker.expanded = !datePicker.expanded + hoverEnabled: true + cursorShape: Qt.PointingHandCursor } } @@ -121,7 +137,7 @@ Item { anchors.rightMargin: 4 height: 16 width: 1 - color: "#DBDBDB" + color: "#808080" visible: datePicker.expanded } @@ -150,9 +166,9 @@ Item { id: dayInput readOnly: true width: 22 - font.family: "Arial" - font.pixelSize: 18 - // color: "#525252" + font.family: Style.fontRegular.name + font.pixelSize: 14 + color: datePicker.error ? errorColor : Style.defaultFontColor maximumLength: 2 horizontalAlignment: TextInput.AlignHCenter validator: IntValidator{bottom: 01; top: 31;} @@ -173,19 +189,19 @@ Item { } Text { - font.family: "Arial" - font.pixelSize: 18 - // color: "#525252" - text: "." + font.family: Style.fontRegular.name + font.pixelSize: 14 + color: datePicker.error ? errorColor : Style.defaultFontColor + text: "-" } TextInput { id: monthInput readOnly: true width: 22 - font.family: "Arial" - font.pixelSize: 18 - // color: "#525252" + font.family: Style.fontRegular.name + font.pixelSize: 14 + color: datePicker.error ? errorColor : Style.defaultFontColor maximumLength: 2 horizontalAlignment: TextInput.AlignHCenter validator: IntValidator{bottom: 01; top: 12;} @@ -205,18 +221,18 @@ Item { } Text { - font.family: "Arial" - font.pixelSize: 18 - // color: "#525252" - text: "." + font.family: Style.fontRegular.name + font.pixelSize: 14 + color: datePicker.error ? errorColor : Style.defaultFontColor + text: "-" } TextInput { id: yearInput width: 44 - font.family: "Arial" - font.pixelSize: 18 - /// color: "#525252" + font.family: Style.fontRegular.name + font.pixelSize: 14 + color: datePicker.error ? errorColor : Style.defaultFontColor maximumLength: 4 horizontalAlignment: TextInput.AlignHCenter validator: IntValidator{bottom: 1000; top: 9999;} @@ -272,6 +288,7 @@ Item { gridVisible: false background: Rectangle { color: "transparent" } dayDelegate: Item { + z: parent.z + 1 implicitHeight: implicitWidth implicitWidth: calendar.width / 7 @@ -308,6 +325,8 @@ Item { calendar.showNextMonth() else calendar.showPreviousMonth() } + + dateChanged(); } } } diff --git a/components/HistoryTable.qml b/components/HistoryTable.qml index cac884ae..87c9be76 100644 --- a/components/HistoryTable.qml +++ b/components/HistoryTable.qml @@ -30,6 +30,8 @@ import QtQuick 2.0 import moneroComponents.Clipboard 1.0 import moneroComponents.AddressBookModel 1.0 import "../components" as MoneroComponents +import "../js/TxUtils.js" as TxUtils +import "." 1.0 ListView { id: listView @@ -65,11 +67,10 @@ ListView { return addressBookModel.data(idx, AddressBookModel.AddressBookDescriptionRole) } - footer: Rectangle { - height: 127 + height: 127 * scaleRatio width: listView.width - color: "#FFFFFF" + color: "transparent" Text { anchors.centerIn: parent @@ -82,398 +83,401 @@ ListView { delegate: Rectangle { id: delegate - height: 144 + property bool collapsed: index ? false : true + height: collapsed ? 180 * scaleRatio : 70 * scaleRatio width: listView.width - color: index % 2 ? "#F8F8F8" : "#FFFFFF" - z: listView.count - index - function collapseDropdown() { dropdown.expanded = false } + color: "transparent" - StandardButton { - id: detailsButton - anchors.right:parent.right - anchors.rightMargin: 15 - anchors.top: parent.top - anchors.topMargin: parent.height/2 - this.height/2 - width: 80 - fontSize: 14 - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - text: qsTr("Details") - onClicked: { - var tx_key = currentWallet.getTxKey(hash) - var tx_note = currentWallet.getUserNote(hash) - var rings = currentWallet.getRings(hash) - if (rings) - rings = rings.replace(/\|/g, '\n') - informationPopup.title = "Transaction details"; - informationPopup.content = buildTxDetailsString(hash,paymentId,tx_key,tx_note,destinations, rings); - informationPopup.onCloseCallback = null - informationPopup.open(); - } + function collapse(){ + delegate.height = 180 * scaleRatio; } + // borders + Rectangle{ + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + width: 1 + color: "#404040" + } + Rectangle{ + anchors.left: parent.left + anchors.top: parent.top + anchors.bottom: parent.bottom + width: collapsed ? 2 : 1 + color: collapsed ? "#BBBBBB" : "#404040" + } - Row { + Rectangle{ + anchors.right: parent.right + anchors.bottom: parent.top + anchors.left: parent.left + height: 1 + color: "#404040" + } + + Rectangle{ + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.left: parent.left + height: 1 + color: "#404040" + } + + Rectangle { id: row1 anchors.left: parent.left + anchors.leftMargin: 20 * scaleRatio anchors.right: parent.right + anchors.rightMargin: 20 * scaleRatio anchors.top: parent.top - anchors.topMargin: 14 - // -- direction indicator - Rectangle { - id: dot - width: 14 - height: width - radius: width / 2 - color: isOut ? "#FF4F41" : "#36B05B" + anchors.topMargin: 15 * scaleRatio + height: 40 * scaleRatio + color: "transparent" + + Image { + id: arrowImage + source: isOut ? "../images/downArrow.png" : "../images/upArrow-green.png" + height: 18 * scaleRatio + width: 12 * scaleRatio + anchors.top: parent.top + anchors.topMargin: 12 * scaleRatio } - Item { //separator - width: 12 - height: 14 - } - - // -- description aka recepient name from address book (TODO) - /* Text { - id: descriptionText - width: text.length ? (descriptionArea.containsMouse ? parent.width - x - 12 : 120) : 0 - anchors.verticalCenter: dot.verticalCenter - font.family: "Arial" - font.bold: true - font.pixelSize: 19 - color: "#444444" - elide: Text.ElideRight - text: description + id: txrxLabel + anchors.left: arrowImage.right + anchors.leftMargin: 18 * scaleRatio + font.family: Style.fontLight.name + font.pixelSize: 14 * scaleRatio + text: isOut ? "Sent" : "Received" + color: "#808080" + } - MouseArea { - id: descriptionArea - anchors.fill: parent - hoverEnabled: true + Text { + id: amountLabel + anchors.left: arrowImage.right + anchors.leftMargin: 18 * scaleRatio + anchors.top: txrxLabel.bottom + anchors.topMargin: 0 * scaleRatio + font.family: Style.fontBold.name + font.pixelSize: 18 * scaleRatio + font.bold: true + text: { + var _amount = amount; + if(_amount === 0){ + // *sometimes* amount is 0, while the 'destinations string' + // has the correct amount, so we try to fetch it from that instead. + _amount = TxUtils.destinationsToAmount(destinations); + _amount = (_amount *1); + } + + return _amount + " XMR"; + } + color: isOut ? "white" : "#2eb358" + } + + Rectangle { + anchors.right: parent.right + width: 300 * scaleRatio + height: parent.height + color: "transparent" + + Text { + id: dateLabel + anchors.left: parent.left + font.family: Style.fontRegular.name + font.pixelSize: 14 * scaleRatio + text: date + color: "#808080" + } + + Text { + id: timeLabel + anchors.left: dateLabel.right + anchors.leftMargin: 7 * scaleRatio + anchors.top: parent.top + anchors.topMargin: 3 * scaleRatio + font.pixelSize: 12 * scaleRatio + text: time + color: "#808080" + } + + Text { + id: toLabel + property string address: "" + color: "#BBBBBB" + anchors.left: parent.left + anchors.top: dateLabel.bottom + anchors.topMargin: 0 + font.family: Style.fontRegular.name + font.pixelSize: 16 * scaleRatio + text: { + if(isOut){ + address = TxUtils.destinationsToAddress(destinations); + if(address){ + var truncated = TxUtils.addressTruncate(address); + return "To " + truncated; + } else { + return "Unknown recipient"; + } + } + return ""; + } + + MouseArea{ + visible: parent.address !== undefined + hoverEnabled: true + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onEntered: { + toLabel.color = "white"; + } + onExited: { + toLabel.color = "#BBBBBB"; + } + onClicked: { + if(parent.address){ + console.log("Address copied to clipboard"); + clipboard.setText(parent.address); + appWindow.showStatusMessage(qsTr("Address copied to clipboard"),3) + } + } + } + } + + Rectangle { + height: 24 * scaleRatio + width: 24 * scaleRatio + color: "transparent" + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + + Image { + id: dropdownImage + height: 8 * scaleRatio + width: 12 * scaleRatio + source: "../images/whiteDropIndicator.png" + rotation: delegate.collapsed ? 180 : 0 + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + } + + MouseArea{ + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + delegate.collapsed = !delegate.collapsed; + } + } } } - */ - /* - Item { //separator - width: descriptionText.width ? 12 : 0 - height: 14 - visible: !descriptionArea.containsMouse - } - */ - // -- address (in case outgoing transaction) - N/A in case of incoming - MoneroComponents.TextBlock { - id: addressText - anchors.verticalCenter: dot.verticalCenter - width: parent.width - x - 12 - //elide: Text.ElideRight - font.family: "Arial" - font.pixelSize: 14 - color: "#545454" - text: hash - // visible: !descriptionArea.containsMouse - } } - Row { - // - Payment ID + Rectangle { id: row2 anchors.left: parent.left + anchors.leftMargin: 20 * scaleRatio anchors.right: parent.right - anchors.top: parent.top - anchors.topMargin: 40 - anchors.leftMargin: 26 + anchors.rightMargin: 20 * scaleRatio + anchors.top: row1.bottom + anchors.topMargin: 15 * scaleRatio + height: 40 * scaleRatio + color: "transparent" + visible: delegate.collapsed - // -- "PaymentID" title - Text { - id: paymentLabel - width: 86 - anchors.bottom: parent.bottom - font.family: "Arial" - font.pixelSize: 12 - color: "#535353" - text: paymentId !== "" ? qsTr("Payment ID:") + translationManager.emptyString : "" - } - // -- "PaymentID" value - MoneroComponents.TextBlock { - id: paymentIdValue - width: 136 - anchors.bottom: parent.bottom - //elide: Text.ElideRight - font.family: "Arial" - font.pixelSize:13 - color: "#545454" - text: paymentId + // left column + HistoryTableInnerColumn{ + anchors.left: parent.left + anchors.leftMargin: 30 * scaleRatio + labelHeader: "Transaction ID" + labelValue: hash.substring(0, 18) + "..." + copyValue: hash } - // Address book lookup - MoneroComponents.TextBlock { - id: addressBookLookupValue - width: 136 - anchors.bottom: parent.bottom - //elide: Text.ElideRight - font.family: "Arial" - font.pixelSize:13 - color: "#545454" - text: "(" + lookupPaymentID(paymentId) + ")" - visible: text !== "()" + + // right column + HistoryTableInnerColumn{ + anchors.right: parent.right + anchors.rightMargin: 100 * scaleRatio + width: 200 * scaleRatio + height: parent.height + color: "transparent" + + labelHeader: qsTr("Fee") + labelValue: { + if(!isOut && !fee){ + return "-"; + } else if(isOut && fee){ + return fee + " XMR"; + } else { + return "Unknown" + } + } + copyValue: { + if(isOut && fee){ return fee } + else { return "" } + } } + } - Row { - // block height row + + Rectangle { id: row3 anchors.left: parent.left + anchors.leftMargin: 20 * scaleRatio anchors.right: parent.right + anchors.rightMargin: 20 * scaleRatio anchors.top: row2.bottom - anchors.topMargin: rowSpacing - anchors.leftMargin: 26 + anchors.topMargin: 15 * scaleRatio + height: 40 * scaleRatio + color: "transparent" + visible: delegate.collapsed - // -- "BlockHeight" title - Text { - id: blockHeghtTitle - anchors.bottom: parent.bottom - width: 86 - font.family: "Arial" - font.pixelSize: 12 - color: "#535353" - text: qsTr("BlockHeight:") + translationManager.emptyString - } - // -- "BlockHeight" value - MoneroComponents.TextBlock { - width: 200 - anchors.bottom: parent.bottom - //elide: Text.ElideRight - font.family: "Arial" - font.pixelSize: 13 - color: (confirmations < confirmationsRequired)? "#FF6C3C" : "#545454" - text: { + // left column + HistoryTableInnerColumn{ + anchors.left: parent.left + anchors.leftMargin: 30 * scaleRatio + labelHeader: qsTr("Blockheight") + labelValue: { if (!isPending) if(confirmations < confirmationsRequired) - return blockHeight + " " + qsTr("(%1/%2 confirmations)").arg(confirmations).arg(confirmationsRequired) + return blockHeight + " " + qsTr("(%1/%2 confirmations)").arg(confirmations).arg(confirmationsRequired); else - return blockHeight + return blockHeight; if (!isOut) return qsTr("UNCONFIRMED") + translationManager.emptyString if (isFailed) return qsTr("FAILED") + translationManager.emptyString return qsTr("PENDING") + translationManager.emptyString + } + copyValue: labelValue + } + // right column + HistoryTableInnerColumn { + visible: currentWallet.getUserNote(hash) + anchors.right: parent.right + anchors.rightMargin: 80 * scaleRatio + width: 220 * scaleRatio + height: parent.height + color: "transparent" + + labelHeader: qsTr("Description") + labelValue: { + var note = currentWallet.getUserNote(hash); + if(note){ + if(note.length > 28) { + return note.substring(0, 28) + "..."; + } else { + return note; + } + } else { + return ""; + } + } + copyValue: { + return currentWallet.getUserNote(hash); } } - Item { //separator - width: 100 - height: 14 - } - // -- "Received by" title - Text { + + Rectangle { + id: proofButton + visible: isOut + color: "#404040" + height: 24 * scaleRatio + width: 24 * scaleRatio + anchors.right: parent.right anchors.bottom: parent.bottom - font.family: "Arial" - font.pixelSize: 12 - color: "#535353" - text: (isOut ? qsTr("Spent from:") : qsTr("Received by:")) + translationManager.emptyString + anchors.bottomMargin: 36 + radius: 20 * scaleRatio + + MouseArea { + id: proofButtonMouseArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + var address = TxUtils.destinationsToAddress(destinations); + if(address === undefined){ + console.log('getProof: Error fetching address') + return; + } + + var checked = (TxUtils.checkTxID(hash) && TxUtils.checkAddress(address, appWindow.persistentSettings.nettype)); + if(!checked){ + console.log('getProof: Error checking TxId and/or address'); + } + + console.log("getProof: Generate clicked: txid " + hash + ", address " + address); + root.getProofClicked(hash, address, ''); + } + + onEntered: { + proofButton.color = "#656565"; + } + + onExited: { + proofButton.color = "#404040"; + } + } + + Text { + color: Style.defaultFontColor + text: "P" + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + font.pixelSize: 14 * scaleRatio + } } - Item { //separator - width: 5 - height: 14 - } - // -- "Index" value - Text { + + Rectangle { + id: detailsButton + color: "#404040" + height: 24 * scaleRatio + width: 24 * scaleRatio + anchors.right: parent.right anchors.bottom: parent.bottom - font.family: "Arial" - font.pixelSize: 13 - font.bold: true - color: "#545454" - text: "#" + subaddrIndex - } - Item { //separator - width: 5 - height: 14 - } - // -- "Label" value - Text { - anchors.bottom: parent.bottom - font.family: "Arial" - font.pixelSize: 13 - color: "#545454" - text: label - elide: Text.ElideRight - width: detailsButton.x - x - 30 - } - } + anchors.bottomMargin: 6 + radius: 20 * scaleRatio - // -- "Date", "Balance" and "Amound" section - Row { - id: row4 - anchors.top: row3.bottom - anchors.left: parent.left - spacing: 12 - anchors.topMargin: rowSpacing - - Item { //separator - width: 14 - height: 14 - } - - // -- "Date" column - Column { - anchors.top: parent.top - width: 215 - - Text { - anchors.left: parent.left - font.family: "Arial" - font.pixelSize: 12 - color: "#545454" - text: qsTr("Date") + translationManager.emptyString - } - - Row { - anchors.left: parent.left - anchors.right: parent.right - spacing: 33 - - Text { - font.family: "Arial" - font.pixelSize: 18 - color: "#000000" - text: date + MouseArea { + id: detailsButtonMouseArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + var tx_key = currentWallet.getTxKey(hash) + var tx_note = currentWallet.getUserNote(hash) + var rings = currentWallet.getRings(hash) + if (rings) + rings = rings.replace(/\|/g, '\n') + informationPopup.title = "Transaction details"; + informationPopup.content = buildTxDetailsString(hash,paymentId,tx_key,tx_note,destinations, rings); + informationPopup.onCloseCallback = null + informationPopup.open(); } - Text { - font.family: "Arial" - font.pixelSize: 18 - color: "#000000" - text: time + onEntered: { + detailsButton.color = "#656565"; } - } - } - // -- "Balance" column - // XXX: we don't have a balance - /* - Column { - anchors.top: parent.top - width: 148 - visible: false - Text { - anchors.left: parent.left - font.family: "Arial" - font.pixelSize: 12 - color: "#545454" - text: qsTr("Balance") + translationManager.emptyString + onExited: { + detailsButton.color = "#404040"; + } } Text { - font.family: "Arial" - font.pixelSize: 18 - color: "#000000" - text: balance - } - } - */ - - // -- "Amount column - Column { - anchors.top: parent.top - - Text { - anchors.left: parent.left - font.family: "Arial" - font.pixelSize: 12 - color: "#545454" - text: qsTr("Amount") + translationManager.emptyString - } - - Row { - spacing: 2 - Text { - anchors.bottom: parent.bottom - anchors.bottomMargin: 3 - font.family: "Arial" - font.pixelSize: 16 - color: isOut ? "#FF4F41" : "#36B05B" - text: isOut ? "↓" : "↑" - } - - Text { - id: amountText - anchors.bottom: parent.bottom - font.family: "Arial" - font.pixelSize: 18 - color: isOut ? "#FF4F41" : "#36B05B" - text: displayAmount - } - } - } - - // -- "Fee column - Column { - anchors.top: parent.top - width: 148 - visible: isOut && fee != "" - Text { - anchors.left: parent.left - font.family: "Arial" - font.pixelSize: 12 - color: "#545454" - text: qsTr("Fee") + translationManager.emptyString - } - - Row { - spacing: 2 - Text { - anchors.bottom: parent.bottom - font.family: "Arial" - font.pixelSize: 18 - color: "#FF4F41" - text: fee - } + color: Style.defaultFontColor + text: "?" + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + font.pixelSize: 14 * scaleRatio } } } - - - /* - // Transaction dropdown menu. - // Disable for now until AddressBook implemented - TableDropdown { - id: dropdown - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.bottomMargin: 11 - anchors.rightMargin: 5 - dataModel: dropModel - z: 1 - onExpandedChanged: { - if(expanded) { - listView.previousItem = delegate - listView.currentIndex = index - } - } - onOptionClicked: { - if(option === 0) - clipboard.setText(address) - } - } - - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: 1 - color: "#DBDBDB" - } - */ - } - - ListModel { - id: dropModel - ListElement { name: "Copy address to clipboard"; icon: "../images/dropdownCopy.png" } - ListElement { name: "Add to address book"; icon: "../images/dropdownAdd.png" } - ListElement { name: "Send to this address"; icon: "../images/dropdownSend.png" } - ListElement { name: "Find similar transactions"; icon: "../images/dropdownSearch.png" } } Clipboard { id: clipboard } diff --git a/components/HistoryTableInnerColumn.qml b/components/HistoryTableInnerColumn.qml new file mode 100644 index 00000000..23ff766e --- /dev/null +++ b/components/HistoryTableInnerColumn.qml @@ -0,0 +1,91 @@ +// Copyright (c) 2014-2015, 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.0 +import QtQuick.Layouts 1.1 +import QtQuick.Dialogs 1.2 +import moneroComponents.Clipboard 1.0 +import moneroComponents.PendingTransaction 1.0 +import moneroComponents.Wallet 1.0 +import "../components" +import "." 1.0 + + +Rectangle{ + Clipboard { id: clipboard } + + width: label1.width > label2.width ? label1.width : label2.width + height: label1.height + label2.height + color: "transparent" + + property string copyValue: "" + property alias labelHeader: label1.text + property alias labelValue: label2.text + + Text { + id: label1 + anchors.left: parent.left + font.family: Style.fontRegular.name + font.pixelSize: 14 * scaleRatio + text: labelHeader + color: Style.greyFontColor + } + + Text { + id: label2 + anchors.left: parent.left + anchors.top: label1.bottom + font.family: Style.fontRegular.name + font.pixelSize: 14 * scaleRatio + text: labelValue + color: Style.dimmedFontColor + } + + // hover effect / copy value + MouseArea { + visible: copyValue !== "" + hoverEnabled: true + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onEntered: { + label1.color = Style.defaultFontColor; + label2.color = Style.defaultFontColor; + } + onExited: { + label1.color = Style.greyFontColor; + label2.color = Style.dimmedFontColor; + } + onClicked: { + if(copyValue){ + console.log("Copied to clipboard"); + clipboard.setText(copyValue); + appWindow.showStatusMessage(qsTr("Copied to clipboard"),3) + } + } + } +} diff --git a/components/HistoryTableMobile.qml b/components/HistoryTableMobile.qml index 3b1dc31c..8ea5afcc 100644 --- a/components/HistoryTableMobile.qml +++ b/components/HistoryTableMobile.qml @@ -68,7 +68,7 @@ ListView { footer: Rectangle { height: 127 * scaleRatio width: listView.width - color: "#FFFFFF" + color: "transparent" Text { anchors.centerIn: parent @@ -83,10 +83,35 @@ ListView { id: delegate height: tableContent.height + 20 * scaleRatio width: listView.width - color: index % 2 ? "#F8F8F8" : "#FFFFFF" + color: "transparent" Layout.leftMargin: 10 * scaleRatio z: listView.count - index function collapseDropdown() { dropdown.expanded = false } + + Rectangle{ + anchors.left: parent.left + anchors.top: parent.top + anchors.bottom: parent.bottom + width: 1 + color: "#404040" + } + + Rectangle{ + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.top: parent.top + width: 1 + color: "#404040" + } + + Rectangle{ + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.left: parent.left + height: 1 + color: "#404040" + } + MouseArea { anchors.fill: parent onClicked: { @@ -109,7 +134,7 @@ ListView { anchors.topMargin: parent.height/2 - this.height/2 width: 30 * scaleRatio; height: 30 * scaleRatio radius: 25 - color: "#FF4304" + color: "#404040" Image { width: 20 * scaleRatio @@ -127,16 +152,16 @@ ListView { Layout.topMargin: 20 * scaleRatio Layout.leftMargin: 10 * scaleRatio Text { - font.family: "Arial" + font.family: Style.fontMedium.name font.pixelSize: 14 * scaleRatio - color: "#555555" + color: Style.defaultFontColor text: date } Text { - font.family: "Arial" + font.family: Style.fontRegular.name font.pixelSize: 14 * scaleRatio - color: "#555555" + color: Style.dimmedFontColor text: time } @@ -144,7 +169,7 @@ ListView { Text { visible: confirmations < confirmationsRequired || isPending Layout.leftMargin: 5 * scaleRatio - font.family: "Arial" + font.family: Style.fontRegular.name font.pixelSize: 14 * scaleRatio color: (confirmations < confirmationsRequired)? "#FF6C3C" : "#545454" text: { @@ -161,7 +186,6 @@ ListView { } } - // Amount & confirmations RowLayout { Layout.leftMargin: 10 * scaleRatio @@ -169,7 +193,7 @@ ListView { Text { font.family: "Arial" font.pixelSize: 14 * scaleRatio - color: isOut ? "#FF4F41" : "#36B05B" + color: isOut ? Style.defaultFontColor : "#2eb358" text: isOut ? "↓" : "↑" } @@ -177,7 +201,7 @@ ListView { id: amountText font.family: "Arial" font.pixelSize: 18 * scaleRatio - color: isOut ? "#FF4F41" : "#36B05B" + color: isOut ? Style.defaultFontColor : "#2eb358" text: displayAmount } } diff --git a/components/InlineButton.qml b/components/InlineButton.qml new file mode 100644 index 00000000..77f88f3d --- /dev/null +++ b/components/InlineButton.qml @@ -0,0 +1,92 @@ +// Copyright (c) 2014-2015, 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.0 +import QtQuick.Layouts 1.1 +import "." 1.0 + +Item { + id: inlineButton + height: rect.height * scaleRatio + property string shadowPressedColor: "#B32D00" + property string shadowReleasedColor: "#FF4304" + property string pressedColor: "#FF4304" + property string releasedColor: "#FF6C3C" + property string icon: "" + property string textColor: "#FFFFFF" + property int fontSize: 12 * scaleRatio + property alias text: inlineText.text + signal clicked() + + function doClick() { + // Android workaround + releaseFocus(); + clicked(); + } + + Rectangle{ + id: rect + color: Style.buttonBackgroundColorDisabled + border.color: "black" + height: 28 * scaleRatio + width: inlineText.width + 22 * scaleRatio + radius: 4 + + anchors.top: parent.top + anchors.right: parent.right + + Text { + id: inlineText + font.family: Style.fontBold.name + font.bold: true + font.pixelSize: 16 * scaleRatio + color: "black" + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + } + + MouseArea { + id: buttonArea + cursorShape: rect.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor + hoverEnabled: true + anchors.fill: parent + onClicked: doClick() + onEntered: { + rect.color = "#707070"; + rect.opacity = 0.8; + } + onExited: { + rect.opacity = 1.0; + rect.color = "#808080"; + } + } + } + + Keys.onSpacePressed: doClick() + Keys.onReturnPressed: doClick() +} diff --git a/components/Input.qml b/components/Input.qml index 076fd9bc..d1ddae89 100644 --- a/components/Input.qml +++ b/components/Input.qml @@ -26,21 +26,20 @@ // 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.Controls 1.2 -import QtQuick.Controls.Styles 1.2 -import QtQuick 2.2 +import QtQuick.Controls 2.2 +import QtQuick 2.7 +import "." 1.0 + TextField { - font.family: "Arial" + font.family: Style.fontRegular.name + font.pixelSize: 18 * scaleRatio + font.bold: true horizontalAlignment: TextInput.AlignLeft selectByMouse: true - style: TextFieldStyle { - textColor: "#3F3F3F" - placeholderTextColor: "#BABABA" + color: Style.defaultFontColor - background: Rectangle { - border.width: 0 - color: "transparent" - } + background: Rectangle { + color: "transparent" } } diff --git a/components/InputDialog.qml b/components/InputDialog.qml index 8ab5b5d8..37354b35 100644 --- a/components/InputDialog.qml +++ b/components/InputDialog.qml @@ -26,8 +26,8 @@ // 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.0 -import QtQuick.Controls 1.4 +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 @@ -38,14 +38,6 @@ import "../components" as MoneroComponents Item { id: root visible: false - Rectangle { - id: bg - z: parent.z + 1 - anchors.fill: parent - color: "white" - opacity: 0.9 - } - property alias labelText: label.text property alias inputText: input.text @@ -78,42 +70,45 @@ Item { ColumnLayout { id: column - //anchors {fill: parent; margins: 16 } + + Layout.fillWidth: true Layout.alignment: Qt.AlignHCenter + Layout.maximumWidth: 400 * scaleRatio Label { id: label - Layout.alignment: Qt.AlignHCenter - // Layout.columnSpan: 2 + anchors.left: parent.left Layout.fillWidth: true - horizontalAlignment: Text.AlignHCenter - font.pixelSize: 18 * scaleRatio - font.family: "Arial" - color: "#555555" + + font.pixelSize: 16 * scaleRatio + font.family: Style.fontLight.name + + color: Style.defaultFontColor } TextField { id : input focus: true + Layout.topMargin: 6 Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - horizontalAlignment: TextInput.AlignHCenter + anchors.left: parent.left + horizontalAlignment: TextInput.AlignLeft verticalAlignment: TextInput.AlignVCenter - font.family: "Arial" - font.pixelSize: 32 * scaleRatio - // echoMode: TextInput.Password + font.family: Style.fontLight.name + font.pixelSize: 24 * scaleRatio KeyNavigation.tab: okButton + bottomPadding: 10 + leftPadding: 10 + topPadding: 10 + color: Style.defaultFontColor - style: TextFieldStyle { - renderType: Text.NativeRendering - textColor: "#35B05A" - // passwordCharacter: "•" - // no background - background: Rectangle { - radius: 0 - border.width: 0 - } + background: Rectangle { + radius: 2 + border.color: Qt.rgba(255, 255, 255, 0.35) + border.width: 1 + color: "black" } + Keys.onReturnPressed: { root.close() root.accepted() @@ -123,59 +118,47 @@ Item { root.rejected() } } - // underline - Rectangle { - height: 1 - color: "#DBDBDB" - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - anchors.bottomMargin: 3 - } - // padding - Rectangle { - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - height: 10 - opacity: 0 - color: "black" - } - } - // Ok/Cancel buttons - RowLayout { - id: buttons - spacing: 60 - Layout.alignment: Qt.AlignHCenter - - MoneroComponents.StandardButton { - id: cancelButton - width: 120 - fontSize: 14 - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - text: qsTr("Cancel") + translationManager.emptyString - KeyNavigation.tab: input - onClicked: { - root.close() - root.rejected() + + // Ok/Cancel buttons + RowLayout { + id: buttons + spacing: 16 * scaleRatio + Layout.topMargin: 16 + Layout.alignment: Qt.AlignRight + + MoneroComponents.StandardButton { + id: cancelButton + small: true + width: 120 + fontSize: 14 + text: qsTr("Cancel") + translationManager.emptyString + KeyNavigation.tab: input + onClicked: { + root.close() + root.rejected() + } } - } - MoneroComponents.StandardButton { - id: okButton - width: 120 - fontSize: 14 - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - text: qsTr("Ok") - KeyNavigation.tab: cancelButton - onClicked: { - root.close() - root.accepted() + MoneroComponents.StandardButton { + id: okButton + small: true + width: 120 + fontSize: 14 + text: qsTr("Ok") + KeyNavigation.tab: cancelButton + onClicked: { + root.close() + root.accepted() + } } } } } + + Rectangle { + id: bg + z: parent.z + 1 + anchors.fill: parent + color: "black" + opacity: 0.8 + } } diff --git a/components/InputMulti.qml b/components/InputMulti.qml new file mode 100644 index 00000000..3b860fdf --- /dev/null +++ b/components/InputMulti.qml @@ -0,0 +1,68 @@ +// Copyright (c) 2014-2015, 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.Controls 2.2 + +import QtQuick 2.7 +import "../js/TxUtils.js" as TxUtils +import "." 1.0 + + +TextArea { + property bool error: false + property bool addressValidation: false + property bool wrapAnywhere: true + property int fontSize: 18 * scaleRatio + property bool fontBold: false + + id: textArea + font.family: Style.fontRegular.name + font.pixelSize: fontSize + font.bold: fontBold + horizontalAlignment: TextInput.AlignLeft + selectByMouse: true + color: Style.defaultFontColor + + wrapMode: { + if(wrapAnywhere){ + return Text.WrapAnywhere; + } else { + return Text.WordWrap; + } + } + onTextChanged: { + if(addressValidation){ + // js replacement for `RegExpValidator { regExp: /[0-9A-Fa-f]{95}/g }` + textArea.text = textArea.text.replace(/[^a-z0-9]/gi,''); + var address_ok = TxUtils.checkAddress(textArea.text, appWindow.persistentSettings.nettype); + if(!address_ok) error = true; + else error = false; + TextArea.cursorPosition = textArea.text.length; + } + } +} diff --git a/components/Label.qml b/components/Label.qml index 76b13c05..b77a614c 100644 --- a/components/Label.qml +++ b/components/Label.qml @@ -29,6 +29,8 @@ import QtQuick 2.0 import QtQuick.Layouts 1.1 +import "." 1.0 + Item { id: item property alias text: label.text @@ -36,11 +38,14 @@ Item { property alias textFormat: label.textFormat property string tipText: "" property int fontSize: 16 * scaleRatio + property bool fontBold: false + property string fontColor: Style.defaultFontColor + property string fontFamily: "" property alias wrapMode: label.wrapMode property alias horizontalAlignment: label.horizontalAlignment signal linkActivated() - width: icon.x + icon.width * scaleRatio - height: icon.height * scaleRatio + height: label.height * scaleRatio + width: label.width * scaleRatio Layout.topMargin: 10 * scaleRatio Text { @@ -48,38 +53,16 @@ Item { anchors.bottom: parent.bottom anchors.bottomMargin: 2 * scaleRatio anchors.left: parent.left - font.family: "Arial" + font.family: { + if(fontFamily){ + return fontFamily; + } else { + return Style.fontRegular.name; + } + } font.pixelSize: fontSize - color: "#555555" + font.bold: fontBold + color: fontColor onLinkActivated: item.linkActivated() } - - Image { - id: icon - anchors.verticalCenter: parent.verticalCenter - anchors.left: label.right - anchors.leftMargin: 5 * scaleRatio - source: "../images/whatIsIcon.png" - visible: appWindow.whatIsEnable - } - -// MouseArea { -// anchors.fill: icon -// enabled: appWindow.whatIsEnable -// hoverEnabled: true -// onEntered: { -// icon.visible = false -// var pos = appWindow.mapFromItem(icon, 0, -15) -// tipItem.text = item.tipText -// tipItem.x = pos.x -// if(tipItem.height > 30) -// pos.y -= tipItem.height - 28 -// tipItem.y = pos.y -// tipItem.visible = true -// } -// onExited: { -// icon.visible = Qt.binding(function(){ return appWindow.whatIsEnable; }) -// tipItem.visible = false -// } -// } } diff --git a/components/LabelButton.qml b/components/LabelButton.qml new file mode 100644 index 00000000..38b05fbc --- /dev/null +++ b/components/LabelButton.qml @@ -0,0 +1,73 @@ +// Copyright (c) 2014-2015, 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.0 +import QtQuick.Layouts 1.1 +import "." 1.0 + + +Rectangle { + signal clicked(); + property alias text: labelButtonText.text + + id: labelButton + color: "#808080" + radius: 3 + height: 20 + width: labelButtonText.width + 14 + anchors.right: copyButton.left + anchors.rightMargin: 6 + visible: isValidOpenAliasAddress(addressLine.text) + + Text { + id: labelButtonText + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + font.family: Style.fontRegular.name + font.pixelSize: 12 + font.bold: true + text: "" + color: "black" + } + + MouseArea { + cursorShape: Qt.PointingHandCursor + anchors.fill: parent + hoverEnabled: true + onClicked: labelButton.clicked() + onEntered: { + labelButton.color = "#707070"; + labelButtonText.opacity = 0.8; + } + onExited: { + labelButton.color = "#808080"; + labelButtonText.opacity = 1.0; + } + } +} + diff --git a/components/LabelSubheader.qml b/components/LabelSubheader.qml new file mode 100644 index 00000000..daa067e0 --- /dev/null +++ b/components/LabelSubheader.qml @@ -0,0 +1,45 @@ +// Copyright (c) 2014-2015, 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.0 +import "." 1.0 + +Label { + id: item + fontSize: 17 * scaleRatio + + Rectangle { + anchors.top: item.bottom + anchors.topMargin: 4 + anchors.left: parent.left + anchors.right: parent.right + height: 2 + color: Style.dividerColor + opacity: Style.dividerOpacity + } +} diff --git a/components/LineEdit.qml b/components/LineEdit.qml index c91073a7..f7266d2c 100644 --- a/components/LineEdit.qml +++ b/components/LineEdit.qml @@ -27,54 +27,187 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 +import "." 1.0 Item { id: item - property alias placeholderText: input.placeholderText property alias text: input.text + + property alias placeholderText: placeholderLabel.text + property bool placeholderCenter: false + property string placeholderFontFamily: Style.fontRegular.name + property bool placeholderFontBold: false + property int placeholderFontSize: 18 * scaleRatio + property string placeholderColor: Style.defaultFontColor + property real placeholderOpacity: 0.25 + property alias validator: input.validator property alias readOnly : input.readOnly property alias cursorPosition: input.cursorPosition property alias echoMode: input.echoMode + property alias inlineButton: inlineButtonId + property alias inlineButtonText: inlineButtonId.text + property alias inlineIcon: inlineIcon.visible + property bool copyButton: false + property string borderColor: { + if(input.activeFocus){ + return Qt.rgba(255, 255, 255, 0.35); + } else { + return Qt.rgba(255, 255, 255, 0.25); + } + } + property bool borderDisabled: false property int fontSize: 18 * scaleRatio property bool showBorder: true + property bool fontBold: false + property alias fontColor: input.color property bool error: false - signal editingFinished() + property alias labelText: inputLabel.text + property alias labelColor: inputLabel.color + property alias labelTextFormat: inputLabel.textFormat + property string backgroundColor: "transparent" + property string tipText: "" + property int labelFontSize: 16 * scaleRatio + property bool labelFontBold: false + property alias labelWrapMode: inputLabel.wrapMode + property alias labelHorizontalAlignment: inputLabel.horizontalAlignment + property bool showingHeader: inputLabel.text !== "" || copyButton + property int inputHeight: 42 * scaleRatio + + signal labelLinkActivated(); // input label, rich text signal + signal editingFinished(); signal accepted(); signal textUpdated(); - height: 37 * scaleRatio + height: showingHeader ? (inputLabel.height + inputItem.height + 2) * scaleRatio : 42 * scaleRatio - function getColor(error) { - if (error) - return "#FFDDDD" - else - return "#FFFFFF" + onTextUpdated: { + // check to remove placeholder text when there is content + if(item.isEmpty()){ + placeholderLabel.visible = true; + } else { + placeholderLabel.visible = false; + } } - Rectangle { - visible: showBorder - anchors.fill: parent - anchors.bottomMargin: 1 * scaleRatio - color: "#DBDBDB" - //radius: 4 + function isEmpty(){ + var val = input.text; + if(val === "") { + return true; + } + else { + return false; + } } - Rectangle { - anchors.fill: parent - anchors.topMargin: 1 * scaleRatio - color: getColor(error) - //radius: 4 + Text { + id: inputLabel + anchors.top: parent.top + anchors.left: parent.left + anchors.topMargin: 2 * scaleRatio + font.family: Style.fontLight.name + font.pixelSize: labelFontSize + font.bold: labelFontBold + textFormat: Text.RichText + color: Style.defaultFontColor + onLinkActivated: item.labelLinkActivated() + + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.NoButton + cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor + } } - Input { - id: input - anchors.fill: parent - anchors.leftMargin: 4 * scaleRatio - anchors.rightMargin: 30 * scaleRatio - font.pixelSize: parent.fontSize - onEditingFinished: item.editingFinished() - onAccepted: item.accepted(); - onTextChanged: item.textUpdated() + LabelButton { + id: copyButtonId + text: qsTr("Copy") + anchors.right: parent.right + onClicked: { + if (input.text.length > 0) { + console.log("Copied to clipboard"); + clipboard.setText(input.text); + appWindow.showStatusMessage(qsTr("Copied to clipboard"), 3); + } + } + visible: copyButton && input.text !== "" + } + + Item{ + id: inputItem + height: inputHeight * scaleRatio + anchors.top: showingHeader ? inputLabel.bottom : parent.top + anchors.topMargin: showingHeader ? 12 * scaleRatio : 2 * scaleRatio + width: parent.width + + Text { + id: placeholderLabel + visible: input.text ? false : true + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: placeholderCenter ? parent.horizontalCenter : undefined + anchors.left: placeholderCenter ? undefined : parent.left + anchors.leftMargin: { + if(placeholderCenter){ + return undefined; + } + else if(inlineIcon.visible){ return 50 * scaleRatio; } + else { return 10 * scaleRatio; } + } + + opacity: item.placeholderOpacity + color: item.placeholderColor + font.family: item.placeholderFontFamily + font.pixelSize: placeholderFontSize * scaleRatio + font.bold: item.placeholderFontBold + text: "" + z: 3 + } + + Rectangle { + anchors.fill: parent + anchors.topMargin: 1 * scaleRatio + color: "transparent" + } + + Rectangle { + id: inputFill + color: backgroundColor + anchors.fill: parent + border.width: borderDisabled ? 0 : 1 + border.color: borderColor + radius: 4 + } + + Image { + id: inlineIcon + width: 26 * scaleRatio + height: 26 * scaleRatio + anchors.top: parent.top + anchors.topMargin: 8 * scaleRatio + anchors.left: parent.left + anchors.leftMargin: 12 * scaleRatio + source: "../images/moneroIcon-28x28.png" + visible: false + } + + Input { + id: input + anchors.fill: parent + anchors.leftMargin: inlineIcon.visible ? 38 : 0 + font.pixelSize: item.fontSize + font.bold: item.fontBold + onEditingFinished: item.editingFinished() + onAccepted: item.accepted(); + onTextChanged: item.textUpdated() + } + + InlineButton { + id: inlineButtonId + visible: item.inlineButtonText ? true : false + anchors.right: parent.right + anchors.rightMargin: 8 * scaleRatio + anchors.top: parent.top + anchors.topMargin: 6 * scaleRatio + } } } diff --git a/components/LineEditMulti.qml b/components/LineEditMulti.qml new file mode 100644 index 00000000..b013156a --- /dev/null +++ b/components/LineEditMulti.qml @@ -0,0 +1,140 @@ +// Copyright (c) 2014-2015, 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.0 +import QtQuick.Layouts 1.1 +import "." 1.0 + + +ColumnLayout { + id: lineditmulti + property alias text: multiLine.text + property alias placeholderText: placeholderLabel.text + property alias labelText: inputLabel.text + property alias error: multiLine.error + property alias readOnly: multiLine.readOnly + property alias addressValidation: multiLine.addressValidation + property alias labelButtonText: labelButton.text + property bool labelFontBold: false + property bool labelButtonVisible: false + property bool copyButton: false + property bool wrapAnywhere: true + property bool showingHeader: true + property bool showBorder: true + property bool fontBold: false + property int fontSize: 16 * scaleRatio + + signal labelButtonClicked(); + signal inputLabelLinkActivated(); + + spacing: 0 + Rectangle { + id: inputLabelRect + color: "transparent" + Layout.fillWidth: true + height: (inputLabel.height + 10) * scaleRatio + visible: showingHeader ? true : false + + Text { + id: inputLabel + anchors.top: parent.top + anchors.left: parent.left + font.family: Style.fontRegular.name + font.pixelSize: 16 * scaleRatio + font.bold: labelFontBold + textFormat: Text.RichText + color: Style.defaultFontColor + onLinkActivated: inputLabelLinkActivated() + } + + LabelButton { + id: labelButton + onClicked: labelButtonClicked() + visible: labelButtonVisible + } + + LabelButton { + id: copyButtonId + visible: copyButton && multiLine.text !== "" + text: qsTr("Copy") + anchors.right: labelButton.visible ? inputLabel.right : parent.right + anchors.rightMargin: labelButton.visible? 4 : 0 + onClicked: { + if (multiLine.text.length > 0) { + console.log("Copied to clipboard"); + clipboard.setText(multiLine.text); + appWindow.showStatusMessage(qsTr("Copied to clipboard"), 3); + } + } + } + } + + InputMulti { + id: multiLine + readOnly: false + addressValidation: true + anchors.top: parent.showingHeader ? inputLabelRect.bottom : parent.top + Layout.fillWidth: true + topPadding: parent.showingHeader ? 10 * scaleRatio : 0 + bottomPadding: 10 * scaleRatio + wrapAnywhere: parent.wrapAnywhere + fontSize: parent.fontSize + fontBold: parent.fontBold + + Text { + id: placeholderLabel + visible: multiLine.text ? false : true + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 10 * scaleRatio + opacity: 0.25 + color: Style.defaultFontColor + font.family: Style.fontRegular.name + font.pixelSize: 18 * scaleRatio + text: "" + z: 3 + } + + Rectangle { + color: "transparent" + border.width: 1 + border.color: { + if(multiLine.error && multiLine.text !== ""){ + return Qt.rgba(255, 0, 0, 0.45); + } else if(multiLine.activeFocus){ + return Qt.rgba(255, 255, 255, 0.35); + } else { + return Qt.rgba(255, 255, 255, 0.25); + } + } + radius: 4 + anchors.fill: parent + visible: lineditmulti.showBorder + } + } +} diff --git a/components/MenuButton.qml b/components/MenuButton.qml index 778dca68..ef6da091 100644 --- a/components/MenuButton.qml +++ b/components/MenuButton.qml @@ -26,7 +26,8 @@ // 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.0 +import QtQuick 2.5 +import "." 1.0 Rectangle { id: button @@ -55,9 +56,91 @@ Rectangle { return offset } - color: checked ? "#FFFFFF" : "#1C1C1C" + color: "transparent" property bool present: !under || under.checked || checked || under.numSelectedChildren > 0 - height: present ? ((appWindow.height >= 800) ? 48 * scaleRatio : 36 * scaleRatio ) : 0 + height: present ? ((appWindow.height >= 800) ? 44 * scaleRatio : 38 * scaleRatio ) : 0 + + // button gradient while checked + Image { + height: parent.height + width: 260 + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: -20 + anchors.leftMargin: parent.getOffset() + source: "../images/menuButtonGradient.png" + visible: button.checked + } + + // button decorations that are subject to leftMargin offsets + Rectangle { + anchors.left: parent.left + anchors.leftMargin: parent.getOffset() + 20 * scaleRatio + height: parent.height + width: button.checked ? 20: 10 + color: "#00000000" + + // dot if unchecked + Rectangle { + id: dot + anchors.centerIn: parent + width: button.checked ? 20 * scaleRatio : 8 * scaleRatio + height: button.checked ? 20 * scaleRatio : 8 * scaleRatio + radius: button.checked ? 20 * scaleRatio : 4 * scaleRatio + color: button.dotColor + // arrow if checked + Image { + anchors.centerIn: parent + anchors.left: parent.left + source: "../images/arrow-right-medium-white.png" + visible: button.checked + } + } + + // button text + Text { + id: label + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.right + anchors.leftMargin: 8 * scaleRatio + font.family: Style.fontMedium.name + font.bold: true + font.pixelSize: 16 * scaleRatio + color: "#FFFFFF" + } + } + + // menu button right arrow + Image { + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 20 * scaleRatio + anchors.leftMargin: parent.getOffset() + source: "../images/right.png" + opacity: button.checked ? 1.0 : 0.4 + } + + Text { + id: symbolText + anchors.centerIn: parent + font.pixelSize: 11 * scaleRatio + font.bold: true + color: button.checked || buttonArea.containsMouse ? "#FFFFFF" : dot.color + visible: appWindow.ctrlPressed + } + + MouseArea { + id: buttonArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + if(parent.checked) + return + button.doClick() + parent.checked = true + } + } transform: Scale { yScale: button.present ? 1 : 0 @@ -77,77 +160,4 @@ Rectangle { // we get the value of checked before the change ScriptAction { script: if (under) under.numSelectedChildren += checked > 0 ? -1 : 1 } } - - Item { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.leftMargin: parent.getOffset() - width: 50 * scaleRatio - - Rectangle { - id: dot - anchors.centerIn: parent - width: 14 * scaleRatio - height: width - radius: height / 2 - - Rectangle { - anchors.centerIn: parent - width: 10 * scaleRatio - height: width - radius: height / 2 - color: "#1C1C1C" - visible: !button.checked && !buttonArea.containsMouse - } - } - - Text { - id: symbolText - anchors.centerIn: parent - font.pixelSize: 11 * scaleRatio - font.bold: true - color: button.checked || buttonArea.containsMouse ? "#FFFFFF" : dot.color - visible: appWindow.ctrlPressed - } - } - - Rectangle { - anchors.left: parent.left - anchors.top: parent.top - anchors.bottom: parent.bottom - width: 1 - color: "#DBDBDB" - visible: parent.checked - } - - Image { - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: 20 * scaleRatio - anchors.leftMargin: parent.getOffset() - source: "../images/menuIndicator.png" - } - - Text { - id: label - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: parent.getOffset() + 50 * scaleRatio - font.family: "Arial" - font.pixelSize: 16 * scaleRatio - color: parent.checked ? "#000000" : "#FFFFFF" - } - - MouseArea { - id: buttonArea - anchors.fill: parent - hoverEnabled: true - onClicked: { - if(parent.checked) - return - button.doClick() - parent.checked = true - } - } } diff --git a/components/NetworkStatusItem.qml b/components/NetworkStatusItem.qml index 440d1bb9..f1916457 100644 --- a/components/NetworkStatusItem.qml +++ b/components/NetworkStatusItem.qml @@ -27,26 +27,15 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 +import QtQuick.Layouts 1.1 import moneroComponents.Wallet 1.0 +import "." 1.0 Rectangle { id: item + color: "transparent" property var connected: Wallet.ConnectionStatus_Disconnected - function getConnectionStatusImage(status) { - if (status == Wallet.ConnectionStatus_Connected) - return "../images/statusConnected.png" - else - return "../images/statusDisconnected.png" - } - - function getConnectionStatusColor(status) { - if (status == Wallet.ConnectionStatus_Connected) - return "#FF6C3B" - else - return "#AAAAAA" - } - function getConnectionStatusString(status) { if (status == Wallet.ConnectionStatus_Connected) { if(!appWindow.daemonSynced) @@ -62,40 +51,64 @@ Rectangle { return qsTr("Invalid connection status") } + RowLayout { + Layout.preferredHeight: 40 * scaleRatio - color: "#1C1C1C" - Row { - height: 60 * scaleRatio Item { id: iconItem - anchors.bottom: parent.bottom - width: 50 * scaleRatio - height: 50 * scaleRatio + anchors.top: parent.top + width: 40 * scaleRatio + height: 40 * scaleRatio + opacity: { + if(item.connected == Wallet.ConnectionStatus_Connected){ + return 1 + } else { + return 0.5 + } + } Image { - anchors.centerIn: parent - source: getConnectionStatusImage(item.connected) + anchors.top: parent.top + anchors.topMargin: 6 + anchors.right: parent.right + anchors.rightMargin: 11 + source: { + if(item.connected == Wallet.ConnectionStatus_Connected){ + return "../images/lightning.png" + } else { + return "../images/lightning-white.png" + } + } } } - Column { - anchors.bottom: parent.bottom - height: 53 * scaleRatio - spacing: 3 * scaleRatio + Item { + anchors.top: parent.top + anchors.left: iconItem.right + height: 40 * scaleRatio + width: 260 * scaleRatio Text { + id: statusText anchors.left: parent.left - font.family: "Arial" - font.pixelSize: 12 * scaleRatio - color: "#545454" + anchors.top: parent.top + anchors.topMargin: 0 + font.family: Style.fontMedium.name + font.bold: true + font.pixelSize: 13 * scaleRatio + color: "white" + opacity: 0.5 text: qsTr("Network status") + translationManager.emptyString } Text { + id: statusTextVal anchors.left: parent.left - font.family: "Arial" - font.pixelSize: 18 * scaleRatio - color: getConnectionStatusColor(item.connected) + anchors.top: parent.top + anchors.topMargin: 14 + font.family: Style.fontMedium.name + font.pixelSize: 20 * scaleRatio + color: "white" text: getConnectionStatusString(item.connected) + translationManager.emptyString } } diff --git a/components/NewPasswordDialog.qml b/components/NewPasswordDialog.qml index 414a225d..9d4e4d20 100644 --- a/components/NewPasswordDialog.qml +++ b/components/NewPasswordDialog.qml @@ -26,8 +26,8 @@ // 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.0 -import QtQuick.Controls 1.4 +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 @@ -42,8 +42,8 @@ Item { id: bg z: parent.z + 1 anchors.fill: parent - color: "white" - opacity: 0.9 + color: "black" + opacity: 0.8 } property alias password: passwordInput1.text @@ -93,57 +93,60 @@ Item { ColumnLayout { id: column - //anchors {fill: parent; margins: 16 } + + Layout.fillWidth: true Layout.alignment: Qt.AlignHCenter + Layout.maximumWidth: 400 * scaleRatio Label { text: qsTr("Please enter new password") - Layout.alignment: Qt.AlignHCenter - Layout.columnSpan: 2 + anchors.left: parent.left Layout.fillWidth: true - horizontalAlignment: Text.AlignHCenter - font.pixelSize: 18 * scaleRatio - font.family: "Arial" - color: "#555555" + + font.pixelSize: 16 * scaleRatio + font.family: Style.fontLight.name + + color: Style.defaultFontColor } TextField { id : passwordInput1 + Layout.topMargin: 6 Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - Layout.maximumWidth: 400 * scaleRatio - horizontalAlignment: TextInput.AlignHCenter + anchors.left: parent.left + horizontalAlignment: TextInput.AlignLeft verticalAlignment: TextInput.AlignVCenter - font.family: "Arial" - font.pixelSize: 32 * scaleRatio + font.family: Style.fontLight.name + font.pixelSize: 24 * scaleRatio echoMode: TextInput.Password + bottomPadding: 10 + leftPadding: 10 + topPadding: 10 + color: Style.defaultFontColor KeyNavigation.tab: passwordInput2 - style: TextFieldStyle { - renderType: Text.NativeRendering - textColor: "#35B05A" - passwordCharacter: "•" - // no background - background: Rectangle { - radius: 0 - border.width: 0 + background: Rectangle { + radius: 2 + border.color: Qt.rgba(255, 255, 255, 0.35) + border.width: 1 + color: "black" + + Image { + width: 12 + height: 16 + source: "../images/lockIcon.png" + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 20 } } + Keys.onEscapePressed: { root.close() root.rejected() } } - // underline - Rectangle { - height: 1 - color: "#DBDBDB" - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - anchors.bottomMargin: 3 - Layout.maximumWidth: passwordInput1.width - } // padding Rectangle { Layout.fillWidth: true @@ -155,37 +158,47 @@ Item { Label { text: qsTr("Please confirm new password") - Layout.alignment: Qt.AlignHCenter - Layout.columnSpan: 2 + anchors.left: parent.left Layout.fillWidth: true - horizontalAlignment: Text.AlignHCenter - font.pixelSize: 18 * scaleRatio - font.family: "Arial" - color: "#555555" + + font.pixelSize: 16 * scaleRatio + font.family: Style.fontLight.name + + color: Style.defaultFontColor } TextField { id : passwordInput2 + Layout.topMargin: 6 Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - Layout.maximumWidth: 400 * scaleRatio - horizontalAlignment: TextInput.AlignHCenter + anchors.left: parent.left + horizontalAlignment: TextInput.AlignLeft verticalAlignment: TextInput.AlignVCenter - font.family: "Arial" - font.pixelSize: 32 * scaleRatio + font.family: Style.fontLight.name + font.pixelSize: 24 * scaleRatio echoMode: TextInput.Password KeyNavigation.tab: okButton + bottomPadding: 10 + leftPadding: 10 + topPadding: 10 + color: Style.defaultFontColor - style: TextFieldStyle { - renderType: Text.NativeRendering - textColor: "#35B05A" - passwordCharacter: "•" - // no background - background: Rectangle { - radius: 0 - border.width: 0 + background: Rectangle { + radius: 2 + border.color: Qt.rgba(255, 255, 255, 0.35) + border.width: 1 + color: "black" + + Image { + width: 12 + height: 16 + source: "../images/lockIcon.png" + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 20 } } + Keys.onReturnPressed: { if (passwordInput1.text === passwordInput2.text) { root.close() @@ -198,15 +211,6 @@ Item { } } - // underline - Rectangle { - height: 1 - color: "#DBDBDB" - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - anchors.bottomMargin: 3 - Layout.maximumWidth: passwordInput1.width - } // padding Rectangle { Layout.fillWidth: true @@ -215,38 +219,32 @@ Item { opacity: 0 color: "black" } - } - // Ok/Cancel buttons - RowLayout { - id: buttons - spacing: 60 * scaleRatio - Layout.alignment: Qt.AlignHCenter - - MoneroComponents.StandardButton { - id: cancelButton - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - text: qsTr("Cancel") + translationManager.emptyString - KeyNavigation.tab: passwordInput1 - onClicked: { - root.close() - root.rejected() + + // Ok/Cancel buttons + RowLayout { + id: buttons + spacing: 16 * scaleRatio + 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 - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - text: qsTr("Continue") - KeyNavigation.tab: cancelButton - enabled: passwordInput1.text === passwordInput2.text - onClicked: { - root.close() - root.accepted() + MoneroComponents.StandardButton { + id: okButton + text: qsTr("Continue") + KeyNavigation.tab: cancelButton + enabled: passwordInput1.text === passwordInput2.text + onClicked: { + root.close() + root.accepted() + } } } } diff --git a/components/PasswordDialog.qml b/components/PasswordDialog.qml index d2315011..dabf233a 100644 --- a/components/PasswordDialog.qml +++ b/components/PasswordDialog.qml @@ -26,8 +26,8 @@ // 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.0 -import QtQuick.Controls 1.4 +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 @@ -38,13 +38,6 @@ import "../components" as MoneroComponents Item { id: root visible: false - Rectangle { - id: bg - z: parent.z + 1 - anchors.fill: parent - color: "white" - opacity: 0.9 - } property alias password: passwordInput.text property string walletName @@ -61,7 +54,7 @@ Item { titleBar.enabled = false show() root.visible = true; - passwordInput.focus = true + passwordInput.forceActiveFocus(); passwordInput.text = "" } @@ -81,42 +74,54 @@ Item { ColumnLayout { id: column - //anchors {fill: parent; margins: 16 } + + Layout.fillWidth: true Layout.alignment: Qt.AlignHCenter + Layout.maximumWidth: 400 * scaleRatio Label { - text: root.walletName.length > 0 ? qsTr("Please enter wallet password for:
") + root.walletName : qsTr("Please enter wallet password") - Layout.alignment: Qt.AlignHCenter - Layout.columnSpan: 2 + text: qsTr("Please enter wallet password") + anchors.left: parent.left Layout.fillWidth: true - horizontalAlignment: Text.AlignHCenter - font.pixelSize: 18 * scaleRatio - font.family: "Arial" - color: "#555555" + + font.pixelSize: 16 * scaleRatio + font.family: Style.fontLight.name + + color: Style.defaultFontColor } TextField { id : passwordInput + Layout.topMargin: 6 Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - Layout.maximumWidth: 400 * scaleRatio - horizontalAlignment: TextInput.AlignHCenter + anchors.left: parent.left + horizontalAlignment: TextInput.AlignLeft verticalAlignment: TextInput.AlignVCenter - font.family: "Arial" - font.pixelSize: 32 * scaleRatio + font.family: Style.fontLight.name + font.pixelSize: 24 * scaleRatio echoMode: TextInput.Password KeyNavigation.tab: okButton + bottomPadding: 10 + leftPadding: 10 + topPadding: 10 + color: Style.defaultFontColor - style: TextFieldStyle { - renderType: Text.NativeRendering - textColor: "#35B05A" - passwordCharacter: "•" - // no background - background: Rectangle { - radius: 0 - border.width: 0 + background: Rectangle { + radius: 2 + border.color: Qt.rgba(255, 255, 255, 0.35) + border.width: 1 + color: "black" + + Image { + width: 12 + height: 16 + source: "../images/lockIcon.png" + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 20 } } + Keys.onReturnPressed: { root.close() root.accepted() @@ -127,52 +132,45 @@ Item { root.rejected() } - - } - // underline - Rectangle { - height: 1 - color: "#DBDBDB" - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - anchors.bottomMargin: 3 - Layout.maximumWidth: passwordInput.width - } - } - // Ok/Cancel buttons - RowLayout { - id: buttons - spacing: 60 * scaleRatio - Layout.alignment: Qt.AlignHCenter - - MoneroComponents.StandardButton { - id: cancelButton - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - text: qsTr("Cancel") + translationManager.emptyString - KeyNavigation.tab: passwordInput - onClicked: { - root.close() - root.rejected() - } - } - MoneroComponents.StandardButton { - id: okButton - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - text: qsTr("Continue") - KeyNavigation.tab: cancelButton - onClicked: { - root.close() - root.accepted() + // Ok/Cancel buttons + RowLayout { + id: buttons + spacing: 16 * scaleRatio + Layout.topMargin: 16 + Layout.alignment: Qt.AlignRight + + MoneroComponents.StandardButton { + id: cancelButton + small: true + text: qsTr("Cancel") + translationManager.emptyString + KeyNavigation.tab: passwordInput + onClicked: { + root.close() + root.rejected() + } + } + + MoneroComponents.StandardButton { + id: okButton + small: true + text: qsTr("Continue") + KeyNavigation.tab: cancelButton + onClicked: { + root.close() + root.accepted() + } } } + } } + Rectangle { + id: bg + + anchors.fill: parent + color: "black" + opacity: 0.8 + } } diff --git a/components/ProgressBar.qml b/components/ProgressBar.qml index 04b92b3a..6e691d6e 100644 --- a/components/ProgressBar.qml +++ b/components/ProgressBar.qml @@ -28,13 +28,15 @@ import QtQuick 2.0 import moneroComponents.Wallet 1.0 +import "." 1.0 Rectangle { id: item property int fillLevel: 0 property string syncType // Wallet or Daemon property string syncText: qsTr("%1 blocks remaining: ").arg(syncType) - color: "#1C1C1C" + visible: false + color: "transparent" function updateProgress(currentBlock,targetBlock, blocksToSync, statusTxt){ if(targetBlock > 0) { @@ -50,33 +52,58 @@ Rectangle { } Item { + anchors.top: item.top + anchors.topMargin: 10 * scaleRatio anchors.leftMargin: 15 * scaleRatio anchors.rightMargin: 15 * scaleRatio anchors.fill: parent + + Text { + id: progressText + anchors.top: parent.top + anchors.topMargin: 6 + font.family: Style.fontMedium.name + font.pixelSize: 13 * scaleRatio + font.bold: true + color: "white" + text: qsTr("Synchronizing %1").arg(syncType) + height: 18 * scaleRatio + } + + Text { + id: progressTextValue + anchors.top: parent.top + anchors.topMargin: 6 + anchors.right: parent.right + font.family: Style.fontMedium.name + font.pixelSize: 13 * scaleRatio + font.bold: true + color: "white" + height:18 * scaleRatio + } + + Rectangle { id: bar anchors.left: parent.left anchors.right: parent.right - anchors.top: parent.top - height: 22 * scaleRatio - radius: 2 * scaleRatio - color: "#FFFFFF" + anchors.top: progressText.bottom + anchors.topMargin: 4 + height: 8 * scaleRatio + radius: 8 * scaleRatio + color: "#333333" // progressbar bg Rectangle { id: fillRect anchors.top: parent.top anchors.bottom: parent.bottom anchors.left: parent.left - anchors.margins: 2 * scaleRatio height: bar.height - property int maxWidth: parent.width - 4 * scaleRatio + property int maxWidth: bar.width - 4 * scaleRatio width: (maxWidth * fillLevel) / 100 - color: { - if(item.fillLevel < 99 ) return "#FF6C3C" - //if(item.fillLevel < 99) return "#FFE00A" - return "#36B25C" - } - + radius: 8 + // could change color based on progressbar status; if(item.fillLevel < 99 ) + color: "#FA6800" } Rectangle { @@ -84,16 +111,6 @@ Rectangle { anchors.bottom: parent.bottom anchors.left: parent.left anchors.leftMargin: 8 * scaleRatio - - Text { - id:progressText - anchors.bottom: parent.bottom - font.family: "Arial" - font.pixelSize: 12 * scaleRatio - color: "#000" - text: qsTr("Synchronizing %1").arg(syncType) - height:18 * scaleRatio - } } } diff --git a/components/RemoteNodeEdit.qml b/components/RemoteNodeEdit.qml index 295e4b16..1f22956f 100644 --- a/components/RemoteNodeEdit.qml +++ b/components/RemoteNodeEdit.qml @@ -33,9 +33,25 @@ import QtQuick.Layouts 1.1 GridLayout { columns: (isMobile) ? 1 : 2 + columnSpacing: 32 id: root property alias daemonAddrText: daemonAddr.text property alias daemonPortText: daemonPort.text + property alias daemonAddrLabelText: daemonAddr.labelText + property alias daemonPortLabelText: daemonPort.labelText + + // TODO: LEGACY; remove these placeHolder variables when + // the wizards get redesigned to the black-theme + property string placeholderFontFamily: Style.fontRegular.name + property bool placeholderFontBold: false + property int placeholderFontSize: 18 * scaleRatio + property string placeholderColor: Style.defaultFontColor + property real placeholderOpacity: 0.25 + + property string lineEditBorderColor: Qt.rgba(0, 0, 0, 0.15) + property string lineEditBackgroundColor: "white" + property string lineEditFontColor: "black" + property bool lineEditFontBold: true signal editingFinished() @@ -47,14 +63,31 @@ GridLayout { id: daemonAddr Layout.fillWidth: true placeholderText: qsTr("Remote Node Hostname / IP") + translationManager.emptyString + placeholderFontFamily: root.placeholderFontFamily + placeholderFontBold: root.placeholderFontBold + placeholderFontSize: root.placeholderFontSize + placeholderColor: root.placeholderColor + placeholderOpacity: root.placeholderOpacity onEditingFinished: root.editingFinished() + borderColor: lineEditBorderColor + backgroundColor: lineEditBackgroundColor + fontColor: lineEditFontColor + fontBold: lineEditFontBold } - LineEdit { id: daemonPort Layout.fillWidth: true placeholderText: qsTr("Port") + translationManager.emptyString + placeholderFontFamily: root.placeholderFontFamily + placeholderFontBold: root.placeholderFontBold + placeholderFontSize: root.placeholderFontSize + placeholderColor: root.placeholderColor + placeholderOpacity: root.placeholderOpacity onEditingFinished: root.editingFinished() + borderColor: lineEditBorderColor + backgroundColor: lineEditBackgroundColor + fontColor: lineEditFontColor + fontBold: lineEditFontBold } } diff --git a/components/Scroll.qml b/components/Scroll.qml index 8ef01087..43876a49 100644 --- a/components/Scroll.qml +++ b/components/Scroll.qml @@ -51,7 +51,7 @@ Item { Rectangle { id: scroll - width: 15 + width: 4 height: { var t = (flickable.height * flickable.height) / flickable.contentHeight return t < 20 ? 20 : t @@ -62,7 +62,7 @@ Item { visible: flickable.contentHeight > flickable.height Behavior on opacity { - NumberAnimation { duration: 100; easing.type: Easing.InQuad } + NumberAnimation { duration: 200; easing.type: Easing.InQuad } } MouseArea { diff --git a/components/StandardButton.qml b/components/StandardButton.qml index 99917752..02e08be8 100644 --- a/components/StandardButton.qml +++ b/components/StandardButton.qml @@ -28,22 +28,25 @@ import QtQuick 2.0 import QtQuick.Layouts 1.1 +import "." 1.0 Item { id: button - height: 37 * scaleRatio - property string shadowPressedColor: "#B32D00" - property string shadowReleasedColor: "#FF4304" - property string pressedColor: "#FF4304" - property string releasedColor: "#FF6C3C" + property string rightIcon: "" property string icon: "" - property string textColor: "#FFFFFF" - property int fontSize: 12 * scaleRatio + property string textColor: button.enabled? Style.buttonTextColor: Style.buttonTextColorDisabled + property bool small: false property alias text: label.text + property int fontSize: { + if(small) return 14 * scaleRatio; + else return 16 * scaleRatio; + } signal clicked() - // Dynamic label width - Layout.minimumWidth: (label.contentWidth > 50)? label.contentWidth + 10 : 60 + // Dynamic height/width + Layout.minimumWidth: (label.contentWidth > 50)? label.contentWidth + 22 : 60 + height: small ? 30 * scaleRatio : 36 * scaleRatio + function doClick() { // Android workaround @@ -55,30 +58,27 @@ Item { anchors.left: parent.left anchors.right: parent.right height: parent.height - 1 - y: buttonArea.pressed ? 0 : 1 - //radius: 4 - color: { - parent.enabled ? (buttonArea.pressed ? parent.shadowPressedColor : parent.shadowReleasedColor) - : Qt.lighter(parent.shadowReleasedColor) - } - border.color: Qt.darker(parent.releasedColor) + radius: 3 + color: parent.enabled ? Style.buttonBackgroundColor : Style.buttonBackgroundColorDisabled border.width: parent.focus ? 1 : 0 - } + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + hoverEnabled: true - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - height: parent.height - 1 - y: buttonArea.pressed ? 1 : 0 - color: { - parent.enabled ? (buttonArea.pressed ? parent.pressedColor : parent.releasedColor) - : Qt.lighter(parent.releasedColor) + propagateComposedEvents: true + // possibly do some hover effects here + onEntered: { +// if(button.enabled) parent.color = Style.buttonBackgroundColorHover; +// else parent.color = Style.buttonBackgroundColorDisabledHover; + } + onExited: { +// if(button.enabled) parent.color = Style.buttonBackgroundColor; +// else parent.color = Style.buttonBackgroundColorDisabled; + } } - //radius: 4 - - } Text { @@ -87,12 +87,11 @@ Item { anchors.left: parent.left anchors.right: parent.right horizontalAlignment: Text.AlignHCenter - font.family: "Arial" + font.family: Style.fontBold.name font.bold: true - font.pixelSize: button.fontSize + font.pixelSize: buttonArea.pressed ? button.fontSize - 1 : button.fontSize color: parent.textColor visible: parent.icon === "" -// font.capitalization : Font.Capitalize } Image { @@ -105,6 +104,7 @@ Item { id: buttonArea anchors.fill: parent onClicked: doClick() + cursorShape: Qt.PointingHandCursor } Keys.onSpacePressed: doClick() diff --git a/components/StandardDialog.qml b/components/StandardDialog.qml index 9d9766d9..5f761ae4 100644 --- a/components/StandardDialog.qml +++ b/components/StandardDialog.qml @@ -27,17 +27,19 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 -import QtQuick.Controls 1.4 +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 "../components" as MoneroComponents +import "." 1.0 + Rectangle { id: root - color: "white" + color: "transparent" visible: false property alias title: dialogTitle.text property alias text: dialogContent.text @@ -55,6 +57,14 @@ Rectangle { signal rejected() signal closeCallback(); + Image { + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + source: "../images/middlePanelBg.jpg" + } + // Make window draggable MouseArea { anchors.fill: parent @@ -68,7 +78,7 @@ Rectangle { // Center if(!isMobile) { root.x = parent.width/2 - root.width/2 - root.y = screenHeight/2 - root.height/2 + root.y = 100 } show() root.z = 11 @@ -81,13 +91,13 @@ Rectangle { } // TODO: implement without hardcoding sizes - width: isMobile ? screenWidth : 480 - height: isMobile ? screenHeight : 280 + width: isMobile ? screenWidth : 520 + height: isMobile ? screenHeight : 380 ColumnLayout { id: mainLayout spacing: 10 - anchors { fill: parent; margins: 35 } + anchors { fill: parent; margins: 15 } RowLayout { id: column @@ -97,9 +107,9 @@ Rectangle { Label { id: dialogTitle horizontalAlignment: Text.AlignHCenter - font.pixelSize: 18 * scaleRatio - font.family: "Arial" - color: "#555555" + fontSize: 18 * scaleRatio + fontFamily: "Arial" + color: Style.defaultFontColor } } @@ -109,12 +119,14 @@ Rectangle { id : dialogContent Layout.fillWidth: true Layout.fillHeight: true - font.family: "Arial" + renderType: Text.QtRendering + font.family: Style.fontLight.name textFormat: TextEdit.AutoText readOnly: true - font.pixelSize: 12 * scaleRatio + font.pixelSize: 14 * scaleRatio selectByMouse: false wrapMode: TextEdit.Wrap + color: Style.defaultFontColor MouseArea { anchors.fill: parent @@ -140,10 +152,6 @@ Rectangle { MoneroComponents.StandardButton { id: cancelButton - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" text: qsTr("Cancel") + translationManager.emptyString onClicked: { root.close() @@ -153,10 +161,6 @@ Rectangle { MoneroComponents.StandardButton { id: okButton - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" text: qsTr("OK") KeyNavigation.tab: cancelButton onClicked: { @@ -168,6 +172,38 @@ Rectangle { } } + // window borders + Rectangle{ + width: 1 + color: Style.grey + anchors.left: parent.left + anchors.top: parent.top + anchors.bottom: parent.bottom + } + + Rectangle{ + width: 1 + color: Style.grey + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + } + + Rectangle{ + height: 1 + color: Style.grey + anchors.left: parent.left + anchors.top: parent.top + anchors.right: parent.right + } + + Rectangle{ + height: 1 + color: Style.grey + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.right: parent.right + } } diff --git a/components/StandardDropdown.qml b/components/StandardDropdown.qml index 5281b846..9ab90f4b 100644 --- a/components/StandardDropdown.qml +++ b/components/StandardDropdown.qml @@ -27,6 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 +import "." 1.0 Item { id: dropdown @@ -38,11 +39,17 @@ Item { property string textColor: "#FFFFFF" property alias currentIndex: column.currentIndex property bool expanded: false + property int dropdownHeight: 42 + property int fontHeaderSize: 16 * scaleRatio + property int fontItemSize: 14 * scaleRatio + property string colorHeaderBackground: "transparent" + property bool headerBorder: true + property bool headerFontBold: false + + height: dropdownHeight signal changed(); - height: 37 * scaleRatio - onExpandedChanged: if(expanded) appWindow.currentItem = dropdown function hide() { dropdown.expanded = false } function containsPoint(px, py) { @@ -60,7 +67,6 @@ Item { // Workaroud for suspected memory leak in 5.8 causing malloc crash on app exit function update() { firstColText.text = column.currentIndex < repeater.model.rowCount() ? qsTr(repeater.model.get(column.currentIndex).column1) + translationManager.emptyString : "" - secondColText.text = column.currentIndex < repeater.model.rowCount() ? qsTr(repeater.model.get(column.currentIndex).column2) + translationManager.emptyString : "" } Item { @@ -68,42 +74,14 @@ Item { anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top - height: 37 * scaleRatio + height: dropdown.dropdownHeight Rectangle { - anchors.left: parent.left - anchors.right: parent.right - height: parent.height - 1 - y: dropdown.expanded || droplist.height > 0 ? 0 : 1 - color: dropdown.expanded || droplist.height > 0 ? dropdown.shadowPressedColor : dropdown.shadowReleasedColor - //radius: 4 - } - - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - height: parent.height - 1 - y: dropdown.expanded || droplist.height > 0 ? 1 : 0 - color: dropdown.expanded || droplist.height > 0 ? dropdown.pressedColor : dropdown.releasedColor - //radius: 4 - } - - Rectangle { - anchors.left: parent.left - anchors.bottom: parent.bottom - height: 3 * scaleRatio - width: 3 * scaleRatio - color: dropdown.pressedColor - visible: dropdown.expanded || droplist.height > 0 - } - - Rectangle { - anchors.right: parent.right - anchors.bottom: parent.bottom - height: 3 * scaleRatio - width: 3 * scaleRatio - color: dropdown.pressedColor - visible: dropdown.expanded || droplist.height > 0 + color: dropdown.colorHeaderBackground + border.width: dropdown.headerBorder ? 1 : 0 + border.color: Qt.rgba(1, 1, 1, 0.25) + radius: 4 + anchors.fill: parent } Text { @@ -112,31 +90,9 @@ Item { anchors.left: parent.left anchors.leftMargin: 12 * scaleRatio elide: Text.ElideRight - font.family: "Arial" - font.bold: true - font.pixelSize: 12 * scaleRatio - color: "#FFFFFF" - } - - Text { - id: secondColText - anchors.verticalCenter: parent.verticalCenter - anchors.right: separator.left - anchors.rightMargin: 12 * scaleRatio - width: dropdown.expanded ? w : (separator.x - 12) - (firstColText.x + firstColText.width + 5) - font.family: "Arial" - font.pixelSize: 12 * scaleRatio - color: "#FFFFFF" - property int w: 0 - Component.onCompleted: w = implicitWidth - } - - Rectangle { - id: separator - anchors.right: dropIndicator.left - anchors.verticalCenter: parent.verticalCenter - height: 18 * scaleRatio - width: 1 + font.family: Style.fontRegular.name + font.bold: dropdown.headerFontBold + font.pixelSize: dropdown.fontHeaderSize color: "#FFFFFF" } @@ -158,6 +114,8 @@ Item { id: dropArea anchors.fill: parent onClicked: dropdown.expanded = !dropdown.expanded + hoverEnabled: true + cursorShape: Qt.PointingHandCursor } } @@ -211,24 +169,24 @@ Item { property string stringSent: qsTr("Sent") + translationManager.emptyString property string stringReceived: qsTr("Received") + translationManager.emptyString - delegate: Rectangle { anchors.left: parent.left anchors.right: parent.right - height: 30 * scaleRatio + height: (dropdown.dropdownHeight * 0.75) * scaleRatio //radius: index === repeater.count - 1 ? 4 : 0 color: itemArea.containsMouse || index === column.currentIndex || itemArea.containsMouse ? dropdown.releasedColor : dropdown.pressedColor Text { + id: col1Text anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.right: col2Text.left anchors.leftMargin: 12 * scaleRatio - anchors.rightMargin: column2.length > 0 ? 12 * scaleRatio: 0 - font.family: "Arial" + anchors.rightMargin: 0 + font.family: Style.fontRegular.name font.bold: true - font.pixelSize: 12 * scaleRatio - color: "#FFFFFF" + font.pixelSize: fontItemSize + color: itemArea.containsMouse || index === column.currentIndex || itemArea.containsMouse ? "#FA6800" : "#FFFFFF" text: qsTr(column1) + translationManager.emptyString } @@ -237,10 +195,10 @@ Item { anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right anchors.rightMargin: 45 * scaleRatio - font.family: "Arial" - font.pixelSize: 12 * scaleRatio + font.family: Style.fontRegular.name + font.pixelSize: 14 * scaleRatio color: "#FFFFFF" - text: column2 + text: "" } Rectangle { @@ -261,6 +219,8 @@ Item { id: itemArea anchors.fill: parent hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { dropdown.expanded = false column.currentIndex = index diff --git a/components/Style.qml b/components/Style.qml new file mode 100644 index 00000000..3b917f97 --- /dev/null +++ b/components/Style.qml @@ -0,0 +1,29 @@ +pragma Singleton + +import QtQuick 2.5 + +QtObject { + property QtObject fontMedium: FontLoader { id: _fontMedium; source: "qrc:/fonts/SFUIDisplay-Medium.otf"; } + property QtObject fontBold: FontLoader { id: _fontBold; source: "qrc:/fonts/SFUIDisplay-Bold.otf"; } + property QtObject fontLight: FontLoader { id: _fontLight; source: "qrc:/fonts/SFUIDisplay-Light.otf"; } + property QtObject fontRegular: FontLoader { id: _fontRegular; source: "qrc:/fonts/SFUIDisplay-Regular.otf"; } + + property string grey: "#404040" + + property string defaultFontColor: "white" + property string greyFontColor: "#808080" + property string dimmedFontColor: "#BBBBBB" + property string inputBoxBackground: "black" + property string inputBoxBackgroundError: "#FFDDDD" + property string inputBoxColor: "white" + property string legacy_placeholderFontColor: "#BABABA" + + property string buttonBackgroundColor: "#FA6800" + property string buttonBackgroundColorHover: "#E65E00" + property string buttonBackgroundColorDisabled: "#707070" + property string buttonBackgroundColorDisabledHover: "#808080" + property string buttonTextColor: "white" + property string buttonTextColorDisabled: "black" + property string dividerColor: "white" + property real dividerOpacity: 0.25 +} diff --git a/components/SubaddressTable.qml b/components/SubaddressTable.qml index 8d6b8d1d..811d1199 100644 --- a/components/SubaddressTable.qml +++ b/components/SubaddressTable.qml @@ -28,40 +28,59 @@ import QtQuick 2.0 import moneroComponents.Clipboard 1.0 +import "../components" +import "." 1.0 ListView { id: listView clip: true boundsBehavior: ListView.StopAtBounds highlightMoveDuration: 0 + highlightFollowsCurrentItem: true + anchors.topMargin: 0 + spacing: 0 delegate: Rectangle { id: delegate - height: 64 + height: 80 + color: 'transparent'; + anchors.topMargin: 0 width: listView.width + clip: true - LineEdit { + LineEditMulti { id: addressLine - fontSize: 12 + + fontSize: 14 readOnly: true width: parent.width anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.margins: 5 - onTextChanged: cursorPosition = 0 + anchors.leftMargin: 10 + anchors.topMargin: 12 + anchors.rightMargin: 54 + anchors.bottomMargin: 0 text: address - showBorder: false - IconButton { - id: clipboardButton - imageSource: "../images/copyToClipboard.png" - onClicked: { - console.log(addressLine.text + " copied to clipboard"); - clipboard.setText(addressLine.text); - appWindow.showStatusMessage(qsTr("Address copied to clipboard"),3); - } + showingHeader: false + showBorder: false + addressValidation: false + } + + IconButton { + id: clipboardButton + imageSource: "../images/copyToClipboard.png" + + onClicked: { + console.log(addressLine.text + " copied to clipboard"); + clipboard.setText(addressLine.text); + appWindow.showStatusMessage(qsTr("Address copied to clipboard"),3); } + + anchors.right: parent.right + anchors.rightMargin: 0 + anchors.verticalCenter: parent.verticalCenter } Text { @@ -85,7 +104,7 @@ ListView { font.family: "Arial" font.bold: true font.pixelSize: 12 - color: "#444444" + color: Style.greyFontColor text: label } @@ -96,14 +115,46 @@ ListView { anchors.bottom: parent.bottom anchors.right: parent.right anchors.rightMargin: clipboardButton.width - onClicked: listView.currentIndex = index + cursorShape: Qt.PointingHandCursor + onClicked: { + listView.currentIndex = index; + } + } + + Rectangle { + anchors.left: parent.left + anchors.top: parent.top + anchors.bottom: parent.bottom + width: 1 + color: Style.grey + z: 6 + } + + Rectangle { + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + width: 1 + color: Style.grey + z: 6 + } + + Rectangle { + anchors.right: parent.right + anchors.left: parent.left + anchors.bottom: parent.bottom + color: Style.grey + height: 1 + z: 6 + } + + Rectangle { + width: 3 + color: 'white' + visible: listView.currentIndex == index + anchors.left: parent.left + anchors.top: parent.top + anchors.bottom: parent.bottom } } - - highlight: Rectangle { - height: 64 - color: '#FF4304' - opacity: 0.2 - z: 2 - } } diff --git a/components/TableHeader.qml b/components/TableHeader.qml index d1f1778b..2936599e 100644 --- a/components/TableHeader.qml +++ b/components/TableHeader.qml @@ -36,26 +36,40 @@ Rectangle { property int offset: 0 height: 31 - color: "#FFFFFF" + color: "transparent" + + Rectangle{ + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + width: 1 + color: "#808080" + } + + Rectangle{ + anchors.left: parent.left + anchors.top: parent.top + anchors.bottom: parent.bottom + width: 1 + color: "#808080" + } Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom height: 1 - color: "#DBDBDB" + color: "#808080" } Row { id: row - anchors.horizontalCenter: header.offset !== 0 ? undefined: parent.horizontalCenter - anchors.left: header.offset !== 0 ? parent.left : undefined - anchors.leftMargin: header.offset + anchors.horizontalCenter: parent.horizontalCenter Rectangle { height: 31 width: 1 - color: "#DBDBDB" + color: "#808080" } Repeater { @@ -70,6 +84,7 @@ Rectangle { delegate: Rectangle { id: delegate property bool desc: false + color: "transparent" height: 31 width: columnWidth @@ -86,7 +101,7 @@ Rectangle { color: { if(delegateArea.pressed) return "#FF4304" - return index === header.activeSortColumn || delegateArea.containsMouse ? "#FF6C3C" : "#4A4949" + return index === header.activeSortColumn || delegateArea.containsMouse ? "white" : "#808080" } text: qsTr(columnName) + translationManager.emptyString } @@ -95,6 +110,7 @@ Rectangle { id: delegateArea hoverEnabled: true anchors.fill: parent + cursorShape: Qt.PointingHandCursor onClicked: { delegate.desc = !delegate.desc header.activeSortColumn = index @@ -170,7 +186,7 @@ Rectangle { anchors.right: parent.right anchors.bottom: parent.bottom height: 1 - color: index === header.activeSortColumn ? "#FFFFFF" : "#DBDBDB" + color: "transparent" } Rectangle { @@ -178,7 +194,7 @@ Rectangle { anchors.bottom: parent.bottom anchors.right: parent.right width: 1 - color: "#DBDBDB" + color: "#808080" } } } diff --git a/components/TextBlock.qml b/components/TextBlock.qml index 684b6240..875a4bf7 100644 --- a/components/TextBlock.qml +++ b/components/TextBlock.qml @@ -1,6 +1,10 @@ import QtQuick 2.0 +import "." 1.0 + TextEdit { + color: Style.defaultFontColor + font.family: Style.fontRegular.name wrapMode: Text.Wrap readOnly: true selectByMouse: true diff --git a/components/TickDelegate.qml b/components/TickDelegate.qml index f7c14eaf..94ead579 100644 --- a/components/TickDelegate.qml +++ b/components/TickDelegate.qml @@ -27,6 +27,8 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 +import "." 1.0 + Item { id: delegateItem @@ -50,7 +52,7 @@ Item { font.family: "Arial" font.bold: true font.pixelSize: 12 * scaleRatio - color: "#4A4949" + color: Style.defaultFontColor text: { if(currentIndex === 0) return qsTr("Default") + translationManager.emptyString if(currentIndex === 13) return qsTr("High") + translationManager.emptyString diff --git a/components/TitleBar.qml b/components/TitleBar.qml index 2a2ae575..a6dfaadf 100644 --- a/components/TitleBar.qml +++ b/components/TitleBar.qml @@ -32,50 +32,78 @@ import QtQuick.Layouts 1.1 Rectangle { id: titleBar - color: "#000000" + property int mouseX: 0 property bool containsMouse: false property alias basicButtonVisible: goToBasicVersionButton.visible property bool customDecorations: true signal goToBasicVersion(bool yes) - height: customDecorations && !isMobile ? 30 : 0 + height: customDecorations && !isMobile ? 50 : 0 y: -height property string title property alias maximizeButtonVisible: maximizeButton.visible z: 1 - Text { - anchors.centerIn: parent - font.family: "Arial" - font.pixelSize: 15 - color: "#FFFFFF" - text: titleBar.title - visible: customDecorations + Item { + id: test + width: parent.width + height: 50 + z: 1 + + // use jpg for gradiency + Image { + anchors.fill: parent + height: parent.height + width: parent.width + source: "../images/titlebarGradient.jpg" + } } - Rectangle { + Item{ + id: titlebarlogo + width: 125 + height: 50 + anchors.centerIn: parent + visible: customDecorations + z: 1 + Image { + anchors.left: parent.left + anchors.top: parent.top + anchors.topMargin: 11 + width: 125 + height: 28 + source: "../images/titlebarLogo.png" + } + } + + // collapse left panel + Rectangle { id: goToBasicVersionButton property bool containsMouse: titleBar.mouseX >= x && titleBar.mouseX <= x + width property bool checked: false anchors.top: parent.top anchors.left: parent.left - color: "#FFE00A" - height: 30 * scaleRatio + color: "transparent" + height: 50 * scaleRatio width: height visible: isMobile + z: 2 Image { - width: parent.width * 2/3; - height: width; + width: 14 + height: 14 anchors.centerIn: parent - source: "../images/menu.png" + source: "../images/expand.png" } MouseArea { id: basicMouseArea hoverEnabled: true anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onEntered: goToBasicVersionButton.color = "#262626"; + onExited: goToBasicVersionButton.color = "transparent"; onClicked: { releaseFocus() parent.checked = !parent.checked @@ -90,22 +118,28 @@ Rectangle { anchors.top: parent.top anchors.bottom: parent.bottom visible: parent.customDecorations + z: 2 Rectangle { - property bool containsMouse: titleBar.mouseX >= x + row.x && titleBar.mouseX <= x + row.x + width && titleBar.containsMouse + id: whatIsAreaButton anchors.top: parent.top anchors.bottom: parent.bottom - width: height - color: containsMouse ? "#6B0072" : "#000000" + width: 42 + color: containsMouse ? "#6B0072" : "#00000000" Image { anchors.centerIn: parent - source: "../images/helpIcon.png" + width: 9 + height: 16 + source: "../images/question.png" } MouseArea { id: whatIsArea anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onEntered: whatIsAreaButton.color = "#262626"; + onExited: whatIsAreaButton.color = "transparent"; onClicked: { } @@ -113,20 +147,24 @@ Rectangle { } Rectangle { - property bool containsMouse: titleBar.mouseX >= x + row.x && titleBar.mouseX <= x + row.x + width && titleBar.containsMouse + id: minimizeButton anchors.top: parent.top anchors.bottom: parent.bottom - width: height - color: containsMouse ? "#3665B3" : "#000000" + width: 42 + color: "transparent" Image { anchors.centerIn: parent - source: "../images/minimizeIcon.png" + source: "../images/minimize.png" } MouseArea { id: minimizeArea anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onEntered: minimizeButton.color = "#262626"; + onExited: minimizeButton.color = "transparent"; onClicked: { appWindow.visibility = Window.Minimized } @@ -135,22 +173,26 @@ Rectangle { Rectangle { id: maximizeButton - property bool containsMouse: titleBar.mouseX >= x + row.x && titleBar.mouseX <= x + row.x + width && titleBar.containsMouse anchors.top: parent.top anchors.bottom: parent.bottom - width: height - color: containsMouse ? "#FF6C3C" : "#000000" + width: 42 + color: "transparent"; Image { anchors.centerIn: parent + height: 16 + width: 16 source: appWindow.visibility === Window.FullScreen ? "../images/backToWindowIcon.png" : - "../images/maximizeIcon.png" - + "../images/fullscreen.png" } MouseArea { id: maximizeArea anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onEntered: maximizeButton.color = "#262626"; + onExited: maximizeButton.color = "transparent"; onClicked: { appWindow.visibility = appWindow.visibility !== Window.FullScreen ? Window.FullScreen : Window.Windowed @@ -159,20 +201,26 @@ Rectangle { } Rectangle { - property bool containsMouse: titleBar.mouseX >= x + row.x && titleBar.mouseX <= x + row.x + width && titleBar.containsMouse + id: closeButton anchors.top: parent.top anchors.bottom: parent.bottom - width: height - color: containsMouse ? "#E04343" : "#000000" + width: 42 + color: containsMouse ? "#E04343" : "#00000000" Image { anchors.centerIn: parent - source: "../images/closeIcon.png" + width: 16 + height: 16 + source: "../images/close.png" } MouseArea { anchors.fill: parent onClicked: appWindow.close(); + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onEntered: closeButton.color = "#262626"; + onExited: closeButton.color = "transparent"; } } } diff --git a/components/qmldir b/components/qmldir new file mode 100644 index 00000000..81984227 --- /dev/null +++ b/components/qmldir @@ -0,0 +1 @@ +singleton Style 1.0 Style.qml diff --git a/fonts/SFUIDisplay-Bold.otf b/fonts/SFUIDisplay-Bold.otf new file mode 100644 index 00000000..87827d53 Binary files /dev/null and b/fonts/SFUIDisplay-Bold.otf differ diff --git a/fonts/SFUIDisplay-Light.otf b/fonts/SFUIDisplay-Light.otf new file mode 100644 index 00000000..b1879c03 Binary files /dev/null and b/fonts/SFUIDisplay-Light.otf differ diff --git a/fonts/SFUIDisplay-Medium.otf b/fonts/SFUIDisplay-Medium.otf new file mode 100644 index 00000000..25d1a647 Binary files /dev/null and b/fonts/SFUIDisplay-Medium.otf differ diff --git a/fonts/SFUIDisplay-Regular.otf b/fonts/SFUIDisplay-Regular.otf new file mode 100644 index 00000000..b644ea11 Binary files /dev/null and b/fonts/SFUIDisplay-Regular.otf differ diff --git a/images/arrow-right-medium-white.png b/images/arrow-right-medium-white.png new file mode 100644 index 00000000..f33e9f41 Binary files /dev/null and b/images/arrow-right-medium-white.png differ diff --git a/images/card-background.png b/images/card-background.png new file mode 100644 index 00000000..c049e7b0 Binary files /dev/null and b/images/card-background.png differ diff --git a/images/checkedBlackIcon.png b/images/checkedBlackIcon.png new file mode 100755 index 00000000..d73b70bf Binary files /dev/null and b/images/checkedBlackIcon.png differ diff --git a/images/checkedIcon-black.png b/images/checkedIcon-black.png new file mode 100755 index 00000000..a1c5a1f4 Binary files /dev/null and b/images/checkedIcon-black.png differ diff --git a/images/close.png b/images/close.png new file mode 100644 index 00000000..c9e47a66 Binary files /dev/null and b/images/close.png differ diff --git a/images/downArrow.png b/images/downArrow.png new file mode 100644 index 00000000..3e03d314 Binary files /dev/null and b/images/downArrow.png differ diff --git a/images/expand.png b/images/expand.png new file mode 100644 index 00000000..88ed69c7 Binary files /dev/null and b/images/expand.png differ diff --git a/images/fullscreen.png b/images/fullscreen.png new file mode 100644 index 00000000..d54ba6ba Binary files /dev/null and b/images/fullscreen.png differ diff --git a/images/historyBorderRadius.png b/images/historyBorderRadius.png new file mode 100755 index 00000000..ee86e191 Binary files /dev/null and b/images/historyBorderRadius.png differ diff --git a/images/leftPanelBg.jpg b/images/leftPanelBg.jpg new file mode 100644 index 00000000..ec8c06eb Binary files /dev/null and b/images/leftPanelBg.jpg differ diff --git a/images/lightning-white.png b/images/lightning-white.png new file mode 100644 index 00000000..ae1d6fc9 Binary files /dev/null and b/images/lightning-white.png differ diff --git a/images/lightning.png b/images/lightning.png new file mode 100644 index 00000000..36d55fb8 Binary files /dev/null and b/images/lightning.png differ diff --git a/images/menuArrow.png b/images/menuArrow.png new file mode 100755 index 00000000..6443f794 Binary files /dev/null and b/images/menuArrow.png differ diff --git a/images/menuButtonGradient.png b/images/menuButtonGradient.png new file mode 100644 index 00000000..caeaf946 Binary files /dev/null and b/images/menuButtonGradient.png differ diff --git a/images/middlePanelBg.jpg b/images/middlePanelBg.jpg new file mode 100644 index 00000000..9957f58e Binary files /dev/null and b/images/middlePanelBg.jpg differ diff --git a/images/minimize.png b/images/minimize.png new file mode 100644 index 00000000..f0f59144 Binary files /dev/null and b/images/minimize.png differ diff --git a/images/moneroIcon-28x28.png b/images/moneroIcon-28x28.png new file mode 100644 index 00000000..4ef14fd1 Binary files /dev/null and b/images/moneroIcon-28x28.png differ diff --git a/images/moneroIcon-trans28x28.png b/images/moneroIcon-trans28x28.png new file mode 100644 index 00000000..61092193 Binary files /dev/null and b/images/moneroIcon-trans28x28.png differ diff --git a/images/moneroIcon-trans56x56.png b/images/moneroIcon-trans56x56.png new file mode 100644 index 00000000..84bcad31 Binary files /dev/null and b/images/moneroIcon-trans56x56.png differ diff --git a/images/moneroIcon-trans84x84.png b/images/moneroIcon-trans84x84.png new file mode 100644 index 00000000..1118a724 Binary files /dev/null and b/images/moneroIcon-trans84x84.png differ diff --git a/images/moneroLogo_white.png b/images/moneroLogo_white.png new file mode 100644 index 00000000..ba4e1438 Binary files /dev/null and b/images/moneroLogo_white.png differ diff --git a/images/question.png b/images/question.png new file mode 100644 index 00000000..79b4d3bc Binary files /dev/null and b/images/question.png differ diff --git a/images/right.png b/images/right.png new file mode 100644 index 00000000..d465fe5c Binary files /dev/null and b/images/right.png differ diff --git a/images/rightArrow.png b/images/rightArrow.png new file mode 100644 index 00000000..2dd60c5d Binary files /dev/null and b/images/rightArrow.png differ diff --git a/images/titlebarGradient.jpg b/images/titlebarGradient.jpg new file mode 100644 index 00000000..c89cf220 Binary files /dev/null and b/images/titlebarGradient.jpg differ diff --git a/images/titlebarLogo.png b/images/titlebarLogo.png new file mode 100644 index 00000000..8ea3ae95 Binary files /dev/null and b/images/titlebarLogo.png differ diff --git a/images/upArrow-green.png b/images/upArrow-green.png new file mode 100644 index 00000000..5438a4d8 Binary files /dev/null and b/images/upArrow-green.png differ diff --git a/images/warning.png b/images/warning.png new file mode 100755 index 00000000..8036d84a Binary files /dev/null and b/images/warning.png differ diff --git a/js/TxUtils.js b/js/TxUtils.js new file mode 100644 index 00000000..4a4b01c4 --- /dev/null +++ b/js/TxUtils.js @@ -0,0 +1,57 @@ +function destinationsToAmount(destinations){ + // Gets amount from destinations line + // input: "20.000000000000: 9tLGyK277MnYrDc7Vzi6TB1pJvstFoviziFwsqQNFbwA9rvg5RxYVYjEezFKDjvDHgAzTELJhJHVx6JAaWZKeVqSUZkXeKk" + // returns: 20.000000000000 + return destinations.split(" ")[0].split(":")[0]; +} + +function destinationsToAddress(destinations){ + var address = destinations.split(" ")[1]; + if(address === undefined) return "" + return address; +} + +function addressTruncate(address){ + return address.substring(0, 6) + "..." + address.substring(address.length-6); +} + +function check256(str, length) { + if (str.length != length) + return false; + for (var i = 0; i < length; ++i) { + if (str[i] >= '0' && str[i] <= '9') + continue; + if (str[i] >= 'a' && str[i] <= 'z') + continue; + if (str[i] >= 'A' && str[i] <= 'Z') + continue; + return false; + } + return true; +} + +function checkAddress(address, testnet) { + return walletManager.addressValid(address, testnet) +} + +function checkTxID(txid) { + return check256(txid, 64) +} + +function checkSignature(signature) { + if (signature.indexOf("OutProofV") === 0) { + if ((signature.length - 10) % 132 != 0) + return false; + return check256(signature, signature.length); + } else if (signature.indexOf("InProofV") === 0) { + if ((signature.length - 9) % 132 != 0) + return false; + return check256(signature, signature.length); + } else if (signature.indexOf("SpendProofV") === 0) { + if ((signature.length - 12) % 88 != 0) + return false; + return check256(signature, signature.length); + } + return false; +} + diff --git a/main.qml b/main.qml index f8c6af06..4efbe71d 100644 --- a/main.qml +++ b/main.qml @@ -73,7 +73,7 @@ ApplicationWindow { property bool remoteNodeConnected: false property bool androidCloseTapped: false; // Default daemon addresses - readonly property string localDaemonAddress : persistentSettings.nettype === NetworkType.MAINNET ? "localhost:18081" : persistentSettings.nettype === NetworkType.TESTNET ? "localhost:28081" : "localhost:38081" + readonly property string localDaemonAddress : persistentSettings.nettype == NetworkType.MAINNET ? "localhost:18081" : persistentSettings.nettype == NetworkType.TESTNET ? "localhost:28081" : "localhost:38081" property string currentDaemonAddress; property bool startLocalNodeCancelled: false @@ -232,12 +232,15 @@ ApplicationWindow { if(isIOS) wallet_path = moneroAccountsDir + wallet_path; // console.log("opening wallet at: ", wallet_path, "with password: ", appWindow.walletPassword); - console.log("opening wallet at: ", wallet_path, ", network type: ", persistentSettings.nettype === NetworkType.MAINNET ? "mainnet" : persistentSettings.nettype === NetworkType.TESTNET ? "testnet" : "stagenet"); + console.log("opening wallet at: ", wallet_path, ", network type: ", persistentSettings.nettype == NetworkType.MAINNET ? "mainnet" : persistentSettings.nettype == NetworkType.TESTNET ? "testnet" : "stagenet"); walletManager.openWalletAsync(wallet_path, walletPassword, persistentSettings.nettype); } + // Hide titlebar based on persistentSettings.customDecorations + titleBar.visible = persistentSettings.customDecorations; } + function closeWallet() { // Disconnect all listeners @@ -263,6 +266,28 @@ ApplicationWindow { function connectWallet(wallet) { currentWallet = wallet + + // TODO: + // When the wallet variable is undefined, it yields a zero balance. + // This can scare users, restart the GUI (as a quick fix). + // + // To reproduce, follow these steps: + // 1) Open the GUI, load up a wallet that has a balance + // 2) Settings -> close wallet + // 3) Create a new wallet + // 4) Settings -> close wallet + // 5) Open the wallet from step 1 + + if(!wallet || wallet === undefined || wallet.path === undefined){ + informationPopup.title = qsTr("Error") + translationManager.emptyString; + informationPopup.text = qsTr("Couldn't open wallet: ") + 'please restart GUI.'; + informationPopup.icon = StandardIcon.Critical + informationPopup.open() + informationPopup.onCloseCallback = function() { + appWindow.close(); + } + } + walletName = usefulName(wallet.path) updateSyncing(false) @@ -539,7 +564,7 @@ ApplicationWindow { function onWalletMoneySent(txId, amount) { // refresh transaction history here - console.log("money sent found") + console.log("monero sent found") currentWallet.refresh() currentWallet.history.refresh(currentWallet.currentSubaddressAccount) // this will refresh model } @@ -585,11 +610,8 @@ ApplicationWindow { + ", fee: " + walletManager.displayAmount(transaction.fee)); // here we show confirmation popup; - - transactionConfirmationPopup.title = qsTr("Confirmation") + translationManager.emptyString - transactionConfirmationPopup.text = qsTr("Please confirm transaction:\n"); - for (var i = 0; i < transaction.subaddrIndices.length; ++i) - transactionConfirmationPopup.text += qsTr("\nSpending address index: ") + transaction.subaddrIndices[i] + transactionConfirmationPopup.title = qsTr("Please confirm transaction:\n") + translationManager.emptyString; + transactionConfirmationPopup.text = ""; transactionConfirmationPopup.text += (address === "" ? "" : (qsTr("\n\nAddress: ") + address)) + (paymentId === "" ? "" : (qsTr("\nPayment ID: ") + paymentId)) @@ -598,7 +620,12 @@ ApplicationWindow { + qsTr("\n\nRingsize: ") + (mixinCount + 1) + qsTr("\n\Number of transactions: ") + transaction.txCount + (transactionDescription === "" ? "" : (qsTr("\n\nDescription: ") + transactionDescription)) - + translationManager.emptyString + + for (var i = 0; i < transaction.subaddrIndices.length; ++i){ + transactionConfirmationPopup.text += qsTr("\nSpending address index: ") + transaction.subaddrIndices[i]; + } + + transactionConfirmationPopup.text += translationManager.emptyString; transactionConfirmationPopup.icon = StandardIcon.Question transactionConfirmationPopup.open() } @@ -751,7 +778,7 @@ ApplicationWindow { txid_text += ", " txid_text += txid[i] } - informationPopup.text = (viewOnly)? qsTr("Transaction saved to file: %1").arg(path) : qsTr("Money sent successfully: %1 transaction(s) ").arg(txid.length) + txid_text + translationManager.emptyString + informationPopup.text = (viewOnly)? qsTr("Transaction saved to file: %1").arg(path) : qsTr("Monero sent successfully: %1 transaction(s) ").arg(txid.length) + txid_text + translationManager.emptyString informationPopup.icon = StandardIcon.Information if (transactionDescription.length > 0) { for (var i = 0; i < txid.length; ++i) @@ -911,11 +938,14 @@ ApplicationWindow { x = 0 if (y < 0) y = 0 - persistentSettings.customDecorations = custom + persistentSettings.customDecorations = custom; + titleBar.visible = custom; // hides custom titlebar based on customDecorations + if (custom) - appWindow.flags = Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint + appWindow.flags = Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint; else - appWindow.flags = Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint | Qt.WindowTitleHint | Qt.WindowMaximizeButtonHint + appWindow.flags = Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint | Qt.WindowTitleHint | Qt.WindowMaximizeButtonHint; + appWindow.hide() appWindow.x = x appWindow.y = y @@ -988,7 +1018,7 @@ ApplicationWindow { property bool allow_background_mining : false property bool miningIgnoreBattery : true property var nettype: NetworkType.MAINNET - property string daemon_address: nettype === NetworkType.TESTNET ? "localhost:28081" : nettype === NetworkType.STAGENET ? "localhost:38081" : "localhost:18081" + property string daemon_address: nettype == NetworkType.TESTNET ? "localhost:28081" : nettype == NetworkType.STAGENET ? "localhost:38081" : "localhost:18081" property string payment_id property int restore_height : 0 property bool is_recovering : false @@ -1533,6 +1563,15 @@ ApplicationWindow { } } } + + Rectangle { + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.left: parent.left + height:1 + color: "#2F2F2F" + z: 2 + } } // new ToolTip diff --git a/monero-wallet-gui.pro b/monero-wallet-gui.pro index 61732a26..50d3e0e0 100644 --- a/monero-wallet-gui.pro +++ b/monero-wallet-gui.pro @@ -276,6 +276,7 @@ linux { -lboost_chrono \ -lboost_program_options \ -lssl \ + -llmdb \ -lcrypto if(!android) { diff --git a/pages/AddressBook.qml b/pages/AddressBook.qml index 4b406af8..68598dc4 100644 --- a/pages/AddressBook.qml +++ b/pages/AddressBook.qml @@ -34,30 +34,21 @@ import moneroComponents.AddressBookModel 1.0 Rectangle { id: root - color: "#F0EEEE" + color: "transparent" property var model ColumnLayout { - anchors.margins: 17 * scaleRatio + id: columnLayout + anchors.margins: (isMobile)? 17 : 40 anchors.left: parent.left anchors.top: parent.top anchors.right: parent.right - spacing: 10 * scaleRatio - - Label { - id: addressLabel - anchors.left: parent.left - text: qsTr("Address") + translationManager.emptyString - } + spacing: 26 * scaleRatio RowLayout { StandardButton { id: qrfinderButton text: qsTr("Qr Code") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" visible : appWindow.qrScannerEnabled enabled : visible width: visible ? 60 * scaleRatio : 0 @@ -70,32 +61,25 @@ Rectangle { LineEdit { Layout.fillWidth: true; id: addressLine + labelText: qsTr("Address") + translationManager.emptyString error: true; placeholderText: qsTr("4...") + translationManager.emptyString } } - Label { - id: paymentIdLabel - text: qsTr("Payment ID (Optional)") + translationManager.emptyString - tipText: qsTr("Payment ID

A unique user name used in
the address book. It is not a
transfer of information sent
during the transfer") - + translationManager.emptyString - } - LineEdit { id: paymentIdLine Layout.fillWidth: true; + labelText: qsTr("Payment ID (Optional)") + translationManager.emptyString placeholderText: qsTr("Paste 64 hexadecimal characters") + translationManager.emptyString - } - - Label { - id: descriptionLabel - text: qsTr("Description (Optional)") + translationManager.emptyString +// tipText: qsTr("Payment ID

A unique user name used in
the address book. It is not a
transfer of information sent
during the transfer") +// + translationManager.emptyString } LineEdit { id: descriptionLine Layout.fillWidth: true; + labelText: qsTr("Description (Optional)") + translationManager.emptyString placeholderText: qsTr("Give this entry a name or description") + translationManager.emptyString } @@ -104,10 +88,6 @@ Rectangle { id: addButton Layout.bottomMargin: 17 * scaleRatio StandardButton { - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" text: qsTr("Add") + translationManager.emptyString enabled: checkInformation(addressLine.text, paymentIdLine.text, appWindow.persistentSettings.nettype) @@ -132,29 +112,23 @@ Rectangle { } } } - } Rectangle { id: tableRect + anchors.top: columnLayout.bottom + anchors.leftMargin: (isMobile)? 17 : 40 + anchors.rightMargin: (isMobile)? 17 : 40 anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom height: parent.height - addButton.y - addButton.height - 36 * scaleRatio - color: "#FFFFFF" + color: "transparent" Behavior on height { NumberAnimation { duration: 200; easing.type: Easing.InQuad } } - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: 1 - color: "#DBDBDB" - } - Scroll { id: flickableScroll anchors.right: table.right @@ -170,8 +144,6 @@ Rectangle { anchors.right: parent.right anchors.top: parent.top anchors.bottom: parent.bottom - anchors.leftMargin: 14 - anchors.rightMargin: 14 onContentYChanged: flickableScroll.flickableContentYChanged() model: root.model } diff --git a/pages/History.qml b/pages/History.qml index 5ea27ca7..f9855189 100644 --- a/pages/History.qml +++ b/pages/History.qml @@ -27,7 +27,8 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 - +import QtQuick.Layouts 1.1 +import QtQuick.Dialogs 1.2 import moneroComponents.Wallet 1.0 import moneroComponents.WalletManager 1.0 import moneroComponents.TransactionHistory 1.0 @@ -37,15 +38,16 @@ import moneroComponents.TransactionHistoryModel 1.0 import "../components" Rectangle { - id: root + id: mainLayout property var model + property int tableHeight: !isMobile ? table.contentHeight : tableMobile.contentHeight QtObject { id: d property bool initialized: false } - color: "#F0EEEE" + color: "transparent" function getSelectedAmount() { if (typeof model === 'undefined' || model == null) @@ -81,182 +83,25 @@ Rectangle { onModelChanged: { if (typeof model !== 'undefined' && model != null) { - - selectedAmount.text = getSelectedAmount() - if (!d.initialized) { // setup date filter scope according to real transactions fromDatePicker.currentDate = model.transactionHistory.firstDateTime toDatePicker.currentDate = model.transactionHistory.lastDateTime - /* Default sorting by timestamp desc */ - /* Sort indicator on table header */ - /* index of 'sort by blockheight' column */ - header.activeSortColumn = 2 - /* Sorting model */ - model.sortRole = TransactionHistoryModel.TransactionBlockHeightRole model.sort(0, Qt.DescendingOrder); d.initialized = true - // TODO: public interface for 'Header' item that will cause 'sortRequest' signal } - } } function onFilterChanged() { + // set datepicker error states var datesValid = fromDatePicker.currentDate <= toDatePicker.currentDate - var amountsValid = amountFromLine.text === "" ? true : - amountToLine.text === "" ? true: - parseFloat(amountFromLine.text) <= parseFloat(amountToLine.text) - - // reset error state if amount filter valid - if (amountsValid) { - amountFromLine.error = amountToLine.error = false - } - - filterButton.enabled = datesValid && amountsValid - } - - - Text { - visible: !isMobile - id: filterHeaderText - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.leftMargin: 17 - anchors.topMargin: 17 - - elide: Text.ElideRight - font.family: "Arial" - font.pixelSize: 18 - color: "#4A4949" - text: qsTr("Filter transaction history") + translationManager.emptyString - } - - Label { - visible: !isMobile - id: selectedAmount - anchors.right: parent.right - anchors.top: parent.top - anchors.rightMargin: 17 - anchors.topMargin: 17 - text: getSelectedAmount() - fontSize: 14 - } - - // Filter by string - LineEdit { - visible: !isMobile - id: searchLine - anchors.left: parent.left - anchors.right: parent.right - anchors.top: filterHeaderText.bottom - anchors.leftMargin: 17 - anchors.rightMargin: 17 - anchors.topMargin: 5 - placeholderText: qsTr("Type for incremental search...") + translationManager.emptyString - onTextChanged: { - model.searchFilter = searchLine.text - selectedAmount.text = getSelectedAmount() - } - } - - // Filter by description input (not implemented yet) - /* - Label { - id: descriptionLabel - anchors.left: parent.left - anchors.top: searchLine.bottom - anchors.leftMargin: 17 - anchors.topMargin: 17 - text: qsTr("Description (Local database)") + translationManager.emptyString - fontSize: 14 - } - - LineEdit { - id: descriptionLine - anchors.left: parent.left - anchors.right: parent.right - anchors.top: descriptionLabel.bottom - anchors.leftMargin: 17 - anchors.rightMargin: 17 - anchors.topMargin: 5 - } - */ - - - // DateFrom picker - Label { - visible: !isMobile - id: dateFromText - anchors.left: parent.left - anchors.top: searchLine.bottom // descriptionLine.bottom - anchors.leftMargin: 17 - anchors.topMargin: 17 - width: 156 - text: qsTr("Date from") + translationManager.emptyString - fontSize: 14 - } - - DatePicker { - visible: !isMobile - id: fromDatePicker - anchors.left: parent.left - anchors.top: dateFromText.bottom - anchors.leftMargin: 17 - anchors.topMargin: 5 - z: 2 - onCurrentDateChanged: { - error = currentDate > toDatePicker.currentDate - onFilterChanged() - } - } - - // DateTo picker - Label { - visible: !isMobile - id: dateToText - anchors.left: dateFromText.right - anchors.top: searchLine.bottom //descriptionLine.bottom - anchors.leftMargin: 17 - anchors.topMargin: 17 - text: qsTr("To") + translationManager.emptyString - fontSize: 14 - } - - DatePicker { - visible: !isMobile - id: toDatePicker - anchors.left: fromDatePicker.right - anchors.top: dateToText.bottom - anchors.leftMargin: 17 - anchors.topMargin: 5 - z: 2 - onCurrentDateChanged: { - error = currentDate < fromDatePicker.currentDate - onFilterChanged() - } - } - - - - StandardButton { - visible: !isMobile - id: filterButton - anchors.bottom: toDatePicker.bottom - anchors.left: toDatePicker.right - anchors.leftMargin: 17 - width: 60 - text: qsTr("Filter") + translationManager.emptyString - shadowReleasedColor: "#4D0051" - shadowPressedColor: "#2D002F" - releasedColor: "#6B0072" - pressedColor: "#4D0051" - onClicked: { - // Apply filter here; + fromDatePicker.error = !datesValid; + toDatePicker.error = !datesValid; + if(datesValid){ resetFilter(model) if (fromDatePicker.currentDate > toDatePicker.currentDate) { @@ -266,281 +111,254 @@ Rectangle { model.dateToFilter = toDatePicker.currentDate } - if (advancedFilteringCheckBox.checked) { - if (amountFromLine.text.length) { - model.amountFromFilter = parseFloat(amountFromLine.text) - } - - if (amountToLine.text.length) { - model.amountToFilter = parseFloat(amountToLine.text) - } - - var directionFilter = transactionsModel.get(transactionTypeDropdown.currentIndex).value - console.log("Direction filter: " + directionFilter) - model.directionFilter = directionFilter - } - - selectedAmount.text = getSelectedAmount() + model.searchFilter = searchLine.text; + tableHeader.visible = model.rowCount() > 0; } } - CheckBox { - visible: !isMobile - id: advancedFilteringCheckBox - text: qsTr("Advanced filtering") + translationManager.emptyString - anchors.left: filterButton.right - anchors.bottom: filterButton.bottom - anchors.leftMargin: 17 - checkedIcon: "../images/checkedVioletIcon.png" - uncheckedIcon: "../images/uncheckedIcon.png" - onClicked: { - if(checked) tableRect.height = Qt.binding(function(){ return tableRect.collapsedHeight }) - else tableRect.height = Qt.binding(function(){ return tableRect.middleHeight }) - } + Rectangle{ + id: rootLayout + visible: false } - Label { - visible: !isMobile - id: transactionTypeText + ColumnLayout { + id: pageRoot + anchors.margins: isMobile ? 17 : 20 * scaleRatio + anchors.topMargin: isMobile ? 0 : 40 * scaleRatio + anchors.left: parent.left - anchors.top: fromDatePicker.bottom - anchors.leftMargin: 17 - anchors.topMargin: 17 - width: 156 - text: qsTr("Type of transaction") + translationManager.emptyString - fontSize: 14 - } - - ListModel { - id: transactionsModel - ListElement { column1: "All"; column2: ""; value: TransactionInfo.Direction_Both } - ListElement { column1: "Sent"; column2: ""; value: TransactionInfo.Direction_Out } - ListElement { column1: "Received"; column2: ""; value: TransactionInfo.Direction_In } - - } - - StandardDropdown { - visible: !isMobile - id: transactionTypeDropdown - anchors.left: parent.left - anchors.top: transactionTypeText.bottom - anchors.leftMargin: 17 - anchors.topMargin: 5 - width: 156 - shadowReleasedColor: "#4D0051" - shadowPressedColor: "#2D002F" - releasedColor: "#6B0072" - pressedColor: "#4D0051" - dataModel: transactionsModel - z: 1 - } - - Label { - visible: !isMobile - id: amountFromText - anchors.left: transactionTypeText.right - anchors.top: fromDatePicker.bottom - anchors.leftMargin: 17 - anchors.topMargin: 17 - width: 156 - text: qsTr("Amount from") + translationManager.emptyString - fontSize: 14 - } - - LineEdit { - visible: !isMobile - id: amountFromLine - anchors.left: transactionTypeDropdown.right - anchors.top: amountFromText.bottom - anchors.leftMargin: 17 - anchors.topMargin: 5 - width: 156 - validator: DoubleValidator { - locale: "C" - notation: DoubleValidator.StandardNotation - bottom: 0 - } - onTextChanged: { - // indicating error - amountFromLine.error = amountFromLine.text === "" ? false : parseFloat(amountFromLine.text) > parseFloat(amountToLine.text) - onFilterChanged() - } - - } - - Label { - visible: !isMobile - id: amountToText - anchors.left: amountFromText.right - anchors.top: fromDatePicker.bottom - anchors.leftMargin: 17 - anchors.topMargin: 17 - width: 156 - text: qsTr("To") + translationManager.emptyString - fontSize: 14 - } - - LineEdit { - visible: !isMobile - id: amountToLine - anchors.left: amountFromLine.right - anchors.top: amountToText.bottom - anchors.leftMargin: 17 - anchors.topMargin: 5 - width: 156 - validator: DoubleValidator { - locale: "C" - notation: DoubleValidator.StandardNotation - bottom: 0.0 - } - - onTextChanged: { - // indicating error - amountToLine.error = amountToLine.text === "" ? false : parseFloat(amountFromLine.text) > parseFloat(amountToLine.text) - onFilterChanged() - } - - } - - Item { - visible: !isMobile - id: expandItem - property bool expanded: false - + anchors.top: parent.top anchors.right: parent.right - anchors.bottom: tableRect.top - width: 34 - height: 34 - Image { - anchors.centerIn: parent - source: "../images/expandTable.png" - rotation: parent.expanded ? 180 : 0 - } + spacing: 0 - MouseArea { - anchors.fill: parent - onClicked: { - parent.expanded = !parent.expanded - if (advancedFilteringCheckBox.checked) { - tableRect.height = Qt.binding(function() { return parent.expanded ? tableRect.expandedHeight : tableRect.collapsedHeight }) + GridLayout { + property int column_width: { + if(!isMobile){ + return (parent.width / 2) - 20; } else { - tableRect.height = Qt.binding(function() { return parent.expanded ? tableRect.expandedHeight : tableRect.middleHeight }) + return parent.width - 20; + } + } + + columns: 2 + Layout.fillWidth: true + + RowLayout { + visible: !isMobile + Layout.preferredWidth: parent.column_width + } + + RowLayout { + Layout.preferredWidth: parent.column_width + LineEdit { + id: searchLine + fontSize: 14 * scaleRatio + inputHeight: 28 * scaleRatio + borderDisabled: true + Layout.fillWidth: true + backgroundColor: "#404040" + placeholderText: qsTr("Search") + translationManager.emptyString + placeholderCenter: true + onTextChanged: { + onFilterChanged(); + } } } } - } - Rectangle { - id: tableRect - property int expandedHeight: parent.height - filterHeaderText.y - filterHeaderText.height - 5 - property int middleHeight: parent.height - fromDatePicker.y - fromDatePicker.height - 17 - property int collapsedHeight: parent.height - transactionTypeDropdown.y - transactionTypeDropdown.height - 17 - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom -// anchors.top: parent.top - color: "#FFFFFF" - z: 1 - - height: (isMobile)? parent.height : middleHeight - onHeightChanged: { - if(height === middleHeight) z = 1 - else if(height === collapsedHeight) z = 0 - else z = 3 - } - - Behavior on height { - NumberAnimation { duration: 200; easing.type: Easing.InQuad } - } - - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: 1 - color: "#DBDBDB" - } - - ListModel { - id: columnsModel - property int pidWidth: 127 * scaleRatio - ListElement { columnName: "Payment ID"; columnWidth: 127 } - ListElement { columnName: "Date"; columnWidth: 100 } - ListElement { columnName: "Block height"; columnWidth: 150 } - ListElement { columnName: "Amount"; columnWidth: 148 } - // ListElement { columnName: "Description"; columnWidth: 148 } - } - - TableHeader { - id: header + GridLayout { + z: 6 + columns: (isMobile)? 1 : 3 + Layout.fillWidth: true + columnSpacing: 22 * scaleRatio visible: !isMobile - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.topMargin: 17 * scaleRatio - anchors.leftMargin: 14 * scaleRatio - anchors.rightMargin: 14 * scaleRatio - dataModel: columnsModel - offset: 20 - onSortRequest: { - console.log("column: " + column + " desc: " + desc) - switch (column) { - case 0: - // Payment ID - model.sortRole = TransactionHistoryModel.TransactionPaymentIdRole - break; - case 1: - // Date (actually sort by timestamp as we want to have transactions sorted within one day as well); - model.sortRole = TransactionHistoryModel.TransactionTimeStampRole - break; - case 2: - // BlockHeight; - model.sortRole = TransactionHistoryModel.TransactionBlockHeightRole - break; - case 3: - // Amount; - model.sortRole = TransactionHistoryModel.TransactionAmountRole - break; + + ColumnLayout { + Layout.fillWidth: true + + RowLayout { + Layout.fillWidth: true + id: fromDateRow + Layout.minimumWidth: 150 * scaleRatio + + DatePicker { + visible: !isMobile + + id: fromDatePicker + Layout.fillWidth: true + width: 100 * scaleRatio + inputLabel.text: "Date from" + + onCurrentDateChanged: { + onFilterChanged() + } + } + } + } + + ColumnLayout { + Layout.fillWidth: true + + RowLayout { + Layout.fillWidth: true + id: toDateRow + Layout.minimumWidth: 150 * scaleRatio + + DatePicker { + visible: !isMobile + + id: toDatePicker + Layout.fillWidth: true + width: 100 * scaleRatio + inputLabel.text: "Date to" + + onCurrentDateChanged: { + onFilterChanged() + } + } + } + } + + ColumnLayout { + Layout.fillWidth: true + + Label { + id: transactionPriority + Layout.minimumWidth: 120 * scaleRatio + text: qsTr("Sort") + translationManager.emptyString + fontSize: 14 + } + + ListModel { + id: priorityModelV5 + + ListElement { column1: qsTr("Block height") ; column2: "";} + ListElement { column1: qsTr("Date") ; column2: ""; } + } + + StandardDropdown { + id: priorityDropdown + anchors.topMargin: 2 * scaleRatio + fontHeaderSize: 14 * scaleRatio + dropdownHeight: 28 * scaleRatio + + Layout.fillWidth: true + shadowReleasedColor: "#FF4304" + shadowPressedColor: "#B32D00" + releasedColor: "#404040" + pressedColor: "#202020" + colorHeaderBackground: "#404040" + + onChanged: { + switch(priorityDropdown.currentIndex){ + case 0: + // block sort + model.sortRole = TransactionHistoryModel.TransactionBlockHeightRole; + break; + case 1: + // amount sort + model.sortRole = TransactionHistoryModel.TransactionDateRole; + break; + } + model.sort(0, Qt.DescendingOrder); + } + } - model.sort(0, desc ? Qt.DescendingOrder : Qt.AscendingOrder) } } - Scroll { - id: flickableScroll - visible: !isMobile - anchors.right: table.right - anchors.rightMargin: !isMobile ? -14 * scaleRatio : 0 - anchors.top: table.top - anchors.bottom: table.bottom - flickable: table + GridLayout { + Layout.topMargin: 20 + visible: table.count === 0 + + Label { + fontSize: 16 * scaleRatio + text: qsTr("No history...") + translationManager.emptyString + } } - HistoryTable { - id: table - visible: !isMobile - anchors.left: parent.left - anchors.right: parent.right - anchors.top: header.bottom - anchors.bottom: parent.bottom - anchors.leftMargin: 14 * scaleRatio - anchors.rightMargin: 14 * scaleRatio - onContentYChanged: flickableScroll.flickableContentYChanged() - model: !isMobile ? root.model : null - addressBookModel: null - } + GridLayout { + id: tableHeader + columns: 1 + columnSpacing: 0 + rowSpacing: 0 + Layout.topMargin: 20 + Layout.fillWidth: true - HistoryTableMobile { - id: tableMobile - visible: isMobile - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: parent.bottom - onContentYChanged: flickableScroll.flickableContentYChanged() - model: isMobile ? root.model : null - addressBookModel: null + RowLayout{ + Layout.preferredHeight: 10 + Layout.fillWidth: true + + Rectangle { + id: header + Layout.fillWidth: true + visible: table.count > 0 + + height: 10 + color: "transparent" + + Rectangle { + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.rightMargin: 10 + anchors.leftMargin: 10 + + height: 1 + color: "#404040" + } + + Image { + anchors.top: parent.top + anchors.left: parent.left + + width: 10 + height: 10 + + source: "../images/historyBorderRadius.png" + } + + Image { + anchors.top: parent.top + anchors.right: parent.right + + width: 10 + height: 10 + + source: "../images/historyBorderRadius.png" + rotation: 90 + } + } + } + + RowLayout { + Layout.preferredHeight: isMobile ? tableMobile.contentHeight : table.contentHeight + Layout.fillWidth: true + Layout.fillHeight: true + + HistoryTable { + id: table + visible: !isMobile + onContentYChanged: flickableScroll.flickableContentYChanged() + model: !isMobile ? mainLayout.model : null + addressBookModel: null + + Layout.fillWidth: true + Layout.fillHeight: true + } + + HistoryTableMobile { + id: tableMobile + visible: isMobile + onContentYChanged: flickableScroll.flickableContentYChanged() + model: isMobile ? mainLayout.model : null + addressBookModel: null + + Layout.fillWidth: true + Layout.fillHeight: true + } + } } } @@ -548,8 +366,11 @@ Rectangle { if(currentWallet != null && typeof currentWallet.history !== "undefined" ) { currentWallet.history.refresh(currentWallet.currentSubaddressAccount) table.addressBookModel = currentWallet ? currentWallet.addressBookModel : null - transactionTypeDropdown.update() + //transactionTypeDropdown.update() } + priorityDropdown.dataModel = priorityModelV5; + priorityDropdown.currentIndex = 0; + priorityDropdown.update(); } } diff --git a/pages/Keys.qml b/pages/Keys.qml index 4bcff537..37ea3060 100644 --- a/pages/Keys.qml +++ b/pages/Keys.qml @@ -31,73 +31,76 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.2 -import "../version.js" as Version - - -import "../components" import moneroComponents.Clipboard 1.0 +import "../version.js" as Version +import "../components" +import "." 1.0 + Rectangle { property bool viewOnly: false id: page - color: "#F0EEEE" + color: "transparent" Clipboard { id: clipboard } ColumnLayout { id: mainLayout - anchors.margins: 17 * scaleRatio + anchors.left: parent.left anchors.top: parent.top anchors.right: parent.right - spacing: 20 * scaleRatio + + anchors.margins: (isMobile)? 17 : 20 + anchors.topMargin: 40 * scaleRatio + + spacing: 30 * scaleRatio Layout.fillWidth: true //! Manage wallet ColumnLayout { Layout.fillWidth: true + Label { Layout.fillWidth: true + fontSize: 22 * scaleRatio + Layout.topMargin: 10 * scaleRatio text: qsTr("Mnemonic seed") + translationManager.emptyString } Rectangle { Layout.fillWidth: true - height: 1 - color: "#DEDEDE" + height: 2 + color: Style.dividerColor + opacity: Style.dividerOpacity + Layout.bottomMargin: 10 * scaleRatio } - TextEdit { + + LineEditMulti{ id: seedText - wrapMode: TextEdit.Wrap - Layout.fillWidth: true; - font.pixelSize: 14 * scaleRatio + spacing: 0 + copyButton: true + addressValidation: false readOnly: true - MouseArea { - anchors.fill: parent - onClicked: { - appWindow.showStatusMessage(qsTr("Double tap to copy"),3) - } - onDoubleClicked: { - parent.selectAll() - parent.copy() - parent.deselect() - console.log("copied to clipboard"); - appWindow.showStatusMessage(qsTr("Seed copied to clipboard"),3) - } - } + wrapAnywhere: false } } ColumnLayout { Layout.fillWidth: true + Label { Layout.fillWidth: true + fontSize: 22 * scaleRatio + Layout.topMargin: 10 * scaleRatio text: qsTr("Keys") + translationManager.emptyString } Rectangle { Layout.fillWidth: true - height: 1 - color: "#DEDEDE" + height: 2 + color: Style.dividerColor + opacity: Style.dividerOpacity + Layout.bottomMargin: 10 * scaleRatio } TextEdit { id: keysText @@ -106,6 +109,7 @@ Rectangle { font.pixelSize: 14 * scaleRatio textFormat: TextEdit.RichText readOnly: true + color: Style.defaultFontColor MouseArea { anchors.fill: parent onClicked: { @@ -124,21 +128,26 @@ Rectangle { ColumnLayout { Layout.fillWidth: true + Label { Layout.fillWidth: true + fontSize: 22 * scaleRatio + Layout.topMargin: 10 * scaleRatio text: qsTr("Export wallet") + translationManager.emptyString } Rectangle { Layout.fillWidth: true - height: 1 - color: "#DEDEDE" + height: 2 + color: Style.dividerColor + opacity: Style.dividerOpacity + Layout.bottomMargin: 10 * scaleRatio } - RowLayout { StandardButton { enabled: !fullWalletQRCode.visible id: showFullQr + small: true text: qsTr("Spendable Wallet") + translationManager.emptyString onClicked: { viewOnlyQRCode.visible = false @@ -147,6 +156,7 @@ Rectangle { StandardButton { enabled: fullWalletQRCode.visible id: showViewOnlyQr + small: true text: qsTr("View Only Wallet") + translationManager.emptyString onClicked: { viewOnlyQRCode.visible = true @@ -155,7 +165,6 @@ Rectangle { Layout.bottomMargin: 30 * scaleRatio } - Image { visible: !viewOnlyQRCode.visible id: fullWalletQRCode @@ -178,6 +187,7 @@ Rectangle { Layout.fillWidth: true font.bold: true font.pixelSize: 16 * scaleRatio + color: Style.defaultFontColor text: (viewOnlyQRCode.visible) ? qsTr("View Only Wallet") + translationManager.emptyString : qsTr("Spendable Wallet") + translationManager.emptyString horizontalAlignment: Text.AlignHCenter } diff --git a/pages/Mining.qml b/pages/Mining.qml index 0f0b370b..f27a2b19 100644 --- a/pages/Mining.qml +++ b/pages/Mining.qml @@ -34,7 +34,7 @@ import moneroComponents.Wallet 1.0 Rectangle { id: root - color: "#F0EEEE" + color: "transparent" property var currentHashRate: 0 /* main layout */ @@ -74,13 +74,16 @@ Rectangle { text: qsTr("Mining with your computer helps strengthen the Monero network. The more that people mine, the harder it is for the network to be attacked, and every little bit helps.

Mining also gives you a small chance to earn some Monero. Your computer will create hashes looking for block solutions. If you find a block, you will get the associated reward. Good luck!") + translationManager.emptyString wrapMode: Text.Wrap Layout.fillWidth: true + font.family: Style.fontRegular.name + font.pixelSize: 14 * scaleRatio + color: Style.defaultFontColor } RowLayout { id: soloMinerThreadsRow Label { id: soloMinerThreadsLabel - color: "#4A4949" + color: Style.defaultFontColor text: qsTr("CPU threads") + translationManager.emptyString fontSize: 16 Layout.preferredWidth: 120 @@ -102,8 +105,6 @@ Rectangle { checked: persistentSettings.allow_background_mining onClicked: {persistentSettings.allow_background_mining = checked} text: qsTr("Background mining (experimental)") + translationManager.emptyString - checkedIcon: "../images/checkedVioletIcon.png" - uncheckedIcon: "../images/uncheckedIcon.png" } } @@ -118,15 +119,13 @@ Rectangle { checked: !persistentSettings.miningIgnoreBattery onClicked: {persistentSettings.miningIgnoreBattery = !checked} text: qsTr("Enable mining when running on battery") + translationManager.emptyString - checkedIcon: "../images/checkedVioletIcon.png" - uncheckedIcon: "../images/uncheckedIcon.png" } } RowLayout { Label { id: manageSoloMinerLabel - color: "#4A4949" + color: Style.defaultFontColor text: qsTr("Manage miner") + translationManager.emptyString fontSize: 16 } @@ -136,11 +135,8 @@ Rectangle { //enabled: !walletManager.isMining() id: startSoloMinerButton width: 110 + small: true text: qsTr("Start mining") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" onClicked: { var success = walletManager.startMining(appWindow.currentWallet.address(0, 0), soloMinerThreadsLine.text, persistentSettings.allow_background_mining, persistentSettings.miningIgnoreBattery) if (success) { @@ -161,11 +157,8 @@ Rectangle { //enabled: walletManager.isMining() id: stopSoloMinerButton width: 110 + small: true text: qsTr("Stop mining") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" onClicked: { walletManager.stopMining() update() @@ -177,6 +170,7 @@ Rectangle { Text { id: statusText text: qsTr("Status: not mining") + color: Style.defaultFontColor textFormat: Text.RichText wrapMode: Text.Wrap } diff --git a/pages/Receive.qml b/pages/Receive.qml index f839741e..497851e7 100644 --- a/pages/Receive.qml +++ b/pages/Receive.qml @@ -27,7 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.2 import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.2 @@ -43,7 +43,7 @@ import moneroComponents.SubaddressModel 1.0 Rectangle { id: pageReceive - color: "#F0EEEE" + color: "transparent" property var model property var current_address property alias addressText : pageReceive.current_address @@ -142,7 +142,6 @@ Rectangle { Clipboard { id: clipboard } - /* main layout */ ColumnLayout { id: mainLayout @@ -159,9 +158,9 @@ Rectangle { property int lineEditFontSize: 12 * scaleRatio property int qrCodeSize: 240 * scaleRatio - ColumnLayout { id: addressRow + spacing: 0 Label { id: addressLabel text: qsTr("Addresses") + translationManager.emptyString @@ -169,10 +168,54 @@ Rectangle { } Rectangle { - id: tableRect + id: header Layout.fillWidth: true - Layout.preferredHeight: 200 - color: "#FFFFFF" + Layout.topMargin: 10 + visible: table.count > 0 + + height: 10 + color: "transparent" + + Rectangle { + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.rightMargin: 10 + anchors.leftMargin: 10 + + height: 1 + color: "#404040" + } + + Image { + anchors.top: parent.top + anchors.left: parent.left + + width: 10 + height: 10 + + source: "../images/historyBorderRadius.png" + } + + Image { + anchors.top: parent.top + anchors.right: parent.right + + width: 10 + height: 10 + + source: "../images/historyBorderRadius.png" + rotation: 90 + } + } + + Rectangle { + id: tableRect + property int table_max_height: 260 + Layout.fillWidth: true + Layout.preferredHeight: table.contentHeight < table_max_height ? table.contentHeight : table_max_height + color: "transparent" + Scroll { id: flickableScroll anchors.right: table.right @@ -180,6 +223,7 @@ Rectangle { anchors.bottom: table.bottom flickable: table } + SubaddressTable { id: table anchors.fill: parent @@ -192,11 +236,10 @@ Rectangle { RowLayout { spacing: 20 + Layout.topMargin: 20 + StandardButton { - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" + small: true text: qsTr("Create new address") + translationManager.emptyString; onClicked: { inputDialog.labelText = qsTr("Set the label of the new address:") + translationManager.emptyString @@ -210,10 +253,7 @@ Rectangle { } } StandardButton { - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" + small: true enabled: table.currentIndex > 0 text: qsTr("Rename") + translationManager.emptyString; onClicked: { @@ -240,7 +280,6 @@ Rectangle { LineEdit { id: amountLine - fontSize: mainLayout.lineEditFontSize placeholderText: qsTr("Amount to receive") + translationManager.emptyString readOnly: false width: mainLayout.editWidth @@ -255,7 +294,7 @@ Rectangle { } } - RowLayout { + ColumnLayout { id: trackingRow visible: !isAndroid && !isIOS Label { @@ -288,15 +327,14 @@ Rectangle { TextEdit { id: trackingLine - anchors.top: trackingRow.top - textFormat: Text.RichText - text: "" readOnly: true width: mainLayout.editWidth Layout.fillWidth: true + textFormat: Text.RichText + text: "" selectByMouse: true + color: 'white' } - } MessageDialog { diff --git a/pages/Settings.qml b/pages/Settings.qml index f9d1e3bc..abfc0e05 100644 --- a/pages/Settings.qml +++ b/pages/Settings.qml @@ -41,48 +41,58 @@ Rectangle { property bool viewOnly: false id: page - color: "#F0EEEE" + color: "transparent" + + // fires on every page load + function onPageCompleted() { + console.log("Settings page loaded"); + + if(typeof daemonManager != "undefined"){ + appWindow.daemonRunning = daemonManager.running(persistentSettings.testnet); + } + + logLevelDropdown.update() + } Clipboard { id: clipboard } - function initSettings() { - //runs on every page load - } - ColumnLayout { id: mainLayout - anchors.margins: 17 * scaleRatio + anchors.margins: (isMobile)? 17 : 40 anchors.left: parent.left anchors.top: parent.top anchors.right: parent.right - spacing: 10 * scaleRatio + spacing: 26 * scaleRatio //! Manage wallet RowLayout { + Layout.fillWidth: true Label { id: manageWalletLabel + fontSize: 22 * scaleRatio Layout.fillWidth: true - color: "#4A4949" text: qsTr("Manage wallet") + translationManager.emptyString Layout.topMargin: 10 * scaleRatio } - } - Rectangle { - Layout.fillWidth: true - height: 1 - color: "#DEDEDE" + Rectangle { + anchors.top: manageWalletLabel.bottom + anchors.topMargin: 4 + anchors.left: parent.left + anchors.right: parent.right + Layout.fillWidth: true + height: 2 + color: Style.dividerColor + opacity: Style.dividerOpacity + } } GridLayout { columns: (isMobile)? 1 : 4 StandardButton { id: closeWalletButton + small: true text: qsTr("Close wallet") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" visible: true onClicked: { console.log("closing wallet button clicked") @@ -91,13 +101,10 @@ Rectangle { } StandardButton { - enabled: !viewOnly id: createViewOnlyWalletButton + enabled: !viewOnly + small: true text: qsTr("Create view only wallet") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" visible: true onClicked: { wizard.openCreateViewOnlyWalletPage(); @@ -141,12 +148,9 @@ Rectangle { */ StandardButton { id: rescanSpentButton + small: true enabled: !persistentSettings.useRemoteNode text: qsTr("Rescan wallet balance") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" onClicked: { if (!currentWallet.rescanSpent()) { console.error("Error: ", currentWallet.errorString); @@ -164,14 +168,15 @@ Rectangle { } } } + } + + RowLayout{ + Layout.fillWidth: true StandardButton { id: changePasswordButton + small: true text: qsTr("Change password") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" onClicked: { passwordDialog.onAcceptedCallback = function() { if(appWindow.walletPassword === passwordDialog.password){ @@ -193,16 +198,20 @@ Rectangle { } RowLayout { + Layout.fillWidth: true + LabelSubheader { + text: qsTr("Wallet mode") + translationManager.emptyString + } + } + + RowLayout { StandardButton { id: remoteDisconnect + small: true enabled: persistentSettings.useRemoteNode Layout.fillWidth: false text: qsTr("Local Node") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" onClicked: { appWindow.disconnectRemoteNode(); } @@ -210,185 +219,51 @@ Rectangle { StandardButton { id: remoteConnect + small: true enabled: !persistentSettings.useRemoteNode Layout.fillWidth: false text: qsTr("Remote Node") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" onClicked: { appWindow.connectRemoteNode(); } } } - //! Manage daemon RowLayout { - visible: !isMobile - Layout.topMargin: 20 - Label { - id: manageDaemonLabel - color: "#4A4949" - text: qsTr("Manage Daemon") + translationManager.emptyString - } - - CheckBox { - id: daemonAdvanced - Layout.leftMargin: 15 - text: qsTr("Show advanced") + translationManager.emptyString - checkedIcon: "../images/checkedVioletIcon.png" - uncheckedIcon: "../images/uncheckedIcon.png" - } - } - Rectangle { + visible: !isMobile && !persistentSettings.useRemoteNode Layout.fillWidth: true - height: 1 - color: "#DEDEDE" - } - GridLayout { - visible: !isMobile && !persistentSettings.useRemoteNode - id: daemonStatusRow - columns: (isMobile) ? 2 : 4 - StandardButton { - visible: !appWindow.daemonRunning - id: startDaemonButton - text: qsTr("Start Local Node") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - onClicked: { - // Update bootstrap daemon address - persistentSettings.bootstrapNodeAddress = bootstrapNodeEdit.daemonAddrText ? bootstrapNodeEdit.getAddress() : ""; - - // Set current daemon address to local - appWindow.currentDaemonAddress = appWindow.localDaemonAddress - appWindow.startDaemon(daemonFlags.text) - } - } - - StandardButton { - visible: appWindow.daemonRunning - id: stopDaemonButton - text: qsTr("Stop Local Node") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - onClicked: { - appWindow.stopDaemon() - } - } - - StandardButton { - visible: true - id: daemonStatusButton - text: qsTr("Show status") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - onClicked: { - daemonManager.sendCommand("status",currentWallet.nettype); - daemonConsolePopup.open(); - } - } - } - - ColumnLayout { - id: blockchainFolderRow - visible: !isMobile && !persistentSettings.useRemoteNode - Label { - id: blockchainFolderLabel - color: "#4A4949" - text: qsTr("Blockchain location") + translationManager.emptyString - } - LineEdit { - id: blockchainFolder - Layout.preferredWidth: 200 - Layout.fillWidth: true - text: persistentSettings.blockchainDataDir - placeholderText: qsTr("(optional)") + translationManager.emptyString - - MouseArea { - anchors.fill: parent - onClicked: { - mouse.accepted = false - if(persistentSettings.blockchainDataDir != "") - blockchainFileDialog.folder = "file://" + persistentSettings.blockchainDataDir - blockchainFileDialog.open() - blockchainFolder.focus = true - } - } - - } - } - - - RowLayout { - visible: daemonAdvanced.checked && !isMobile && !persistentSettings.useRemoteNode - id: daemonFlagsRow - Label { - id: daemonFlagsLabel - color: "#4A4949" - text: qsTr("Local daemon startup flags") + translationManager.emptyString - } - LineEdit { - id: daemonFlags - Layout.preferredWidth: 200 - Layout.fillWidth: true - text: appWindow.persistentSettings.daemonFlags; - placeholderText: qsTr("(optional)") + translationManager.emptyString - } - } - - RowLayout { - Layout.fillWidth: true - visible: (daemonAdvanced.checked || isMobile) && persistentSettings.useRemoteNode - Label { - id: daemonLoginLabel - Layout.fillWidth: true - color: "#4A4949" - text: qsTr("Node login (optional)") + translationManager.emptyString - } - - } - - ColumnLayout { - visible: (daemonAdvanced.checked || isMobile) && persistentSettings.useRemoteNode - LineEdit { - id: daemonUsername - Layout.preferredWidth: 100 * scaleRatio - Layout.fillWidth: true - text: persistentSettings.daemonUsername - placeholderText: qsTr("Username") + translationManager.emptyString - } - - - LineEdit { - id: daemonPassword - Layout.preferredWidth: 100 * scaleRatio - Layout.fillWidth: true - text: persistentSettings.daemonPassword - placeholderText: qsTr("Password") + translationManager.emptyString - echoMode: TextInput.Password + LabelSubheader { + text: qsTr("Bootstrap node") + translationManager.emptyString } } RowLayout { visible: !isMobile && !persistentSettings.useRemoteNode + ColumnLayout { - Label { - color: "#4A4949" - text: qsTr("Bootstrap node (leave blank if not wanted)") + translationManager.emptyString - } + Layout.fillWidth: true + RemoteNodeEdit { id: bootstrapNodeEdit Layout.minimumWidth: 100 * scaleRatio + Layout.bottomMargin: 20 * scaleRatio + + lineEditBackgroundColor: "transparent" + lineEditFontColor: "white" + lineEditBorderColor: Qt.rgba(255, 255, 255, 0.35) + + daemonAddrLabelText: qsTr("Address") + daemonPortLabelText: qsTr("Port") daemonAddrText: persistentSettings.bootstrapNodeAddress.split(":")[0].trim() - daemonPortText: (persistentSettings.bootstrapNodeAddress.split(":")[1].trim() == "") ? "18081" : persistentSettings.bootstrapNodeAddress.split(":")[1] + daemonPortText: { + var node_split = persistentSettings.bootstrapNodeAddress.split(":"); + if(node_split.length == 2){ + (node_split[1].trim() == "") ? "18081" : node_split[1]; + } else { + return "" + } + } onEditingFinished: { persistentSettings.bootstrapNodeAddress = daemonAddrText ? bootstrapNodeEdit.getAddress() : ""; console.log("setting bootstrap node to " + persistentSettings.bootstrapNodeAddress) @@ -400,13 +275,19 @@ Rectangle { RowLayout { visible: persistentSettings.useRemoteNode ColumnLayout { - Label { - color: "#4A4949" - text: qsTr("Remote node") + translationManager.emptyString - } + Layout.fillWidth: true + RemoteNodeEdit { id: remoteNodeEdit Layout.minimumWidth: 100 * scaleRatio + + lineEditBackgroundColor: "transparent" + lineEditFontColor: "white" + lineEditBorderColor: Qt.rgba(255, 255, 255, 0.35) + + daemonAddrLabelText: qsTr("Address") + daemonPortLabelText: qsTr("Port") + property var rna: persistentSettings.remoteNodeAddress daemonAddrText: rna.search(":") != -1 ? rna.split(":")[0].trim() : "" daemonPortText: rna.search(":") != -1 ? (rna.split(":")[1].trim() == "") ? "18081" : rna.split(":")[1] : "" @@ -415,43 +296,203 @@ Rectangle { console.log("setting remote node to " + persistentSettings.remoteNodeAddress) } } + } + } + RowLayout{ + visible: persistentSettings.useRemoteNode + Layout.fillWidth: true + + StandardButton { + id: remoteNodeSave + small: true + text: qsTr("Connect") + translationManager.emptyString + onClicked: { + // Update daemon login + persistentSettings.remoteNodeAddress = remoteNodeEdit.getAddress(); + persistentSettings.daemonUsername = daemonUsername.text; + persistentSettings.daemonPassword = daemonPassword.text; + persistentSettings.useRemoteNode = true + + currentWallet.setDaemonLogin(persistentSettings.daemonUsername, persistentSettings.daemonPassword); + + appWindow.connectRemoteNode() + } + } + } + + //! Manage daemon + RowLayout { + visible: !isMobile + + Label { + id: manageDaemonLabel + fontSize: 22 * scaleRatio + text: qsTr("Manage Daemon") + translationManager.emptyString + } + + Rectangle { + anchors.top: manageDaemonLabel.bottom + anchors.topMargin: 4 + anchors.left: parent.left + anchors.right: parent.right + Layout.fillWidth: true + height: 2 + color: Style.dividerColor + opacity: Style.dividerOpacity + } + } + + GridLayout { + visible: !isMobile && !persistentSettings.useRemoteNode + id: daemonStatusRow + columns: (isMobile) ? 2 : 4 + StandardButton { + id: startDaemonButton + small: true + visible: !appWindow.daemonRunning + text: qsTr("Start Local Node") + translationManager.emptyString + onClicked: { + // Update bootstrap daemon address + persistentSettings.bootstrapNodeAddress = bootstrapNodeEdit.daemonAddrText ? bootstrapNodeEdit.getAddress() : ""; + + // Set current daemon address to local + appWindow.currentDaemonAddress = appWindow.localDaemonAddress; + appWindow.startDaemon(daemonFlags.text); + } + } + + StandardButton { + id: stopDaemonButton + small: true + visible: appWindow.daemonRunning + text: qsTr("Stop Local Node") + translationManager.emptyString + onClicked: { + appWindow.stopDaemon() + } + } + + StandardButton { + id: daemonStatusButton + small: true + visible: true + text: qsTr("Show status") + translationManager.emptyString + onClicked: { + daemonManager.sendCommand("status",currentWallet.nettype); + daemonConsolePopup.open(); + } + } + } + + ColumnLayout { + id: blockchainFolderRow + visible: !isMobile && !persistentSettings.useRemoteNode + + RowLayout { + Layout.fillWidth: true + Layout.bottomMargin: 14 * scaleRatio + + LabelSubheader { + text: qsTr("Blockchain location") + translationManager.emptyString + } + } + + RowLayout { + visible: persistentSettings.blockchainDataDir.length > 0 + + LineEdit { + id: blockchainFolder + Layout.preferredWidth: 200 + + Layout.fillWidth: true + text: persistentSettings.blockchainDataDir; + placeholderText: qsTr("(optional)") + translationManager.emptyString + } + } + + RowLayout { + Layout.fillWidth: true + Layout.topMargin: 8 StandardButton { - id: remoteNodeSave - text: qsTr("Connect") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" + id: blockchainFolderButton + small: true + visible: true + text: qsTr("Change location") + translationManager.emptyString onClicked: { - // Update daemon login - persistentSettings.remoteNodeAddress = remoteNodeEdit.getAddress(); - persistentSettings.daemonUsername = daemonUsername.text; - persistentSettings.daemonPassword = daemonPassword.text; - persistentSettings.useRemoteNode = true - - currentWallet.setDaemonLogin(persistentSettings.daemonUsername, persistentSettings.daemonPassword); - - appWindow.connectRemoteNode() + //mouse.accepted = false + if(persistentSettings.blockchainDataDir != "") + blockchainFileDialog.folder = "file://" + persistentSettings.blockchainDataDir + blockchainFileDialog.open() + blockchainFolder.focus = true } } } } + RowLayout{ + CheckBox { + id: daemonAdvanced + text: qsTr("Show advanced") + translationManager.emptyString + } + } + + RowLayout { + visible: daemonAdvanced.checked && !isMobile && !persistentSettings.useRemoteNode + id: daemonFlagsRow + + LineEdit { + id: daemonFlags + Layout.preferredWidth: 200 + Layout.fillWidth: true + labelText: qsTr("Local daemon startup flags") + translationManager.emptyString + text: appWindow.persistentSettings.daemonFlags; + placeholderText: qsTr("(optional)") + translationManager.emptyString + } + } + + ColumnLayout { + visible: (daemonAdvanced.checked || isMobile) && persistentSettings.useRemoteNode + GridLayout { + columns: (isMobile) ? 1 : 2 + columnSpacing: 32 + + LineEdit { + id: daemonUsername + Layout.fillWidth: true + labelText: "Daemon username" + text: persistentSettings.daemonUsername + placeholderText: qsTr("Username") + translationManager.emptyString + } + + LineEdit { + id: daemonPassword + Layout.fillWidth: true + labelText: "Daemon password" + text: persistentSettings.daemonPassword + placeholderText: qsTr("Password") + translationManager.emptyString + echoMode: TextInput.Password + } + } + } + RowLayout { visible: !isMobile Label { - color: "#4A4949" + id: layoutSettingsLabel + fontSize: 22 * scaleRatio text: qsTr("Layout settings") + translationManager.emptyString - anchors.topMargin: 30 * scaleRatio - Layout.topMargin: 30 * scaleRatio } - } - Rectangle { - visible: !isMobile - Layout.fillWidth: true - height: 1 - color: "#DEDEDE" + + Rectangle { + anchors.top: layoutSettingsLabel.bottom + anchors.topMargin: 4 + anchors.left: parent.left + anchors.right: parent.right + Layout.fillWidth: true + height: 2 + color: Style.dividerColor + opacity: Style.dividerOpacity + } } RowLayout { @@ -461,8 +502,6 @@ Rectangle { checked: persistentSettings.customDecorations onClicked: appWindow.setCustomWindowDecorations(checked) text: qsTr("Custom decorations") + translationManager.emptyString - checkedIcon: "../images/checkedVioletIcon.png" - uncheckedIcon: "../images/uncheckedIcon.png" } } @@ -470,41 +509,84 @@ Rectangle { RowLayout { Label { - color: "#4A4949" + id: logLevelLabel + fontSize: 22 * scaleRatio text: qsTr("Log level") + translationManager.emptyString - anchors.topMargin: 30 * scaleRatio - Layout.topMargin: 30 * scaleRatio - } - } - Rectangle { - Layout.fillWidth: true - height: 1 - color: "#DEDEDE" - } - ColumnLayout { - ComboBox { - id: logLevel - model: [0,1,2,3,4,"custom"] - currentIndex : appWindow.persistentSettings.logLevel; - onCurrentIndexChanged: { - if (currentIndex == 5) { - console.log("log categories changed: ", logCategories.text); - walletManager.setLogCategories(logCategories.text); - } - else { - console.log("log level changed: ",currentIndex); - walletManager.setLogLevel(currentIndex); - } - appWindow.persistentSettings.logLevel = currentIndex; - } } + Rectangle { + anchors.top: logLevelLabel.bottom + anchors.topMargin: 4 + anchors.left: parent.left + anchors.right: parent.right + Layout.fillWidth: true + height: 2 + color: Style.dividerColor + opacity: Style.dividerOpacity + } + } + + GridLayout { + columns: (isMobile)? 1 : 3 + Layout.fillWidth: true + columnSpacing: 32 + + ColumnLayout { + spacing: 0 + Layout.fillWidth: true + + ListModel { + id: logLevel + ListElement { name: "wow"; column1: "0"; } + ListElement { column1: "1"; } + ListElement { column1: "2"; } + ListElement { column1: "3"; } + ListElement { column1: "4"; } + ListElement { column1: "custom"; } + } + + StandardDropdown { + id: logLevelDropdown + dataModel: logLevel + currentIndex: appWindow.persistentSettings.logLevel; + onChanged: { + if (currentIndex == 5) { + console.log("log categories changed: ", logCategories.text); + walletManager.setLogCategories(logCategories.text); + } + else { + console.log("log level changed: ",currentIndex); + walletManager.setLogLevel(currentIndex); + } + appWindow.persistentSettings.logLevel = currentIndex; + } + Layout.fillWidth: true + shadowReleasedColor: "#FF4304" + shadowPressedColor: "#B32D00" + releasedColor: "#363636" + pressedColor: "#202020" + } + // Make sure dropdown is on top + z: parent.z + 30 + } + + ColumnLayout { + Layout.fillWidth: true + } + + ColumnLayout { + Layout.fillWidth: true + } + } + + ColumnLayout { LineEdit { id: logCategories Layout.fillWidth: true text: appWindow.persistentSettings.logCategories + labelText: "Log Categories" placeholderText: qsTr("(e.g. *:WARNING,net.p2p:DEBUG)") + translationManager.emptyString - enabled: logLevel.currentIndex == 5 + enabled: logLevelDropdown.currentIndex === 5 onEditingFinished: { if(enabled) { console.log("log categories changed: ", text); @@ -518,31 +600,41 @@ Rectangle { // Version RowLayout { Label { - color: "#4A4949" + id: debugLabel text: qsTr("Debug info") + translationManager.emptyString - fontSize: 16 + fontSize: 22 anchors.topMargin: 30 * scaleRatio Layout.topMargin: 30 * scaleRatio } + + Rectangle { + anchors.top: debugLabel.bottom + anchors.topMargin: 4 + anchors.left: parent.left + anchors.right: parent.right + Layout.fillWidth: true + height: 2 + color: Style.dividerColor + opacity: Style.dividerOpacity + } } - Rectangle { - Layout.fillWidth: true - height: 1 - color: "#DEDEDE" - } + TextBlock { Layout.topMargin: 8 + font.pixelSize: 14 Layout.fillWidth: true text: qsTr("GUI version: ") + Version.GUI_VERSION + translationManager.emptyString } TextBlock { id: guiMoneroVersion Layout.fillWidth: true + font.pixelSize: 14 text: qsTr("Embedded Monero version: ") + Version.GUI_MONERO_VERSION + translationManager.emptyString } TextBlock { id: restoreHeightText Layout.fillWidth: true + font.pixelSize: 14 textFormat: Text.RichText property var txt: "" + qsTr("Wallet creation height: ") + (currentWallet ? currentWallet.walletCreationHeight : "") + translationManager.emptyString property var linkTxt: qsTr("
(Click to change)") + translationManager.emptyString @@ -569,13 +661,10 @@ Rectangle { StandardButton { id: restoreHeightSave + small: true Layout.fillWidth: false Layout.leftMargin: 30 text: qsTr("Save") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" onClicked: { currentWallet.walletCreationHeight = restoreHeight.text @@ -613,14 +702,17 @@ Rectangle { TextBlock { Layout.fillWidth: true + font.pixelSize: 14 text: (!currentWallet) ? "" : qsTr("Wallet log path: ") + currentWallet.walletLogPath + translationManager.emptyString } TextBlock { Layout.fillWidth: true + font.pixelSize: 14 text: qsTr("Wallet Name: ") + walletName + translationManager.emptyString } TextBlock { Layout.fillWidth: true + font.pixelSize: 14 text: (!currentWallet) ? "" : qsTr("Daemon log path: ") + currentWallet.daemonLogPath + translationManager.emptyString } } @@ -644,7 +736,8 @@ Rectangle { folder: "file://" + persistentSettings.blockchainDataDir onAccepted: { - var dataDir = walletManager.urlToLocalPath(blockchainFileDialog.fileUrl) + var dataDir = walletManager.urlToLocalPath(blockchainFileDialog.fileUrl); + console.log(dataDir); var validator = daemonManager.validateDataDir(dataDir); if(!validator.valid) { @@ -691,16 +784,6 @@ Rectangle { } - // fires on every page load - function onPageCompleted() { - console.log("Settings page loaded"); - initSettings(); - - - if(typeof daemonManager != "undefined") - appWindow.daemonRunning = daemonManager.running(persistentSettings.nettype) - } - // fires only once Component.onCompleted: { if(typeof daemonManager != "undefined") diff --git a/pages/SharedRingDB.qml b/pages/SharedRingDB.qml index 53ea34e1..f1a002f6 100644 --- a/pages/SharedRingDB.qml +++ b/pages/SharedRingDB.qml @@ -37,7 +37,7 @@ import moneroComponents.Clipboard 1.0 Rectangle { - color: "#F0EEEE" + color: "transparent" Clipboard { id: clipboard } @@ -90,6 +90,7 @@ Rectangle { "This database is meant for use by Monero wallets as well as wallets from Monero clones which reuse the Monero keys.") + translationManager.emptyString wrapMode: Text.Wrap Layout.fillWidth: true; + color: Style.defaultFontColor } Text { @@ -117,6 +118,7 @@ Rectangle { sharedRingDBDialog.icon = StandardIcon.Information sharedRingDBDialog.open() } + color: Style.defaultFontColor } RowLayout { @@ -140,11 +142,8 @@ Rectangle { id: selectBlackballFileButton anchors.rightMargin: 17 * scaleRatio text: qsTr("Select") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" enabled: true + small: true onClicked: { loadBlackballFileDialog.open() } @@ -172,10 +171,7 @@ Rectangle { id: loadBlackballFileButton anchors.right: parent.right text: qsTr("Load") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" + small: true enabled: !!appWindow.currentWallet onClicked: appWindow.currentWallet.blackballOutputs(walletManager.urlToLocalPath(loadBlackballFileDialog.fileUrl), true) } @@ -209,10 +205,7 @@ Rectangle { StandardButton { id: blackballButton text: qsTr("Blackball") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" + small: true enabled: !!appWindow.currentWallet && validHex32(blackballOutputLine.text) onClicked: appWindow.currentWallet.blackballOutput(blackballOutputLine.text) } @@ -221,10 +214,7 @@ Rectangle { id: unblackballButton anchors.right: parent.right text: qsTr("Unblackball") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" + small: true enabled: !!appWindow.currentWallet && validHex32(blackballOutputLine.text) onClicked: appWindow.currentWallet.unblackballOutput(blackballOutputLine.text) } @@ -255,6 +245,7 @@ Rectangle { sharedRingDBDialog.icon = StandardIcon.Information sharedRingDBDialog.open() } + color: Style.defaultFontColor } RowLayout { @@ -281,10 +272,7 @@ Rectangle { StandardButton { id: getRingButton text: qsTr("Get Ring") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" + small: true enabled: !!appWindow.currentWallet && validHex32(keyImageLine.text) onClicked: { var ring = appWindow.currentWallet.getRing(keyImageLine.text) @@ -322,7 +310,7 @@ Rectangle { id: setRingRelative checked: true text: qsTr("Relative") + translationManager.emptyString - checkedIcon: "../images/checkedVioletIcon.png" + checkedIcon: "../images/checkedBlackIcon.png" uncheckedIcon: "../images/uncheckedIcon.png" } LineEdit { @@ -344,10 +332,6 @@ Rectangle { StandardButton { id: setRingButton text: qsTr("Set Ring") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" enabled: !!appWindow.currentWallet && validHex32(keyImageLine.text) && validRing(setRingLine.text.trim(), setRingRelative.checked) onClicked: { var outs = setRingLine.text.trim() @@ -360,7 +344,7 @@ Rectangle { id: segregatePreForkOutputs checked: persistentSettings.segregatePreForkOutputs text: qsTr("I intend to spend on key-reusing fork(s)") + translationManager.emptyString - checkedIcon: "../images/checkedVioletIcon.png" + checkedIcon: "../images/checkedBlackIcon.png" uncheckedIcon: "../images/uncheckedIcon.png" onClicked: { persistentSettings.segregatePreForkOutputs = segregatePreForkOutputs.checked @@ -373,7 +357,7 @@ Rectangle { id: keyReuseMitigation2 checked: persistentSettings.keyReuseMitigation2 text: qsTr("I might want to spend on key-reusing fork(s)") + translationManager.emptyString - checkedIcon: "../images/checkedVioletIcon.png" + checkedIcon: "../images/checkedBlackIcon.png" uncheckedIcon: "../images/uncheckedIcon.png" onClicked: { persistentSettings.keyReuseMitigation2 = keyReuseMitigation2.checked diff --git a/pages/Sign.qml b/pages/Sign.qml index 6ff8dd6a..e86ac71a 100644 --- a/pages/Sign.qml +++ b/pages/Sign.qml @@ -39,14 +39,10 @@ import moneroComponents.WalletManager 1.0 Rectangle { id: mainLayout - color: "#F0EEEE" + color: "transparent" Clipboard { id: clipboard } - function checkAddress(address, nettype) { - return walletManager.addressValid(address, nettype) - } - MessageDialog { // dynamically change onclose handler property var onCloseCallback @@ -88,322 +84,215 @@ Rectangle { // sign / verify ColumnLayout { - anchors.margins: 17 * scaleRatio + anchors.top: parent.top + anchors.margins: 40 * scaleRatio anchors.left: parent.left anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: parent.bottom - spacing: 20 * scaleRatio // sign ColumnLayout { id: signBox - - RowLayout { - - Text { - text: qsTr("Sign a message or file contents with your address:") + translationManager.emptyString - wrapMode: Text.Wrap - font.pixelSize: 14 * scaleRatio - Layout.fillWidth: true - } - } + anchors.left: parent.left + anchors.right: parent.right + spacing: 20 * scaleRatio Label { - id: signMessageLabel - text: qsTr("Either message:") + translationManager.emptyString + id: signTitleLabel + fontSize: 24 * scaleRatio + text: qsTr("Sign") + translationManager.emptyString } - RowLayout { + Text { + text: qsTr("This page lets you sign/verify a message (or file contents) with your address.") + translationManager.emptyString + wrapMode: Text.Wrap + Layout.fillWidth: true + font.family: Style.fontRegular.name + font.pixelSize: 14 * scaleRatio + color: Style.defaultFontColor + } + + ColumnLayout{ id: signMessageRow - anchors.topMargin: 17 - anchors.left: parent.left - anchors.right: parent.right - LineEdit { - id: signMessageLine - anchors.left: parent.left - anchors.right: signMessageButton.left - placeholderText: qsTr("Message to sign") + translationManager.emptyString; - readOnly: false - onTextChanged: signSignatureLine.text = "" - - IconButton { - imageSource: "../images/copyToClipboard.png" - onClicked: { - if (signMessageLine.text.length > 0) { - clipboard.setText(signMessageLine.text) - } - } - } - } - - StandardButton { - id: signMessageButton - anchors.right: parent.right - text: qsTr("Sign") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - enabled: true - onClicked: { - var signature = appWindow.currentWallet.signMessage(signMessageLine.text, false) - signSignatureLine.text = signature - } - } - } - - Label { - id: signMessageFileLabel - text: qsTr("Or file:") + translationManager.emptyString - } - - RowLayout { - id: signFileRow - anchors.topMargin: 17 - anchors.left: parent.left - anchors.right: parent.right - - FileDialog { - id: signFileDialog - title: qsTr("Please choose a file to sign") + translationManager.emptyString; - folder: "file://" - nameFilters: [ "*"] - - onAccepted: { - signFileLine.text = walletManager.urlToLocalPath(signFileDialog.fileUrl) - } - } - - StandardButton { - id: loadFileToSignButton - anchors.rightMargin: 17 * scaleRatio - text: qsTr("Select") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - enabled: true - onClicked: { - signFileDialog.open() - } - } - LineEdit { - id: signFileLine - anchors.left: loadFileToSignButton.right - anchors.right: signFileButton.left - placeholderText: qsTr("Filename with message to sign") + translationManager.emptyString; - readOnly: false + RowLayout { Layout.fillWidth: true - onTextChanged: signSignatureLine.text = "" - IconButton { - imageSource: "../images/copyToClipboard.png" - onClicked: { - if (signFileLine.text.length > 0) { - clipboard.setText(signFileLine.text) - } - } + LineEdit { + id: signMessageLine + Layout.fillWidth: true + placeholderText: qsTr("Message to sign") + translationManager.emptyString; + labelText: qsTr("Message") + translationManager.emptyString; + readOnly: false + onTextChanged: signSignatureLine.text = "" } } - StandardButton { - id: signFileButton - anchors.right: parent.right - text: qsTr("Sign") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - enabled: true - onClicked: { - var signature = appWindow.currentWallet.signMessage(signFileLine.text, true) - signSignatureLine.text = signature + RowLayout{ + Layout.fillWidth: true + Layout.topMargin: 18 + + StandardButton { + id: signMessageButton + text: qsTr("Sign") + translationManager.emptyString + enabled: signMessageLine.text !== '' + small: true + onClicked: { + var signature = appWindow.currentWallet.signMessage(signMessageLine.text, false) + signSignatureLine.text = signature + } } } } + ColumnLayout { + id: signFileRow + + RowLayout { + LineEdit { + id: signFileLine + labelText: "Message from file" + placeholderText: qsTr("Path to file") + translationManager.emptyString; + readOnly: false + Layout.fillWidth: true + onTextChanged: signSignatureLine.text = "" + } + } + + RowLayout { + Layout.fillWidth: true + Layout.topMargin: 18 + + StandardButton { + id: loadFileToSignButton + small: true + text: qsTr("Browse") + translationManager.emptyString + enabled: true + onClicked: { + signFileDialog.open(); + } + } + + StandardButton { + id: signFileButton + small: true + anchors.left: loadFileToSignButton.right + anchors.leftMargin: 20 + text: qsTr("Sign") + translationManager.emptyString + enabled: signFileLine.text !== '' + onClicked: { + var signature = appWindow.currentWallet.signMessage(signFileLine.text, true); + signSignatureLine.text = signature; + } + } + } + + } + ColumnLayout { id: signSignatureRow - anchors.topMargin: 17 * scaleRatio - Label { - id: signSignatureLabel - text: qsTr("Signature") + translationManager.emptyString - } - - LineEdit { - id: signSignatureLine - placeholderText: qsTr("Signature") + translationManager.emptyString; - readOnly: true - Layout.fillWidth: true - - IconButton { - imageSource: "../images/copyToClipboard.png" - onClicked: { - if (signSignatureLine.text.length > 0) { - clipboard.setText(signSignatureLine.text) - } - } - } - } - } - } - - - // verify - ColumnLayout { - id: verifyBox - - RowLayout { - Text { - text: qsTr("Verify a message or file signature from an address:") + translationManager.emptyString - wrapMode: Text.Wrap - font.pixelSize: 14 * scaleRatio - Layout.fillWidth: true - } - - } - - Label { - id: verifyMessageLabel - text: qsTr("Either message:") + translationManager.emptyString - } - - RowLayout { - id: verifyMessageRow - anchors.topMargin: 17 * scaleRatio - anchors.left: parent.left - anchors.right: parent.right - - LineEdit { - id: verifyMessageLine - anchors.left: parent.left - anchors.right: verifyMessageButton.left - placeholderText: qsTr("Message to verify") + translationManager.emptyString; - readOnly: false - Layout.fillWidth: true - - IconButton { - imageSource: "../images/copyToClipboard.png" - onClicked: { - if (verifyMessageLine.text.length > 0) { - clipboard.setText(verifyMessageLine.text) - } - } - } - } - - StandardButton { - id: verifyMessageButton - anchors.right: parent.right - text: qsTr("Verify") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - enabled: true - onClicked: { - var verified = appWindow.currentWallet.verifySignedMessage(verifyMessageLine.text, verifyAddressLine.text, verifySignatureLine.text, false) - displayVerificationResult(verified) + RowLayout { + LineEdit { + id: signSignatureLine + labelText: qsTr("Signature") + placeholderText: qsTr("Signature") + translationManager.emptyString; + readOnly: true + Layout.fillWidth: true + copyButton: true } } } Label { - id: verifyMessageFileLabel - text: qsTr("Or file:") + translationManager.emptyString + id: verifyTitleLabel + fontSize: 24 * scaleRatio + Layout.topMargin: 40 + text: qsTr("Verify") + translationManager.emptyString } - RowLayout { - id: verifyFileRow - anchors.topMargin: 17 * scaleRatio - anchors.left: parent.left - anchors.right: parent.right + ColumnLayout { + RowLayout { + id: verifyMessageRow - FileDialog { - id: verifyFileDialog - title: qsTr("Please choose a file to verify") + translationManager.emptyString; - folder: "file://" - nameFilters: [ "*"] - - onAccepted: { - verifyFileLine.text = walletManager.urlToLocalPath(verifyFileDialog.fileUrl) + LineEdit { + id: verifyMessageLine + Layout.fillWidth: true + labelText: qsTr("Verify message") + placeholderText: qsTr("Message to verify") + translationManager.emptyString; + readOnly: false } } - StandardButton { - id: loadFileToVerifyButton - anchors.rightMargin: 17 * scaleRatio - text: qsTr("Select") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - enabled: true - onClicked: { - verifyFileDialog.open() - } - } - LineEdit { - id: verifyFileLine - anchors.left: loadFileToVerifyButton.right - anchors.right: verifyFileButton.left - placeholderText: qsTr("Filename with message to verify") + translationManager.emptyString; - readOnly: false + RowLayout{ Layout.fillWidth: true + Layout.topMargin: 18 - IconButton { - imageSource: "../images/copyToClipboard.png" + StandardButton { + id: verifyMessageButton + small: true + text: qsTr("Verify") + translationManager.emptyString + enabled: true onClicked: { - if (verifyFileLine.text.length > 0) { - clipboard.setText(verifyFileLine.text) - } + var verified = appWindow.currentWallet.verifySignedMessage(verifyMessageLine.text, verifyAddressLine.text, verifySignatureLine.text, false) + displayVerificationResult(verified) } } } + } - StandardButton { - id: verifyFileButton - anchors.right: parent.right - text: qsTr("Verify") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - enabled: true - onClicked: { - var verified = appWindow.currentWallet.verifySignedMessage(verifyFileLine.text, verifyAddressLine.text, verifySignatureLine.text, true) - displayVerificationResult(verified) + ColumnLayout { + RowLayout { + LineEdit { + id: verifyFileLine + labelText: qsTr("Verify file") + placeholderText: qsTr("Filename with message to verify") + translationManager.emptyString; + readOnly: false + Layout.fillWidth: true + } + } + + RowLayout{ + Layout.fillWidth: true + Layout.topMargin: 18 + + StandardButton { + id: loadFileToVerifyButton + small: true + text: qsTr("Browse") + translationManager.emptyString + enabled: true + onClicked: { + verifyFileDialog.open() + } + } + + StandardButton { + id: verifyFileButton + small: true + anchors.left: loadFileToVerifyButton.right + anchors.leftMargin: 20 + text: qsTr("Verify") + translationManager.emptyString + enabled: true + onClicked: { + var verified = appWindow.currentWallet.verifySignedMessage(verifyFileLine.text, verifyAddressLine.text, verifySignatureLine.text, true) + displayVerificationResult(verified) + } } } } - Text { - id: verifyAddressLabel - text: "" + - qsTr("Signing address") + - " ( " + - qsTr("Paste in or select from Address book") + - " )" + - translationManager.emptyString - wrapMode: Text.Wrap - font.pixelSize: 14 * scaleRatio - Layout.fillWidth: true - textFormat: Text.RichText - onLinkActivated: appWindow.showPageRequest("AddressBook") - } + ColumnLayout { + RowLayout{ - LineEdit { - id: verifyAddressLine - anchors.left: parent.left - anchors.right: parent.right - anchors.top: verifyAddressLabel.bottom - anchors.topMargin: 5 * scaleRatio - placeholderText: "4..." - // validator: RegExpValidator { regExp: /[0-9A-Fa-f]{95}/g } + LineEditMulti { + id: verifyAddressLine + Layout.fillWidth: true + labelText: qsTr("Address") + addressValidation: true + anchors.topMargin: 5 * scaleRatio + placeholderText: "4..." + } + } } ColumnLayout { @@ -419,18 +308,33 @@ Rectangle { id: verifySignatureLine placeholderText: qsTr("Signature") + translationManager.emptyString; Layout.fillWidth: true - - IconButton { - imageSource: "../images/copyToClipboard.png" - onClicked: { - if (verifySignatureLine.text.length > 0) { - clipboard.setText(verifySignatureLine.text) - } - } - } + copyButton: true } } } + + + FileDialog { + id: signFileDialog + title: qsTr("Please choose a file to sign") + translationManager.emptyString; + folder: "file://" + nameFilters: [ "*"] + + onAccepted: { + signFileLine.text = walletManager.urlToLocalPath(signFileDialog.fileUrl) + } + } + + FileDialog { + id: verifyFileDialog + title: qsTr("Please choose a file to verify") + translationManager.emptyString; + folder: "file://" + nameFilters: [ "*"] + + onAccepted: { + verifyFileLine.text = walletManager.urlToLocalPath(verifyFileDialog.fileUrl) + } + } } function onPageCompleted() { diff --git a/pages/Transfer.qml b/pages/Transfer.qml index 8e6daebf..db46f04d 100644 --- a/pages/Transfer.qml +++ b/pages/Transfer.qml @@ -29,9 +29,11 @@ import QtQuick 2.0 import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.2 +import moneroComponents.Clipboard 1.0 import moneroComponents.PendingTransaction 1.0 -import "../components" import moneroComponents.Wallet 1.0 +import "../components" +import "." 1.0 Rectangle { @@ -40,13 +42,12 @@ Rectangle { int priority, string description) signal sweepUnmixableClicked() - color: "#F0EEEE" - property string startLinkText: " (" + - qsTr("Start daemon") + - ")" + - translationManager.emptyString + color: "transparent" + property string startLinkText: qsTr(" (Start daemon)") + translationManager.emptyString property bool showAdvanced: false + Clipboard { id: clipboard } + function scaleValueToMixinCount(scaleValue) { var scaleToMixinCount = [6,7,8,9,10,11,12,13,14,16,18,20,22,25]; if (scaleValue < scaleToMixinCount.length) { @@ -112,43 +113,86 @@ Rectangle { ColumnLayout { id: pageRoot - anchors.top: parent.top + anchors.margins: (isMobile)? 17 : 20 + anchors.topMargin: 40 * scaleRatio + anchors.left: parent.left + anchors.top: parent.top anchors.right: parent.right - anchors.margins: 17 * scaleRatio - spacing: 0 + + spacing: 30 * scaleRatio + + RowLayout{ + visible: warningText.text !== "" + + Rectangle { + id: statusRect + Layout.preferredHeight: warningText.height + 40 + Layout.fillWidth: true + + radius: 2 + border.color: Qt.rgba(255, 255, 255, 0.25) + border.width: 1 + color: "transparent" + + GridLayout{ + Layout.fillWidth: true + Layout.preferredHeight: warningText.height + 40 + + Image { + Layout.alignment: Qt.AlignVCenter + Layout.preferredHeight: 33 + Layout.preferredWidth: 33 + Layout.leftMargin: 10 + Layout.topMargin: 10 + source: "../images/warning.png" + } + + Text { + id: warningText + Layout.topMargin: 12 * scaleRatio + Layout.preferredWidth: statusRect.width - 80 + Layout.leftMargin: 6 + text: qsTr("This page lets you sign/verify a message (or file contents) with your address.") + translationManager.emptyString + wrapMode: Text.Wrap + font.family: Style.fontRegular.name + font.pixelSize: 14 * scaleRatio + color: Style.defaultFontColor + textFormat: Text.RichText + onLinkActivated: { + appWindow.startDaemon(appWindow.persistentSettings.daemonFlags); + } + } + } + } + } GridLayout { columns: (isMobile)? 1 : 2 Layout.fillWidth: true + columnSpacing: 32 ColumnLayout { Layout.fillWidth: true - Label { - id: amountLabel - text: qsTr("Amount") + translationManager.emptyString - } RowLayout { - Layout.fillWidth: true id: amountRow - Layout.minimumWidth: 200 - Item { - visible: !isMobile - width: 37 * scaleRatio - height: 37 * scaleRatio - Image { - anchors.centerIn: parent - source: "../images/moneroIcon.png" - } - } + Layout.fillWidth: true + Layout.minimumWidth: 200 + // Amount input LineEdit { - Layout.fillWidth: true id: amountLine + Layout.fillWidth: true + inlineIcon: true + labelText: qsTr("Amount") + translationManager.emptyString placeholderText: qsTr("") + translationManager.emptyString - width:100 + width: 100 + fontBold: true + inlineButtonText: qsTr("All") + translationManager.emptyString + inlineButton.onClicked: amountLine.text = "(all)" + validator: DoubleValidator { bottom: 0.0 top: 18446744.073709551615 @@ -157,28 +201,17 @@ Rectangle { locale: "C" } } - - StandardButton { - id: amountAllButton - width: 60 * scaleRatio - text: qsTr("All") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - enabled : true - onClicked: amountLine.text = "(all)" - } } - - } ColumnLayout { Layout.fillWidth: true Label { id: transactionPriority + Layout.topMargin: 14 text: qsTr("Transaction priority") + translationManager.emptyString + fontBold: false + fontSize: 16 } // Note: workaround for translations in listElements // ListElement: cannot use script for property value, so @@ -186,7 +219,7 @@ Rectangle { // ListElement { column1: qsTr("LOW") + translationManager.emptyString ; column2: ""; priority: PendingTransaction.Priority_Low } // For translations to work, the strings need to be listed in // the file components/StandardDropdown.qml too. - + // Priorites after v5 ListModel { id: priorityModelV5 @@ -196,140 +229,116 @@ Rectangle { ListElement { column1: qsTr("Normal (x1 fee)") ; column2: ""; priority: 2 } ListElement { column1: qsTr("Fast (x5 fee)") ; column2: ""; priority: 3 } ListElement { column1: qsTr("Fastest (x41.5 fee)") ; column2: ""; priority: 4 } - } StandardDropdown { Layout.fillWidth: true id: priorityDropdown + Layout.topMargin: 6 shadowReleasedColor: "#FF4304" shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" + releasedColor: "#363636" + pressedColor: "#202020" } } // Make sure dropdown is on top z: parent.z + 1 } - ColumnLayout { + // recipient address input + RowLayout { + id: addressLineRow Layout.fillWidth: true - Label { - id: addressLabel - textFormat: Text.RichText - text: "" + - qsTr("Address") + - " ( " + - qsTr("Paste in or select from Address book") + - " )" + - translationManager.emptyString - onLinkActivated: appWindow.showPageRequest("AddressBook") - Layout.fillWidth: true - } - // recipient address input - RowLayout { - id: addressLineRow - Layout.fillWidth: true - StandardButton { - id: qrfinderButton - text: qsTr("QR Code") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - visible : appWindow.qrScannerEnabled - enabled : visible - width: visible ? 60 * scaleRatio : 0 - onClicked: { - cameraUi.state = "Capture" - cameraUi.qrcode_decoded.connect(updateFromQrCode) - } - } - LineEdit { - id: addressLine - Layout.fillWidth: true - anchors.topMargin: 5 * scaleRatio - placeholderText: "4..." - // validator: RegExpValidator { regExp: /[0-9A-Fa-f]{95}/g } - } - - StandardButton { - id: resolveButton - width: 60 * scaleRatio - text: qsTr("Resolve") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - enabled : isValidOpenAliasAddress(addressLine.text) - onClicked: { - var result = walletManager.resolveOpenAlias(addressLine.text) - if (result) { - var parts = result.split("|") - if (parts.length == 2) { - var address_ok = walletManager.addressValid(parts[1], appWindow.persistentSettings.nettype) - if (parts[0] === "true") { - if (address_ok) { - addressLine.text = parts[1] - addressLine.cursorPosition = 0 - } - else - oa_message(qsTr("No valid address found at this OpenAlias address")) - } else if (parts[0] === "false") { - if (address_ok) { - addressLine.text = parts[1] - addressLine.cursorPosition = 0 - oa_message(qsTr("Address found, but the DNSSEC signatures could not be verified, so this address may be spoofed")) - } else { - oa_message(qsTr("No valid address found at this OpenAlias address, but the DNSSEC signatures could not be verified, so this may be spoofed")) - } - } else { - oa_message(qsTr("Internal error")) - } + LineEditMulti { + id: addressLine + spacing: 0 + fontBold: true + labelText: qsTr("\ + Address ( Address book )") + + translationManager.emptyString + labelButtonText: qsTr("Resolve") + translationManager.emptyString + placeholderText: "4.." + onInputLabelLinkActivated: { appWindow.showPageRequest("AddressBook") } + onLabelButtonClicked: { + var result = walletManager.resolveOpenAlias(addressLine.text) + if (result) { + var parts = result.split("|") + if (parts.length == 2) { + var address_ok = walletManager.addressValid(parts[1], appWindow.persistentSettings.nettype) + if (parts[0] === "true") { + if (address_ok) { + addressLine.text = parts[1] + addressLine.cursorPosition = 0 + } + else + oa_message(qsTr("No valid address found at this OpenAlias address")) + } else if (parts[0] === "false") { + if (address_ok) { + addressLine.text = parts[1] + addressLine.cursorPosition = 0 + oa_message(qsTr("Address found, but the DNSSEC signatures could not be verified, so this address may be spoofed")) } else { - oa_message(qsTr("Internal error")) + oa_message(qsTr("No valid address found at this OpenAlias address, but the DNSSEC signatures could not be verified, so this may be spoofed")) } } else { - oa_message(qsTr("No address found")) + oa_message(qsTr("Internal error")) } + } else { + oa_message(qsTr("Internal error")) + } + } else { + oa_message(qsTr("No address found")) } } } - Label { - id: paymentIdLabel - text: qsTr("Payment ID ( Optional )") + translationManager.emptyString - } - - // payment id input - LineEdit { - id: paymentIdLine - placeholderText: qsTr("16 or 64 hexadecimal characters") + translationManager.emptyString - Layout.fillWidth: true - } - - Label { - text: qsTr("Description ( Optional )") - + translationManager.emptyString - } - - LineEdit { - id: descriptionLine - placeholderText: qsTr("Saved to local wallet history") + translationManager.emptyString - Layout.fillWidth: true - } - + StandardButton { + id: qrfinderButton + text: qsTr("QR Code") + translationManager.emptyString + visible : appWindow.qrScannerEnabled + enabled : visible + width: visible ? 60 * scaleRatio : 0 + onClicked: { + cameraUi.state = "Capture" + cameraUi.qrcode_decoded.connect(updateFromQrCode) + } + } + } + + RowLayout { + // payment id input + LineEdit { + id: paymentIdLine + fontBold: true + labelText: qsTr("Payment ID ( Optional )") + translationManager.emptyString + placeholderText: qsTr("16 or 64 hexadecimal characters") + translationManager.emptyString + Layout.fillWidth: true + } + } + + RowLayout { + LineEdit { + id: descriptionLine + labelText: qsTr("Description ( Optional )") + translationManager.emptyString + placeholderText: qsTr("Saved to local wallet history") + translationManager.emptyString + Layout.fillWidth: true + } + } + + RowLayout { StandardButton { id: sendButton - Layout.bottomMargin: 17 * scaleRatio - Layout.topMargin: 17 * scaleRatio + rightIcon: "../images/rightIcon.png" + Layout.topMargin: 4 * scaleRatio text: qsTr("Send") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - enabled : !appWindow.viewOnly && pageRoot.checkInformation(amountLine.text, addressLine.text, paymentIdLine.text, appWindow.persistentSettings.nettype) + enabled : { + // Send button is enabled when: + // 1) Currently opened wallet is not view-only + // 2) There is no warning box displayed + // 3) The transactional information is correct + return !appWindow.viewOnly && warningText.text === '' && pageRoot.checkInformation(amountLine.text, addressLine.text, paymentIdLine.text, appWindow.persistentSettings.nettype); + } onClicked: { console.log("Transfer: paymentClicked") var priority = priorityModelV5.get(priorityDropdown.currentIndex).priority @@ -365,7 +374,7 @@ Rectangle { } // pageRoot Rectangle { - id:desaturate + id: desaturate color:"black" anchors.fill: parent opacity: 0.1 @@ -376,22 +385,19 @@ Rectangle { anchors.top: pageRoot.bottom anchors.left: parent.left anchors.right: parent.right - anchors.leftMargin: 17 * scaleRatio - anchors.topMargin: 17 * scaleRatio - anchors.bottomMargin: 17 * scaleRatio - spacing: 10 * scaleRatio + anchors.margins: (isMobile)? 17 : 20 + anchors.topMargin: 32 * scaleRatio + spacing: 26 * scaleRatio enabled: !viewOnly || pageRoot.enabled RowLayout { - CheckBox { + CheckBox2 { id: showAdvancedCheckbox checked: persistentSettings.transferShowAdvanced onClicked: { persistentSettings.transferShowAdvanced = !persistentSettings.transferShowAdvanced } - text: qsTr("Show advanced options") + translationManager.emptyString - checkedIcon: "../images/checkedVioletIcon.png" - uncheckedIcon: "../images/uncheckedIcon.png" + text: qsTr("Advanced options") + translationManager.emptyString } } @@ -399,7 +405,8 @@ Rectangle { visible: persistentSettings.transferShowAdvanced Layout.fillWidth: true height: 1 - color: "#DEDEDE" + color: Style.dividerColor + opacity: Style.dividerOpacity Layout.bottomMargin: 30 * scaleRatio } @@ -410,7 +417,7 @@ Rectangle { Layout.fillWidth: true Label { id: privacyLabel - fontSize: 14 + fontSize: 15 text: "" } @@ -422,8 +429,6 @@ Rectangle { } } - - PrivacyLevel { visible: persistentSettings.transferShowAdvanced && !isMobile id: privacyLevelItem @@ -442,7 +447,6 @@ Rectangle { onFillLevelChanged: updateMixin() } - GridLayout { visible: persistentSettings.transferShowAdvanced Layout.topMargin: 50 * scaleRatio @@ -453,11 +457,8 @@ Rectangle { StandardButton { id: sweepUnmixableButton text: qsTr("Sweep Unmixable") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" enabled : pageRoot.enabled + small: true onClicked: { console.log("Transfer: sweepUnmixableClicked") root.sweepUnmixableClicked() @@ -467,12 +468,9 @@ Rectangle { StandardButton { id: saveTxButton text: qsTr("Create tx file") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" visible: appWindow.viewOnly enabled: pageRoot.checkInformation(amountLine.text, addressLine.text, paymentIdLine.text, appWindow.persistentSettings.nettype) + small: true onClicked: { console.log("Transfer: saveTx Clicked") var priority = priorityModelV5.get(priorityDropdown.currentIndex).priority @@ -489,10 +487,7 @@ Rectangle { StandardButton { id: signTxButton text: qsTr("Sign tx file") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" + small: true visible: !appWindow.viewOnly onClicked: { console.log("Transfer: sign tx clicked") @@ -503,10 +498,7 @@ Rectangle { StandardButton { id: submitTxButton text: qsTr("Submit tx file") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" + small: true visible: appWindow.viewOnly enabled: pageRoot.enabled onClicked: { @@ -515,12 +507,8 @@ Rectangle { } } } - - } - - //SignTxDialog FileDialog { id: signTxDialog @@ -598,7 +586,7 @@ Rectangle { informationPopup.open(); } else { informationPopup.title = qsTr("Information") + translationManager.emptyString - informationPopup.text = qsTr("Money sent successfully") + translationManager.emptyString + informationPopup.text = qsTr("Monero sent successfully") + translationManager.emptyString informationPopup.icon = StandardIcon.Information informationPopup.onCloseCallback = null informationPopup.open(); @@ -610,23 +598,7 @@ Rectangle { } - Rectangle { - x: root.width/2 - width/2 - y: root.height/2 - height/2 - height:statusText.paintedHeight + 50 * scaleRatio - width:statusText.paintedWidth + 40 * scaleRatio - visible: statusText.text != "" - opacity: 0.9 - Text { - id: statusText - anchors.fill:parent - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - textFormat: Text.RichText - onLinkActivated: { appWindow.startDaemon(appWindow.persistentSettings.daemonFlags); } - } - } Component.onCompleted: { //Disable password page until enabled by updateStatus @@ -651,35 +623,35 @@ Rectangle { //TODO: enable send page when we're connected and daemon is synced function updateStatus() { + pageRoot.enabled = true; if(typeof currentWallet === "undefined") { - statusText.text = qsTr("Wallet is not connected to daemon.") + "
" + root.startLinkText + warningText.text = qsTr("Wallet is not connected to daemon.") + root.startLinkText return; } if (currentWallet.viewOnly) { - // statusText.text = qsTr("Wallet is view only.") + // warningText.text = qsTr("Wallet is view only.") //return; } - pageRoot.enabled = false; + //pageRoot.enabled = false; switch (currentWallet.connected()) { case Wallet.ConnectionStatus_Disconnected: - statusText.text = qsTr("Wallet is not connected to daemon.") + "
" + root.startLinkText + warningText.text = qsTr("Wallet is not connected to daemon.") + root.startLinkText break case Wallet.ConnectionStatus_WrongVersion: - statusText.text = qsTr("Connected daemon is not compatible with GUI. \n" + + warningText.text = qsTr("Connected daemon is not compatible with GUI. \n" + "Please upgrade or connect to another daemon") break default: if(!appWindow.daemonSynced){ - statusText.text = qsTr("Waiting on daemon synchronization to finish") + warningText.text = qsTr("Waiting on daemon synchronization to finish") } else { // everything OK, enable transfer page // Light wallet is always ready pageRoot.enabled = true; - statusText.text = ""; + warningText.text = ""; } - } } diff --git a/pages/TxKey.qml b/pages/TxKey.qml index e0455168..791d8f7c 100644 --- a/pages/TxKey.qml +++ b/pages/TxKey.qml @@ -34,321 +34,204 @@ import QtQuick.Layouts 1.1 import "../components" import moneroComponents.Clipboard 1.0 +import "../js/TxUtils.js" as TxUtils + Rectangle { - color: "#F0EEEE" + color: "transparent" Clipboard { id: clipboard } - function checkAddress(address, nettype) { - return walletManager.addressValid(address, nettype) - } - - function check256(str, length) { - if (str.length != length) - return false; - for (var i = 0; i < length; ++i) { - if (str[i] >= '0' && str[i] <= '9') - continue; - if (str[i] >= 'a' && str[i] <= 'z') - continue; - if (str[i] >= 'A' && str[i] <= 'Z') - continue; - return false; - } - return true; - } - - function checkTxID(txid) { - return check256(txid, 64) - } - - function checkSignature(signature) { - if (signature.indexOf("OutProofV") === 0) { - if ((signature.length - 10) % 132 != 0) - return false; - return check256(signature, signature.length); - } else if (signature.indexOf("InProofV") === 0) { - if ((signature.length - 9) % 132 != 0) - return false; - return check256(signature, signature.length); - } else if (signature.indexOf("SpendProofV") === 0) { - if ((signature.length - 12) % 88 != 0) - return false; - return check256(signature, signature.length); - } - return false; - } - /* main layout */ ColumnLayout { id: mainLayout - anchors.margins: 40 + anchors.margins: 40 * scaleRatio anchors.left: parent.left anchors.top: parent.top anchors.right: parent.right + anchors.bottom: parent.bottom + spacing: 20 * scaleRatio - spacing: 20 - property int labelWidth: 120 - property int editWidth: 400 - property int lineEditFontSize: 12 - - Text { - text: qsTr("Generate a proof of your incoming/outgoing payment by supplying the transaction ID, the recipient address and an optional message. \n" + - "For the case of outgoing payments, you can get a 'Spend Proof' that proves the authorship of a transaction. In this case, you don't need to specify the recipient address.") + translationManager.emptyString - wrapMode: Text.Wrap - Layout.fillWidth: true; - } - - RowLayout { - Label { - fontSize: 14 - text: qsTr("Transaction ID") + translationManager.emptyString - width: mainLayout.labelWidth - } - - LineEdit { - id: getProofTxIdLine - fontSize: mainLayout.lineEditFontSize - placeholderText: qsTr("Paste tx ID") + translationManager.emptyString - readOnly: false - width: mainLayout.editWidth - Layout.fillWidth: true - - IconButton { - imageSource: "../images/copyToClipboard.png" - onClicked: { - if (getProofTxIdLine.text.length > 0) { - clipboard.setText(getProofTxIdLine.text) - } - } - } - - } - } - - RowLayout { - Label { - fontSize: 14 - text: qsTr("Address") + translationManager.emptyString - width: mainLayout.labelWidth - } - - LineEdit { - id: getProofAddressLine - fontSize: mainLayout.lineEditFontSize - placeholderText: qsTr("Recipient's wallet address") + translationManager.emptyString; - readOnly: false - width: mainLayout.editWidth - Layout.fillWidth: true - - IconButton { - imageSource: "../images/copyToClipboard.png" - onClicked: { - if (getProofAddressLine.text.length > 0) { - clipboard.setText(getProofAddressLine.text) - } - } - } - } - } - - RowLayout { - Label { - fontSize: 14 - text: qsTr("Message") + translationManager.emptyString - width: mainLayout.labelWidth - } - - LineEdit { - id: getProofMessageLine - fontSize: mainLayout.lineEditFontSize - placeholderText: qsTr("Optional message against which the signature is signed") + translationManager.emptyString; - readOnly: false - width: mainLayout.editWidth - Layout.fillWidth: true - - IconButton { - imageSource: "../images/copyToClipboard.png" - onClicked: { - if (getProofMessageLine.text.length > 0) { - clipboard.setText(getProofMessageLine.text) - } - } - } - } - } - - StandardButton { + // solo + ColumnLayout { + id: soloBox anchors.left: parent.left - anchors.topMargin: 17 - width: 60 - text: qsTr("Generate") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - enabled: checkTxID(getProofTxIdLine.text) && (getProofAddressLine.text.length == 0 || checkAddress(getProofAddressLine.text, appWindow.persistentSettings.nettype)) - onClicked: { - console.log("getProof: Generate clicked: txid " + getProofTxIdLine.text + ", address " + getProofAddressLine.text + ", message: " + getProofMessageLine.text); - root.getProofClicked(getProofTxIdLine.text, getProofAddressLine.text, getProofMessageLine.text) - } - } + anchors.right: parent.right + anchors.top: parent.top + spacing: 20 * scaleRatio - // underline - Rectangle { - height: 1 - color: "#DBDBDB" - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - anchors.bottomMargin: 3 - - } - - Text { - text: qsTr("Verify that funds were paid to an address by supplying the transaction ID, the recipient address, the message used for signing and the signature.\n" + - "For the case with Spend Proof, you don't need to specify the recipient address.") + translationManager.emptyString - wrapMode: Text.Wrap - Layout.fillWidth: true; - } - - RowLayout { Label { - fontSize: 14 - text: qsTr("Transaction ID") + translationManager.emptyString - width: mainLayout.labelWidth + id: soloTitleLabel + fontSize: 24 * scaleRatio + text: qsTr("Prove Transaction") + translationManager.emptyString } - LineEdit { - id: checkProofTxIdLine - fontSize: mainLayout.lineEditFontSize - placeholderText: qsTr("Paste tx ID") + translationManager.emptyString - readOnly: false - width: mainLayout.editWidth + Text { + text: qsTr("Generate a proof of your incoming/outgoing payment by supplying the transaction ID, the recipient address and an optional message. \n" + + "For the case of outgoing payments, you can get a 'Spend Proof' that proves the authorship of a transaction. In this case, you don't need to specify the recipient address.") + translationManager.emptyString + wrapMode: Text.Wrap Layout.fillWidth: true - - IconButton { - imageSource: "../images/copyToClipboard.png" - onClicked: { - if (checkProofTxIdLine.text.length > 0) { - clipboard.setText(checkProofTxIdLine.text) - } - } - } - - } - } - - RowLayout { - Label { - fontSize: 14 - text: qsTr("Address") + translationManager.emptyString - width: mainLayout.labelWidth + font.family: Style.fontRegular.name + font.pixelSize: 14 * scaleRatio + color: Style.defaultFontColor } - LineEdit { - id: checkProofAddressLine - fontSize: mainLayout.lineEditFontSize - placeholderText: qsTr("Recipient's wallet address") + translationManager.emptyString; - readOnly: false - width: mainLayout.editWidth - Layout.fillWidth: true - - IconButton { - imageSource: "../images/copyToClipboard.png" - onClicked: { - if (checkProofAddressLine.text.length > 0) { - clipboard.setText(checkProofAddressLine.text) - } - } + RowLayout { + LineEdit { + labelText: qsTr("Transaction ID") + translationManager.emptyString + id: getProofTxIdLine + fontSize: 16 * scaleRatio + placeholderText: qsTr("Paste tx ID") + translationManager.emptyString + readOnly: false + Layout.fillWidth: true + copyButton: true } } - } - RowLayout { - Label { - fontSize: 14 - text: qsTr("Message") + translationManager.emptyString - width: mainLayout.labelWidth - } - - LineEdit { - id: checkProofMessageLine - fontSize: mainLayout.lineEditFontSize - placeholderText: qsTr("Optional message against which the signature is signed") + translationManager.emptyString; - readOnly: false - width: mainLayout.editWidth - Layout.fillWidth: true - - IconButton { - imageSource: "../images/copyToClipboard.png" - onClicked: { - if (checkProofMessageLine.text.length > 0) { - clipboard.setText(checkProofMessageLine.text) - } - } + RowLayout { + LineEdit { + id: getProofAddressLine + labelText: qsTr("Address") + translationManager.emptyString + fontSize: 16 * scaleRatio + placeholderText: qsTr("Recipient's wallet address") + translationManager.emptyString; + readOnly: false + Layout.fillWidth: true + copyButton: true } } - } - RowLayout { - Label { - fontSize: 14 - text: qsTr("Signature") + translationManager.emptyString - width: mainLayout.labelWidth - } - - - LineEdit { - id: checkProofSignatureLine - fontSize: mainLayout.lineEditFontSize - placeholderText: qsTr("Paste tx proof") + translationManager.emptyString; - readOnly: false - - width: mainLayout.editWidth - Layout.fillWidth: true - - IconButton { - imageSource: "../images/copyToClipboard.png" - onClicked: { - if (checkProofSignatureLine.text.length > 0) { - clipboard.setText(checkProofSignatureLine.text) - } - } + RowLayout { + LineEdit { + id: getProofMessageLine + fontSize: 16 * scaleRatio + labelText: qsTr("Message") + translationManager.emptyString + placeholderText: qsTr("Optional message against which the signature is signed") + translationManager.emptyString; + readOnly: false + width: mainLayout.editWidth + Layout.fillWidth: true + copyButton: true } } - } - StandardButton { - anchors.left: parent.left - anchors.topMargin: 17 - width: 60 - text: qsTr("Check") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" - enabled: checkTxID(checkProofTxIdLine.text) && checkSignature(checkProofSignatureLine.text) && ((checkProofSignatureLine.text.indexOf("SpendProofV") === 0 && checkProofAddressLine.text.length == 0) || (checkProofSignatureLine.text.indexOf("SpendProofV") !== 0 && checkAddress(checkProofAddressLine.text, appWindow.persistentSettings.nettype))) - onClicked: { - console.log("checkProof: Check clicked: txid " + checkProofTxIdLine.text + ", address " + checkProofAddressLine.text + ", message " + checkProofMessageLine.text + ", signature " + checkProofSignatureLine.text); - root.checkProofClicked(checkProofTxIdLine.text, checkProofAddressLine.text, checkProofMessageLine.text, checkProofSignatureLine.text) + StandardButton { + anchors.left: parent.left + anchors.topMargin: 17 * scaleRatio + width: 60 * scaleRatio + text: qsTr("Generate") + translationManager.emptyString + enabled: TxUtils.checkTxID(getProofTxIdLine.text) && (getProofAddressLine.text.length == 0 || TxUtils.checkAddress(getProofAddressLine.text, appWindow.persistentSettings.nettype)) + onClicked: { + console.log("getProof: Generate clicked: txid " + getProofTxIdLine.text + ", address " + getProofAddressLine.text + ", message: " + getProofMessageLine.text); + root.getProofClicked(getProofTxIdLine.text, getProofAddressLine.text, getProofMessageLine.text) + } } - } - // underline - Rectangle { - height: 1 - color: "#DBDBDB" - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - anchors.bottomMargin: 3 + // underline + Rectangle { + height: 1 + color: "#404040" + Layout.fillWidth: true + Layout.alignment: Qt.AlignHCenter + anchors.bottomMargin: 3 * scaleRatio + } - } + Label { + id: soloTitleLabel2 + fontSize: 24 * scaleRatio + text: qsTr("Check Transaction") + translationManager.emptyString + } - Text { - text: qsTr("If a payment had several transactions then each must be checked and the results combined.") + translationManager.emptyString - wrapMode: Text.Wrap - Layout.fillWidth: true; + Text { + text: qsTr("Verify that funds were paid to an address by supplying the transaction ID, the recipient address, the message used for signing and the signature.\n" + + "For the case with Spend Proof, you don't need to specify the recipient address.") + translationManager.emptyString + wrapMode: Text.Wrap + Layout.fillWidth: true + font.family: Style.fontRegular.name + font.pixelSize: 14 * scaleRatio + color: Style.defaultFontColor + } + + RowLayout { + LineEdit { + id: checkProofTxIdLine + labelText: qsTr("Transaction ID") + translationManager.emptyString + fontSize: 16 * scaleRatio + placeholderText: qsTr("Paste tx ID") + translationManager.emptyString + readOnly: false + width: mainLayout.editWidth + Layout.fillWidth: true + copyButton: true + } + } + + RowLayout { + LineEdit { + id: checkProofAddressLine + labelText: qsTr("Address") + translationManager.emptyString + fontSize: 16 * scaleRatio + placeholderText: qsTr("Recipient's wallet address") + translationManager.emptyString; + readOnly: false + width: mainLayout.editWidth + Layout.fillWidth: true + copyButton: true + } + } + + RowLayout { + LineEdit { + id: checkProofMessageLine + fontSize: 16 * scaleRatio + labelText: qsTr("Message") + translationManager.emptyString + placeholderText: qsTr("Optional message against which the signature is signed") + translationManager.emptyString; + readOnly: false + width: mainLayout.editWidth + Layout.fillWidth: true + copyButton: true + } + } + + RowLayout { + LineEdit { + id: checkProofSignatureLine + fontSize: 16 * scaleRatio + labelText: qsTr("Signature") + translationManager.emptyString + placeholderText: qsTr("Paste tx proof") + translationManager.emptyString; + readOnly: false + width: mainLayout.editWidth + Layout.fillWidth: true + copyButton: true + } + } + + StandardButton { + anchors.left: parent.left + anchors.topMargin: 17 * scaleRatio + width: 60 + text: qsTr("Check") + translationManager.emptyString + enabled: TxUtils.checkTxID(checkProofTxIdLine.text) && TxUtils.checkSignature(checkProofSignatureLine.text) && ((checkProofSignatureLine.text.indexOf("SpendProofV") === 0 && checkProofAddressLine.text.length == 0) || (checkProofSignatureLine.text.indexOf("SpendProofV") !== 0 && TxUtils.checkAddress(checkProofAddressLine.text, appWindow.persistentSettings.nettype))) + onClicked: { + console.log("checkProof: Check clicked: txid " + checkProofTxIdLine.text + ", address " + checkProofAddressLine.text + ", message " + checkProofMessageLine.text + ", signature " + checkProofSignatureLine.text); + root.checkProofClicked(checkProofTxIdLine.text, checkProofAddressLine.text, checkProofMessageLine.text, checkProofSignatureLine.text) + } + } + + // underline + Rectangle { + height: 1 + color: "#404040" + Layout.fillWidth: true + Layout.alignment: Qt.AlignHCenter + anchors.bottomMargin: 3 * scaleRatio + + } + + Text { + text: qsTr("If a payment had several transactions then each must be checked and the results combined.") + translationManager.emptyString + wrapMode: Text.Wrap + Layout.fillWidth: true + font.family: Style.fontRegular.name + font.pixelSize: 14 * scaleRatio + color: Style.defaultFontColor + } } } @@ -356,5 +239,4 @@ Rectangle { console.log("TxKey page loaded"); } - } diff --git a/qml.qrc b/qml.qrc index 86f7dde3..8f00900f 100644 --- a/qml.qrc +++ b/qml.qrc @@ -163,5 +163,47 @@ pages/Keys.qml images/menu.png images/appicon.ico + images/right.png + images/card-background.png + images/minimize.png + images/fullscreen.png + images/close.png + images/moneroLogo_white.png + images/moneroIcon-trans28x28.png + images/moneroIcon-trans84x84.png + images/moneroIcon-trans56x56.png + images/question.png + images/expand.png + images/titlebarGradient.jpg + images/titlebarLogo.png + images/menuArrow.png + images/menuButtonGradient.png + fonts/SFUIDisplay-Medium.otf + fonts/SFUIDisplay-Regular.otf + fonts/SFUIDisplay-Light.otf + fonts/SFUIDisplay-Bold.otf + components/Style.qml + components/qmldir + components/InlineButton.qml + images/lightning.png + images/leftPanelBg.jpg + images/moneroIcon-28x28.png + images/lightning-white.png + images/middlePanelBg.jpg + components/InputMulti.qml + images/checkedIcon-black.png + components/LineEditMulti.qml + components/LabelButton.qml + components/LabelSubheader.qml + images/arrow-right-medium-white.png + images/rightArrow.png + images/upArrow-green.png + images/downArrow.png + images/historyBorderRadius.png + components/HistoryTableInnerColumn.qml + components/CheckBox2.qml + js/TxUtils.js + images/warning.png + images/checkedBlackIcon.png diff --git a/wizard/WizardConfigure.qml b/wizard/WizardConfigure.qml index 88d10a31..c7184f95 100644 --- a/wizard/WizardConfigure.qml +++ b/wizard/WizardConfigure.qml @@ -100,8 +100,6 @@ Item { background: "#F0EEEE" fontColor: "#4A4646" fontSize: 18 - checkedIcon: "../images/checkedVioletIcon.png" - uncheckedIcon: "../images/uncheckedIcon.png" checked: true } @@ -129,8 +127,6 @@ Item { background: "#F0EEEE" fontColor: "#4A4646" fontSize: 18 - checkedIcon: "../images/checkedVioletIcon.png" - uncheckedIcon: "../images/uncheckedIcon.png" checked: true } @@ -160,8 +156,6 @@ Item { background: "#F0EEEE" fontColor: "#4A4646" fontSize: 18 - checkedIcon: "../images/checkedVioletIcon.png" - uncheckedIcon: "../images/uncheckedIcon.png" checked: true } diff --git a/wizard/WizardDaemonSettings.qml b/wizard/WizardDaemonSettings.qml index ca15fc44..c0a45e7a 100644 --- a/wizard/WizardDaemonSettings.qml +++ b/wizard/WizardDaemonSettings.qml @@ -124,11 +124,10 @@ ColumnLayout { CheckBox { id: localNode text: qsTr("Start a node automatically in background (recommended)") + translationManager.emptyString + checkedIcon: "../images/checkedBlackIcon.png" background: "#FFFFFF" fontColor: "#4A4646" fontSize: 16 * scaleRatio - checkedIcon: "../images/checkedVioletIcon.png" - uncheckedIcon: "../images/uncheckedIcon.png" checked: !appWindow.persistentSettings.useRemoteNode && !isAndroid && !isIOS visible: !isAndroid && !isIOS onClicked: { @@ -145,6 +144,7 @@ ColumnLayout { Layout.fillWidth: true Layout.topMargin: 20 * scaleRatio fontSize: 14 * scaleRatio + fontColor: "black" text: qsTr("Blockchain location") + translationManager.emptyString } LineEdit { @@ -152,8 +152,17 @@ ColumnLayout { Layout.preferredWidth: 200 * scaleRatio Layout.fillWidth: true text: persistentSettings.blockchainDataDir + placeholderFontBold: true + placeholderFontFamily: "Arial" + placeholderColor: Style.legacy_placeholderFontColor + placeholderOpacity: 1.0 placeholderText: qsTr("(optional)") + translationManager.emptyString + borderColor: Qt.rgba(0, 0, 0, 0.15) + backgroundColor: "white" + fontColor: "black" + fontBold: false + MouseArea { anchors.fill: parent onClicked: { @@ -170,14 +179,28 @@ ColumnLayout { Layout.fillWidth: true Layout.topMargin: 20 * scaleRatio fontSize: 14 * scaleRatio + color: 'black' text: qsTr("Bootstrap node (leave blank if not wanted)") + translationManager.emptyString } RemoteNodeEdit { Layout.minimumWidth: 300 * scaleRatio opacity: localNode.checked id: bootstrapNodeEdit + + placeholderFontBold: true + placeholderFontFamily: "Arial" + placeholderColor: Style.legacy_placeholderFontColor + placeholderOpacity: 1.0 + daemonAddrText: persistentSettings.bootstrapNodeAddress.split(":")[0].trim() - daemonPortText: (persistentSettings.bootstrapNodeAddress.split(":")[1].trim() == "") ? "18081" : persistentSettings.bootstrapNodeAddress.split(":")[1] + daemonPortText: { + var node_split = persistentSettings.bootstrapNodeAddress.split(":"); + if(node_split.length == 2){ + (node_split[1].trim() == "") ? "18081" : node_split[1]; + } else { + return "" + } + } } } @@ -185,19 +208,17 @@ ColumnLayout { CheckBox { id: remoteNode text: qsTr("Connect to a remote node") + translationManager.emptyString + checkedIcon: "../images/checkedBlackIcon.png" Layout.topMargin: 20 * scaleRatio background: "#FFFFFF" fontColor: "#4A4646" fontSize: 16 * scaleRatio - checkedIcon: "../images/checkedVioletIcon.png" - uncheckedIcon: "../images/uncheckedIcon.png" checked: appWindow.persistentSettings.useRemoteNode onClicked: { checked = true localNode.checked = false } } - } RowLayout { @@ -208,6 +229,16 @@ ColumnLayout { property var rna: persistentSettings.remoteNodeAddress daemonAddrText: rna.search(":") != -1 ? rna.split(":")[0].trim() : "" daemonPortText: rna.search(":") != -1 ? (rna.split(":")[1].trim() == "") ? "18081" : persistentSettings.remoteNodeAddress.split(":")[1] : "" + + placeholderFontBold: true + placeholderFontFamily: "Arial" + placeholderColor: Style.legacy_placeholderFontColor + placeholderOpacity: 1.0 + + lineEditBorderColor: Qt.rgba(0, 0, 0, 0.15) + lineEditBackgroundColor: "white" + lineEditFontColor: "black" + lineEditFontBold: false } } } diff --git a/wizard/WizardDonation.qml b/wizard/WizardDonation.qml index 1fccbebb..a5ebb6cc 100644 --- a/wizard/WizardDonation.qml +++ b/wizard/WizardDonation.qml @@ -114,8 +114,6 @@ Item { background: "#F0EEEE" fontColor: "#4A4646" fontSize: 18 - checkedIcon: "../images/checkedVioletIcon.png" - uncheckedIcon: "../images/uncheckedIcon.png" checked: true } @@ -179,8 +177,6 @@ Item { background: "#F0EEEE" fontColor: "#4A4646" fontSize: 18 - checkedIcon: "../images/checkedVioletIcon.png" - uncheckedIcon: "../images/uncheckedIcon.png" checked: true } diff --git a/wizard/WizardFinish.qml b/wizard/WizardFinish.qml index 0ab50706..a25fc1c1 100644 --- a/wizard/WizardFinish.qml +++ b/wizard/WizardFinish.qml @@ -52,13 +52,15 @@ ColumnLayout { backgroundMiningEnabled = wizard.settings["allow_background_mining"] === true, backgroundMiningText = backgroundMiningEnabled ? qsTr("Enabled") : qsTr("Disabled"), nettype = appWindow.persistentSettings.nettype, - networkText = nettype === NetworkType.TESTNET ? qsTr("Testnet") : nettype === NetworkType.STAGENET ? qsTr("Stagenet") : qsTr("Mainnet"), + networkText = nettype == NetworkType.TESTNET ? qsTr("Testnet") : nettype == NetworkType.STAGENET ? qsTr("Stagenet") : qsTr("Mainnet"), restoreHeightEnabled = wizard.settings['restore_height'] !== undefined; return "" + trStart + qsTr("Language") + trMiddle + wizard.settings["language"] + trEnd + trStart + qsTr("Wallet name") + trMiddle + wizard.settings["account_name"] + trEnd - + trStart + qsTr("Backup seed") + trMiddle + wizard.settings["wallet"].seed + trEnd + // TODO: wizard.settings['wallet'].seed doesnt work anymore; yields undefined. +// + trStart + qsTr("Backup seed") + trMiddle + wizard.settings["wallet"].seed + trEnd + + trStart + qsTr("Backup seed") + trMiddle + '****' + trEnd + trStart + qsTr("Wallet path") + trMiddle + wizard.settings["wallet_path"] + trEnd // + trStart + qsTr("Auto donations") + trMiddle + autoDonationText + trEnd // + (autoDonationEnabled diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index 05a4099e..ec685fe4 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -365,10 +365,6 @@ ColumnLayout { anchors.bottom: parent.bottom anchors.margins: (isMobile) ? 20 * scaleRatio : 50 * scaleRatio text: qsTr("USE MONERO") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" visible: parent.paths[currentPath][currentPage] === finishPage onClicked: { wizard.applySettings(); @@ -382,10 +378,6 @@ ColumnLayout { anchors.bottom: parent.bottom anchors.margins: (isMobile) ? 20 * scaleRatio : 50 text: qsTr("Create wallet") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" visible: currentPath === "create_view_only_wallet" && parent.paths[currentPath][currentPage] === passwordPage enabled: passwordPage.passwordsMatch onClicked: { @@ -414,10 +406,6 @@ ColumnLayout { anchors.bottom: parent.bottom anchors.margins: (isMobile) ? 20 * scaleRatio : 50 text: qsTr("Abort") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" visible: currentPath === "create_view_only_wallet" && parent.paths[currentPath][currentPage] === passwordPage onClicked: { wizard.restart(); diff --git a/wizard/WizardManageWalletUI.qml b/wizard/WizardManageWalletUI.qml index b83648a7..51eb8204 100644 --- a/wizard/WizardManageWalletUI.qml +++ b/wizard/WizardManageWalletUI.qml @@ -154,6 +154,8 @@ ColumnLayout { Label { Layout.topMargin: 20 * scaleRatio + fontFamily: "Arial" + fontColor: "#555555" fontSize: 14 * scaleRatio text: qsTr("Wallet name") + translationManager.emptyString @@ -166,6 +168,10 @@ ColumnLayout { Layout.minimumWidth: 200 * scaleRatio text: defaultAccountName onTextUpdated: checkNextButton() + borderColor: Qt.rgba(0, 0, 0, 0.15) + backgroundColor: "white" + fontColor: "black" + fontBold: false } } @@ -176,10 +182,6 @@ ColumnLayout { StandardButton { id: recoverFromSeedButton text: qsTr("Restore from seed") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" enabled: recoverFromKeys.visible onClicked: { recoverFromSeedMode = true; @@ -190,10 +192,6 @@ ColumnLayout { StandardButton { id: recoverFromKeysButton text: qsTr("Restore from keys") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" enabled: recoverFromSeed.visible onClicked: { recoverFromSeedMode = false; @@ -204,10 +202,6 @@ ColumnLayout { StandardButton { id: qrfinderButton text: qsTr("From QR Code") + translationManager.emptyString - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" visible : true //appWindow.qrScannerEnabled enabled : visible onClicked: { @@ -242,16 +236,32 @@ ColumnLayout { id: addressLine Layout.maximumWidth: 600 * scaleRatio Layout.minimumWidth: 200 * scaleRatio + placeholderFontBold: true + placeholderFontFamily: "Arial" + placeholderColor: Style.legacy_placeholderFontColor placeholderText: qsTr("Account address (public)") + translationManager.emptyString + placeholderOpacity: 1.0 onTextUpdated: checkNextButton() + borderColor: Qt.rgba(0, 0, 0, 0.15) + backgroundColor: "white" + fontColor: "black" + fontBold: false } LineEdit { Layout.fillWidth: true id: viewKeyLine Layout.maximumWidth: 600 * scaleRatio Layout.minimumWidth: 200 * scaleRatio + placeholderFontBold: true + placeholderFontFamily: "Arial" + placeholderColor: Style.legacy_placeholderFontColor placeholderText: qsTr("View key (private)") + translationManager.emptyString + placeholderOpacity: 1.0 onTextUpdated: checkNextButton() + borderColor: Qt.rgba(0, 0, 0, 0.15) + backgroundColor: "white" + fontColor: "black" + fontBold: false } LineEdit { @@ -259,8 +269,16 @@ ColumnLayout { Layout.maximumWidth: 600 * scaleRatio Layout.minimumWidth: 200 * scaleRatio id: spendKeyLine + placeholderFontBold: true + placeholderFontFamily: "Arial" + placeholderColor: Style.legacy_placeholderFontColor placeholderText: qsTr("Spend key (private)") + translationManager.emptyString + placeholderOpacity: 1.0 onTextUpdated: checkNextButton() + borderColor: Qt.rgba(0, 0, 0, 0.15) + backgroundColor: "white" + fontColor: "black" + fontBold: false } } @@ -271,10 +289,18 @@ ColumnLayout { Layout.fillWidth: true Layout.maximumWidth: 600 * scaleRatio Layout.minimumWidth: 200 * scaleRatio + placeholderFontBold: true + placeholderFontFamily: "Arial" + placeholderColor: Style.legacy_placeholderFontColor placeholderText: qsTr("Restore height (optional)") + translationManager.emptyString + placeholderOpacity: 1.0 validator: IntValidator { bottom:0 } + borderColor: Qt.rgba(0, 0, 0, 0.15) + backgroundColor: "white" + fontColor: "black" + fontBold: false } } @@ -284,6 +310,8 @@ ColumnLayout { Layout.fillWidth: true Layout.topMargin: 20 * scaleRatio fontSize: 14 + fontFamily: "Arial" + fontColor: "#555555" text: qsTr("Your wallet is stored in") + ": " + fileUrlInput.text; } @@ -304,6 +332,10 @@ ColumnLayout { fileUrlInput.focus = true } } + borderColor: Qt.rgba(0, 0, 0, 0.15) + backgroundColor: "white" + fontColor: "black" + fontBold: false } FileDialog { diff --git a/wizard/WizardMemoTextInput.qml b/wizard/WizardMemoTextInput.qml index 9611977d..a796fc3f 100644 --- a/wizard/WizardMemoTextInput.qml +++ b/wizard/WizardMemoTextInput.qml @@ -41,6 +41,7 @@ Column { font.pixelSize: 16 * scaleRatio anchors.margins: 8 * scaleRatio font.bold:true + font.family: "Arial" text: qsTr("Enter your 25 (or 24) word mnemonic seed") + translationManager.emptyString color: "#BABABA" visible: !memoTextInput.text/* && !parent.focus*/ diff --git a/wizard/WizardOptions.qml b/wizard/WizardOptions.qml index 7a9ffa62..ef9a4d1c 100644 --- a/wizard/WizardOptions.qml +++ b/wizard/WizardOptions.qml @@ -248,13 +248,13 @@ ColumnLayout { background: "#FFFFFF" fontColor: "#4A4646" fontSize: 16 * scaleRatio - checkedIcon: "../images/checkedVioletIcon.png" + checkedIcon: "../images/checkedBlackIcon.png" uncheckedIcon: "../images/uncheckedIcon.png" - checked: appWindow.persistentSettings.nettype === NetworkType.TESTNET; + checked: appWindow.persistentSettings.nettype == NetworkType.TESTNET; onClicked: { persistentSettings.nettype = testNet.checked ? NetworkType.TESTNET : NetworkType.MAINNET stageNet.checked = false; - console.log("Network type set to ", persistentSettings.nettype === NetworkType.TESTNET ? "Testnet" : "Mainnet") + console.log("Network type set to ", persistentSettings.nettype == NetworkType.TESTNET ? "Testnet" : "Mainnet") } } } @@ -267,13 +267,13 @@ ColumnLayout { background: "#FFFFFF" fontColor: "#4A4646" fontSize: 16 * scaleRatio - checkedIcon: "../images/checkedVioletIcon.png" + checkedIcon: "../images/checkedBlackIcon.png" uncheckedIcon: "../images/uncheckedIcon.png" - checked: appWindow.persistentSettings.nettype === NetworkType.STAGENET; + checked: appWindow.persistentSettings.nettype == NetworkType.STAGENET; onClicked: { persistentSettings.nettype = stageNet.checked ? NetworkType.STAGENET : NetworkType.MAINNET testNet.checked = false; - console.log("Network type set to ", persistentSettings.nettype === NetworkType.STAGENET ? "Stagenet" : "Mainnet") + console.log("Network type set to ", persistentSettings.nettype == NetworkType.STAGENET ? "Stagenet" : "Mainnet") } } }