1
mirror of https://github.com/monero-project/monero-gui synced 2024-11-19 13:37:13 +01:00

Merge pull request #826

Remote nodes + mobile layout
This commit is contained in:
luigi1111 2017-11-03 15:29:10 -05:00
commit c58dfa913b
No known key found for this signature in database
GPG Key ID: F4ACA0183641E010
60 changed files with 2174 additions and 1383 deletions

8
.gitignore vendored
View File

@ -3,3 +3,11 @@
translations/*.qm
build
version.js
# IOS stuff below
moc_*
*.o
*.mak
*.build
*.xcodeproj
monero-wallet-gui_plugin_import.cpp
monero-wallet-gui_qml_plugin_import.cpp

View File

@ -50,6 +50,7 @@ Rectangle {
signal addressBookClicked()
signal miningClicked()
signal signClicked()
signal keysClicked()
function selectItem(pos) {
menuColumn.previousButton.checked = false
@ -69,6 +70,8 @@ Rectangle {
width: (isMobile)? appWindow.width : 260
color: "#FFFFFF"
anchors.bottom: parent.bottom
anchors.top: parent.top
// Item with monero logo
Item {
@ -138,8 +141,8 @@ Rectangle {
visible: !isMobile
Item {
anchors.verticalCenter: parent.verticalCenter
height: 26
width: 50
height: 26 * scaleRatio
width: 50 * scaleRatio
Image {
anchors.centerIn: parent
@ -228,7 +231,8 @@ Rectangle {
Flickable {
contentHeight: 500
id:flicker
contentHeight: 500 * scaleRatio
anchors.fill: parent
clip: true
@ -239,7 +243,7 @@ Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
clip: true
property var previousButton: transferButton
// ------------- Dashboard tab ---------------
@ -393,6 +397,7 @@ Rectangle {
// ------------- Mining tab ---------------
MenuButton {
id: miningButton
visible: !isAndroid && !isIOS
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Mining") + translationManager.emptyString
@ -483,10 +488,33 @@ Rectangle {
color: "#505050"
height: 1
}
// ------------- Sign/verify tab ---------------
MenuButton {
id: keysButton
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Seed & Keys") + translationManager.emptyString
symbol: qsTr("Y") + translationManager.emptyString
dotColor: "#FFD781"
under: settingsButton
onClicked: {
parent.previousButton.checked = false
parent.previousButton = keysButton
panel.keysClicked()
}
}
Rectangle {
visible: settingsButton.present
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
color: "#505050"
height: 1
}
}
} // Column
}
} // Flickable
NetworkStatusItem {
id: networkStatus
@ -494,6 +522,7 @@ Rectangle {
anchors.right: parent.right
anchors.bottom: (progressBar.visible)? progressBar.top : parent.bottom;
connected: Wallet.ConnectionStatus_Disconnected
height: 58 * scaleRatio
}
ProgressBar {
@ -501,8 +530,9 @@ Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: 35 * scaleRatio
}
}
} // menuRect

View File

@ -29,6 +29,7 @@
import QtQml 2.0
import QtQuick 2.2
// QtQuick.Controls 2.0 isn't stable enough yet. Needs more testing.
//import QtQuick.Controls 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
@ -47,7 +48,7 @@ Rectangle {
property string balanceText
property string unlockedBalanceLabelText: qsTr("Unlocked Balance") + translationManager.emptyString
property string unlockedBalanceText
property int minHeight: (appWindow.height > 800) ? appWindow.height : 800
property int minHeight: (appWindow.height > 800) ? appWindow.height : 800 * scaleRatio
// property int headerHeight: header.height
property Transfer transferView: Transfer { }
@ -58,6 +59,7 @@ Rectangle {
property Settings settingsView: Settings { }
property Mining miningView: Mining { }
property AddressBook addressBookView: AddressBook { }
property Keys keysView: Keys { }
signal paymentClicked(string address, string paymentId, string amount, int mixinCount, int priority, string description)
@ -93,33 +95,6 @@ Rectangle {
transferView.sendTo(address, paymentId, description);
}
// XXX: just for memo, to be removed
// states: [
// State {
// name: "Dashboard"
// PropertyChanges { target: loader; source: "pages/Dashboard.qml" }
// }, State {
// name: "History"
// PropertyChanges { target: loader; source: "pages/History.qml" }
// }, State {
// name: "Transfer"
// PropertyChanges { target: loader; source: "pages/Transfer.qml" }
// }, State {
// name: "Receive"
// PropertyChanges { target: loader; source: "pages/Receive.qml" }
// }, State {
// name: "AddressBook"
// PropertyChanges { target: loader; source: "pages/AddressBook.qml" }
// }, State {
// name: "Settings"
// PropertyChanges { target: loader; source: "pages/Settings.qml" }
// }, State {
// name: "Mining"
// PropertyChanges { target: loader; source: "pages/Mining.qml" }
// }
// ]
states: [
State {
name: "Dashboard"
@ -132,7 +107,7 @@ Rectangle {
}, State {
name: "Transfer"
PropertyChanges { target: root; currentView: transferView }
PropertyChanges { target: mainFlickable; contentHeight: 1000 }
PropertyChanges { target: mainFlickable; contentHeight: 1000 * scaleRatio }
}, State {
name: "Receive"
PropertyChanges { target: root; currentView: receiveView }
@ -152,11 +127,15 @@ Rectangle {
}, State {
name: "Settings"
PropertyChanges { target: root; currentView: settingsView }
PropertyChanges { target: mainFlickable; contentHeight: 1200 }
PropertyChanges { target: mainFlickable; contentHeight: 1200 * scaleRatio }
}, State {
name: "Mining"
PropertyChanges { target: root; currentView: miningView }
PropertyChanges { target: mainFlickable; contentHeight: minHeight }
}, State {
name: "Keys"
PropertyChanges { target: root; currentView: keysView }
PropertyChanges { target: mainFlickable; contentHeight: minHeight + 200 * scaleRatio }
}
]
@ -187,6 +166,11 @@ Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
onFlickingChanged: {
releaseFocus();
}
// Disabled scrollbars, gives crash on startup on windows
// ScrollIndicator.vertical: ScrollIndicator { }
// ScrollBar.vertical: ScrollBar { } // uncomment to test
@ -195,11 +179,7 @@ Rectangle {
StackView {
id: stackView
initialItem: transferView
// anchors.topMargin: 30
// Layout.fillWidth: true
// Layout.fillHeight: true
anchors.fill:parent
// anchors.margins: 4
clip: true // otherwise animation will affect left panel
delegate: StackViewDelegate {

View File

@ -38,121 +38,4 @@ Rectangle {
id: root
width: 330
color: "#FFFFFF"
function updateTweets() {
tabView.twitter.item.updateTweets()
}
TabView {
id: tabView
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: styledRow.top
anchors.leftMargin: 14
anchors.rightMargin: 14
anchors.topMargin: 40
property alias twitter: twitter
Tab { id: twitter; title: qsTr("Twitter"); source: "tabs/Twitter.qml" }
Tab { title: qsTr("News") + translationManager.emptyString }
Tab { title: qsTr("Help") + translationManager.emptyString }
Tab { title: qsTr("About") + translationManager.emptyString }
style: TabViewStyle {
frameOverlap: 0
tabOverlap: 0
tab: Rectangle {
implicitHeight: 31
implicitWidth: styleData.index === tabView.count - 1 ? tabView.width - (tabView.count - 1) * 68 : 68
Text {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 12
anchors.rightMargin: 12
elide: Text.ElideRight
font.family: "Arial"
font.pixelSize: 14
color: styleData.selected ? "#FF4E40" : "#4A4646"
text: styleData.title
}
Rectangle {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
width: 1
color: "#DBDBDB"
visible: styleData.index !== tabView.count - 1
}
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.bottomMargin: -1
height: 1
color: styleData.selected ? "#FFFFFF" : "#DBDBDB"
}
}
frame: Rectangle {
color: "#FFFFFF"
anchors.fill: parent
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
//anchors.topMargin: 1
height: 1
color: "#DBDBDB"
}
}
}
}
Row {
id: styledRow
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
Rectangle { height: 8; width: parent.width / 5; color: "#FFE00A" }
Rectangle { height: 8; width: parent.width / 5; color: "#6B0072" }
Rectangle { height: 8; width: parent.width / 5; color: "#FF6C3C" }
Rectangle { height: 8; width: parent.width / 5; color: "#FFD781" }
Rectangle { height: 8; width: parent.width / 5 - 30; color: "#FF4F41" }
}
Rectangle {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: 1
color: "#DBDBDB"
}
Rectangle {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
width: 1
color: "#DBDBDB"
}
// indicate disabled state
// Desaturate {
// anchors.fill: parent
// source: parent
// desaturation: root.enabled ? 0.0 : 1.0
// }
}

View File

@ -144,8 +144,10 @@ ListView {
onOptionClicked: {
// Ensure tooltip is closed
appWindow.toolTip.visible = false;
if(option === 0)
if(option === 0) {
clipboard.setText(address)
appWindow.showStatusMessage(qsTr("Address copied to clipboard"),3)
}
else if(option === 1){
console.log("Sending to: ", address +" "+ paymentId);
middlePanel.sendTo(address, paymentId, description);

View File

@ -29,61 +29,70 @@
import QtQuick 2.0
import QtQuick.Layouts 1.1
Item {
RowLayout {
id: checkBox
property alias text: label.text
property string checkedIcon
property string uncheckedIcon
property bool checked: false
property alias background: backgroundRect.color
property int fontSize: 14
property int fontSize: 14 * scaleRatio
property alias fontColor: label.color
signal clicked()
height: 25
width: label.x + label.width
Layout.minimumWidth: label.x + label.contentWidth
clip: true
height: 25 * scaleRatio
Rectangle {
anchors.left: parent.left
height: parent.height - 1
width: 25
//radius: 4
y: 0
color: "#DBDBDB"
function toggle(){
checkBox.checked = !checkBox.checked
checkBox.clicked()
}
Rectangle {
id: backgroundRect
anchors.left: parent.left
height: parent.height - 1
width: 25
//radius: 4
y: 1
color: "#FFFFFF"
Image {
anchors.centerIn: parent
source: checkBox.checked ? checkBox.checkedIcon :
checkBox.uncheckedIcon
RowLayout {
Layout.fillWidth: true
Rectangle {
anchors.left: parent.left
width: 25 * scaleRatio
height: checkBox.height - 1
//radius: 4
y: 0
color: "#DBDBDB"
}
}
Text {
id: label
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 25 + 12
font.family: "Arial"
font.pixelSize: checkBox.fontSize
color: "#525252"
}
Rectangle {
id: backgroundRect
anchors.left: parent.left
width: 25 * scaleRatio
height: checkBox.height - 1
//radius: 4
y: 1
color: "#FFFFFF"
MouseArea {
anchors.fill: parent
onClicked: {
checkBox.checked = !checkBox.checked
checkBox.clicked()
Image {
anchors.centerIn: parent
source: checkBox.checked ? checkBox.checkedIcon :
checkBox.uncheckedIcon
}
MouseArea {
anchors.fill: parent
onClicked: {
toggle()
}
}
}
Text {
id: label
font.family: "Arial"
font.pixelSize: checkBox.fontSize
color: "#525252"
wrapMode: Text.Wrap
Layout.fillWidth: true
MouseArea {
anchors.fill: parent
onClicked: {
toggle()
}
}
}
}
}

View File

@ -90,7 +90,7 @@ Window {
}
Text {
text: qsTr("Starting Monero daemon in %1 seconds").arg(countDown);
text: qsTr("Starting local node in %1 seconds").arg(countDown);
font.pixelSize: 18
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true

View File

@ -79,14 +79,6 @@ ListView {
}
}
StandardDialog {
id: detailsPopup
cancelVisible: false
okVisible: true
width:850
}
delegate: Rectangle {
id: delegate
height: 144
@ -111,10 +103,10 @@ ListView {
onClicked: {
var tx_key = currentWallet.getTxKey(hash)
var tx_note = currentWallet.getUserNote(hash)
detailsPopup.title = "Transaction details";
detailsPopup.content = buildTxDetailsString(hash,paymentId,tx_key,tx_note,destinations);
detailsPopup.open();
informationPopup.title = "Transaction details";
informationPopup.content = buildTxDetailsString(hash,paymentId,tx_key,tx_note,destinations);
informationPopup.onCloseCallback = null
informationPopup.open();
}
}
@ -383,7 +375,7 @@ ListView {
Column {
anchors.top: parent.top
width: 148
visible: isOut
visible: isOut && fee != ""
Text {
anchors.left: parent.left
font.family: "Arial"

View File

@ -0,0 +1,191 @@
// Copyright (c) 2014-2017, 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 moneroComponents.Clipboard 1.0
import moneroComponents.AddressBookModel 1.0
ListView {
id: listView
clip: true
boundsBehavior: ListView.StopAtBounds
property var previousItem
property var addressBookModel: null
function buildTxDetailsString(tx_id, paymentId, tx_key,tx_note, destinations) {
var trStart = '<tr><td width="85" style="padding-top:5px"><b>',
trMiddle = '</b></td><td style="padding-left:10px;padding-top:5px;">',
trEnd = "</td></tr>";
return '<table border="0">'
+ (tx_id ? trStart + qsTr("Tx ID:") + trMiddle + tx_id + trEnd : "")
+ (paymentId ? trStart + qsTr("Payment ID:") + trMiddle + paymentId + trEnd : "")
+ (tx_key ? trStart + qsTr("Tx key:") + trMiddle + tx_key + trEnd : "")
+ (tx_note ? trStart + qsTr("Tx note:") + trMiddle + tx_note + trEnd : "")
+ (destinations ? trStart + qsTr("Destinations:") + trMiddle + destinations + trEnd : "")
+ "</table>"
+ translationManager.emptyString;
}
function lookupPaymentID(paymentId) {
if (!addressBookModel)
return ""
var idx = addressBookModel.lookupPaymentID(paymentId)
if (idx < 0)
return ""
idx = addressBookModel.index(idx, 0)
return addressBookModel.data(idx, AddressBookModel.AddressBookDescriptionRole)
}
footer: Rectangle {
height: 127 * scaleRatio
width: listView.width
color: "#FFFFFF"
Text {
anchors.centerIn: parent
font.family: "Arial"
font.pixelSize: 14 * scaleRatio
color: "#545454"
text: qsTr("No more results") + translationManager.emptyString
}
}
delegate: Rectangle {
id: delegate
height: tableContent.height + 20 * scaleRatio
width: listView.width
color: index % 2 ? "#F8F8F8" : "#FFFFFF"
Layout.leftMargin: 10 * scaleRatio
z: listView.count - index
function collapseDropdown() { dropdown.expanded = false }
MouseArea {
anchors.fill: parent
onClicked: {
var tx_key = currentWallet.getTxKey(hash)
var tx_note = currentWallet.getUserNote(hash)
informationPopup.title = "Transaction details";
informationPopup.text = buildTxDetailsString(hash,paymentId,tx_key,tx_note,destinations);
informationPopup.open();
informationPopup.onCloseCallback = null
}
}
Rectangle {
anchors.right: parent.right
anchors.rightMargin: 15 * scaleRatio
anchors.top: parent.top
anchors.topMargin: parent.height/2 - this.height/2
width: 30 * scaleRatio; height: 30 * scaleRatio
radius: 25
color: "#FF4304"
Image {
width: 20 * scaleRatio
height: 20 * scaleRatio
fillMode: Image.PreserveAspectFit
anchors.centerIn: parent
source: "qrc:///images/nextPage.png"
}
}
ColumnLayout {
id: tableContent
// Date
RowLayout {
Layout.topMargin: 20 * scaleRatio
Layout.leftMargin: 10 * scaleRatio
Text {
font.family: "Arial"
font.pixelSize: 14 * scaleRatio
color: "#555555"
text: date
}
Text {
font.family: "Arial"
font.pixelSize: 14 * scaleRatio
color: "#555555"
text: time
}
// Show confirmations
Text {
visible: confirmations < confirmationsRequired || isPending
Layout.leftMargin: 5 * scaleRatio
font.family: "Arial"
font.pixelSize: 14 * scaleRatio
color: (confirmations < confirmationsRequired)? "#FF6C3C" : "#545454"
text: {
if (!isPending)
if(confirmations < confirmationsRequired)
return qsTr("(%1/%2 confirmations)").arg(confirmations).arg(confirmationsRequired)
if (!isOut)
return qsTr("UNCONFIRMED") + translationManager.emptyString
return qsTr("PENDING") + translationManager.emptyString
}
}
}
// Amount & confirmations
RowLayout {
Layout.leftMargin: 10 * scaleRatio
spacing: 2
Text {
font.family: "Arial"
font.pixelSize: 14 * scaleRatio
color: isOut ? "#FF4F41" : "#36B05B"
text: isOut ? "↓" : "↑"
}
Text {
id: amountText
font.family: "Arial"
font.pixelSize: 18 * scaleRatio
color: isOut ? "#FF4F41" : "#36B05B"
text: displayAmount
}
}
}
}
ListModel {
id: dropModel
ListElement { name: "<b>Copy address to clipboard</b>"; icon: "../images/dropdownCopy.png" }
ListElement { name: "<b>Add to address book</b>"; icon: "../images/dropdownAdd.png" }
ListElement { name: "<b>Send to this address</b>"; icon: "../images/dropdownSend.png" }
ListElement { name: "<b>Find similar transactions</b>"; icon: "../images/dropdownSearch.png" }
}
Clipboard { id: clipboard }
}

View File

@ -33,7 +33,7 @@ import QtQuick 2.2
TextField {
font.family: "Arial"
horizontalAlignment: TextInput.AlignLeft
selectByMouse: true
style: TextFieldStyle {
textColor: "#3F3F3F"
placeholderTextColor: "#BABABA"

View File

@ -35,19 +35,21 @@ Item {
property alias color: label.color
property alias textFormat: label.textFormat
property string tipText: ""
property int fontSize: 12
property int fontSize: 16 * scaleRatio
property alias wrapMode: label.wrapMode
property alias horizontalAlignment: label.horizontalAlignment
signal linkActivated()
width: icon.x + icon.width
height: icon.height
width: icon.x + icon.width * scaleRatio
height: icon.height * scaleRatio
Layout.topMargin: 10 * scaleRatio
Text {
id: label
anchors.bottom: parent.bottom
anchors.bottomMargin: 2
anchors.bottomMargin: 2 * scaleRatio
anchors.left: parent.left
font.family: "Arial"
font.pixelSize: parent.fontSize
font.pixelSize: fontSize
color: "#555555"
onLinkActivated: item.linkActivated()
}
@ -56,7 +58,7 @@ Item {
id: icon
anchors.verticalCenter: parent.verticalCenter
anchors.left: label.right
anchors.leftMargin: 5
anchors.leftMargin: 5 * scaleRatio
source: "../images/whatIsIcon.png"
visible: appWindow.whatIsEnable
}

View File

@ -36,13 +36,13 @@ Item {
property alias readOnly : input.readOnly
property alias cursorPosition: input.cursorPosition
property alias echoMode: input.echoMode
property int fontSize: 18
property int fontSize: 18 * scaleRatio
property bool error: false
signal editingFinished()
signal accepted();
signal textUpdated();
height: 37
height: 37 * scaleRatio
function getColor(error) {
if (error)
@ -53,14 +53,14 @@ Item {
Rectangle {
anchors.fill: parent
anchors.bottomMargin: 1
anchors.bottomMargin: 1 * scaleRatio
color: "#DBDBDB"
//radius: 4
}
Rectangle {
anchors.fill: parent
anchors.topMargin: 1
anchors.topMargin: 1 * scaleRatio
color: getColor(error)
//radius: 4
}
@ -68,8 +68,8 @@ Item {
Input {
id: input
anchors.fill: parent
anchors.leftMargin: 4
anchors.rightMargin: 30
anchors.leftMargin: 4 * scaleRatio
anchors.rightMargin: 30 * scaleRatio
font.pixelSize: parent.fontSize
onEditingFinished: item.editingFinished()
onAccepted: item.accepted();

View File

@ -38,11 +38,18 @@ Rectangle {
property var under: null
signal clicked()
function doClick() {
// Android workaround
releaseFocus();
clicked();
}
function getOffset() {
var offset = 0
var item = button
while (item.under) {
offset += 20
offset += 20 * scaleRatio
item = item.under
}
return offset
@ -50,7 +57,7 @@ Rectangle {
color: checked ? "#FFFFFF" : "#1C1C1C"
property bool present: !under || under.checked || checked || under.numSelectedChildren > 0
height: present ? ((appWindow.height >= 800) ? 64 : 52) : 0
height: present ? ((appWindow.height >= 800) ? 64 * scaleRatio : 52 * scaleRatio ) : 0
transform: Scale {
yScale: button.present ? 1 : 0
@ -76,18 +83,18 @@ Rectangle {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.leftMargin: parent.getOffset()
width: 50
width: 50 * scaleRatio
Rectangle {
id: dot
anchors.centerIn: parent
width: 16
width: 16 * scaleRatio
height: width
radius: height / 2
Rectangle {
anchors.centerIn: parent
width: 12
width: 12 * scaleRatio
height: width
radius: height / 2
color: "#1C1C1C"
@ -98,7 +105,7 @@ Rectangle {
Text {
id: symbolText
anchors.centerIn: parent
font.pixelSize: 11
font.pixelSize: 11 * scaleRatio
font.bold: true
color: button.checked || buttonArea.containsMouse ? "#FFFFFF" : dot.color
visible: appWindow.ctrlPressed
@ -117,7 +124,7 @@ Rectangle {
Image {
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 20
anchors.rightMargin: 20 * scaleRatio
anchors.leftMargin: parent.getOffset()
source: "../images/menuIndicator.png"
}
@ -126,9 +133,9 @@ Rectangle {
id: label
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: parent.getOffset() + 50
anchors.leftMargin: parent.getOffset() + 50 * scaleRatio
font.family: "Arial"
font.pixelSize: 18
font.pixelSize: 18 * scaleRatio
color: parent.checked ? "#000000" : "#FFFFFF"
}
@ -139,7 +146,7 @@ Rectangle {
onClicked: {
if(parent.checked)
return
button.clicked()
button.doClick()
parent.checked = true
}
}

View File

@ -10,17 +10,16 @@ Rectangle {
anchors.leftMargin: 1
anchors.rightMargin: 1
Layout.fillWidth: true
Layout.preferredHeight: 64
Layout.preferredHeight: 64 * scaleRatio
color: "#FFFFFF"
// visible: basicMode
Image {
id: logo
visible: appWindow.width > 460
visible: appWindow.width > 460 * scaleRatio
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -5
anchors.left: parent.left
anchors.leftMargin: appWindow.persistentSettings.customDecorations ? 20 : 40
anchors.leftMargin: 50 * scaleRatio
source: "../images/moneroLogo2.png"
}
@ -28,9 +27,8 @@ Rectangle {
id: icon
visible: !logo.visible
anchors.verticalCenter: parent.verticalCenter
// anchors.verticalCenterOffset: -5
anchors.left: parent.left
anchors.leftMargin: appWindow.persistentSettings.customDecorations ? 20 : 40
anchors.leftMargin: 40 * scaleRatio
source: "../images/moneroIcon.png"
}
@ -38,16 +36,16 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
anchors.top: parent.top
anchors.right: parent.right
anchors.topMargin: 10
width: 256
anchors.topMargin: 10 * scaleRatio
width: 256 * scaleRatio
columns: 3
Text {
id: balanceLabel
width: 116
height: 20
width: 116 * scaleRatio
height: 20 * scaleRatio
font.family: "Arial"
font.pixelSize: 12
font.pixelSize: 12 * scaleRatio
font.letterSpacing: -1
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
@ -58,10 +56,10 @@ Rectangle {
Text {
id: balanceText
width: 110
height: 20
width: 110 * scaleRatio
height: 20 * scaleRatio
font.family: "Arial"
font.pixelSize: 18
font.pixelSize: 18 * scaleRatio
font.letterSpacing: -1
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
@ -71,8 +69,8 @@ Rectangle {
}
Item {
height: 20
width: 20
height: 20 * scaleRatio
width: 20 * scaleRatio
Image {
anchors.verticalCenter: parent.verticalCenter
@ -82,10 +80,10 @@ Rectangle {
}
Text {
width: 116
height: 20
width: 116 * scaleRatio
height: 20 * scaleRatio
font.family: "Arial"
font.pixelSize: 12
font.pixelSize: 12 * scaleRatio
font.letterSpacing: -1
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
@ -96,10 +94,10 @@ Rectangle {
Text {
id: availableBalanceText
width: 110
height: 20
width: 110 * scaleRatio
height: 20 * scaleRatio
font.family: "Arial"
font.pixelSize: 14
font.pixelSize: 14 * scaleRatio
font.letterSpacing: -1
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft

View File

@ -29,7 +29,7 @@
import QtQuick 2.0
import moneroComponents.Wallet 1.0
Row {
Rectangle {
id: item
property var connected: Wallet.ConnectionStatus_Disconnected
@ -51,6 +51,8 @@ Row {
if (status == Wallet.ConnectionStatus_Connected) {
if(!appWindow.daemonSynced)
return qsTr("Synchronizing")
if(appWindow.remoteNodeConnected)
return qsTr("Remote node")
return qsTr("Connected")
}
if (status == Wallet.ConnectionStatus_WrongVersion)
@ -60,37 +62,44 @@ Row {
return qsTr("Invalid connection status")
}
Item {
id: iconItem
anchors.bottom: parent.bottom
width: 50
height: 50
Image {
anchors.centerIn: parent
source: getConnectionStatusImage(item.connected)
color: "#1C1C1C"
Row {
height: 60 * scaleRatio
Item {
id: iconItem
anchors.bottom: parent.bottom
width: 50 * scaleRatio
height: 50 * scaleRatio
Image {
anchors.centerIn: parent
source: getConnectionStatusImage(item.connected)
}
}
Column {
anchors.bottom: parent.bottom
height: 53 * scaleRatio
spacing: 3 * scaleRatio
Text {
anchors.left: parent.left
font.family: "Arial"
font.pixelSize: 12 * scaleRatio
color: "#545454"
text: qsTr("Network status") + translationManager.emptyString
}
Text {
anchors.left: parent.left
font.family: "Arial"
font.pixelSize: 18 * scaleRatio
color: getConnectionStatusColor(item.connected)
text: getConnectionStatusString(item.connected) + translationManager.emptyString
}
}
}
Column {
anchors.bottom: parent.bottom
height: 53
spacing: 3
Text {
anchors.left: parent.left
font.family: "Arial"
font.pixelSize: 12
color: "#545454"
text: qsTr("Network status") + translationManager.emptyString
}
Text {
anchors.left: parent.left
font.family: "Arial"
font.pixelSize: 18
color: getConnectionStatusColor(item.connected)
text: getConnectionStatusString(item.connected) + translationManager.emptyString
}
}
}

View File

@ -35,40 +35,48 @@ import QtQuick.Window 2.0
import "../components" as MoneroComponents
Window {
Item {
id: root
modality: Qt.ApplicationModal
flags: Qt.Window | Qt.FramelessWindowHint
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
// same signals as Dialog has
signal accepted()
signal rejected()
signal closeCallback()
function open(walletName) {
root.walletName = walletName ? walletName : ""
leftPanel.enabled = false
middlePanel.enabled = false
titleBar.enabled = false
show()
root.visible = true;
passwordInput.focus = true
}
// TODO: implement without hardcoding sizes
width: 480
height: walletName ? 240 : 200
// Make window draggable
MouseArea {
anchors.fill: parent
property point lastMousePos: Qt.point(0, 0)
onPressed: { lastMousePos = Qt.point(mouseX, mouseY); }
onMouseXChanged: root.x += (mouseX - lastMousePos.x)
onMouseYChanged: root.y += (mouseY - lastMousePos.y)
function close() {
leftPanel.enabled = true
middlePanel.enabled = true
titleBar.enabled = true
root.visible = false;
closeCallback();
}
ColumnLayout {
z: bg.z + 1
id: mainLayout
spacing: 10
anchors { fill: parent; margins: 35 }
anchors { fill: parent; margins: 35 * scaleRatio }
ColumnLayout {
id: column
@ -81,20 +89,20 @@ Window {
Layout.columnSpan: 2
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 24
font.pixelSize: 18 * scaleRatio
font.family: "Arial"
color: "#555555"
}
TextField {
id : passwordInput
focus: true
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
Layout.maximumWidth: 400 * scaleRatio
horizontalAlignment: TextInput.AlignHCenter
verticalAlignment: TextInput.AlignVCenter
font.family: "Arial"
font.pixelSize: 32
font.pixelSize: 32 * scaleRatio
echoMode: TextInput.Password
KeyNavigation.tab: okButton
@ -128,27 +136,18 @@ Window {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
anchors.bottomMargin: 3
Layout.maximumWidth: passwordInput.width
}
// padding
Rectangle {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
height: 10
opacity: 0
color: "black"
}
}
// Ok/Cancel buttons
RowLayout {
id: buttons
spacing: 60
spacing: 60 * scaleRatio
Layout.alignment: Qt.AlignHCenter
MoneroComponents.StandardButton {
id: cancelButton
width: 120
fontSize: 14
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
@ -162,13 +161,11 @@ Window {
}
MoneroComponents.StandardButton {
id: okButton
width: 120
fontSize: 14
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("Ok")
text: qsTr("Continue")
KeyNavigation.tab: cancelButton
onClicked: {
root.close()
@ -178,6 +175,3 @@ Window {
}
}
}

View File

@ -31,17 +31,26 @@ import QtQuick.Window 2.1
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
Window {
Rectangle {
id: root
modality: Qt.ApplicationModal
flags: Qt.Window
color: "white"
visible: false
z:11
property alias messageText: messageTitle.text
property alias heightProgressText : heightProgress.text
width: 200
height: 100
width: 200 * scaleRatio
height: 100 * scaleRatio
opacity: 0.7
function show() {
root.visible = true;
}
function close() {
root.visible = false;
}
ColumnLayout {
id: rootLayout
@ -49,8 +58,8 @@ Window {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 30
anchors.rightMargin: 30
anchors.leftMargin: 30 * scaleRatio
anchors.rightMargin: 30 * scaleRatio
BusyIndicator {
running: parent.visible
@ -61,7 +70,7 @@ Window {
id: messageTitle
text: "Please wait..."
font {
pixelSize: 22
pixelSize: 22 * scaleRatio
}
horizontalAlignment: Text.AlignHCenter
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
@ -72,7 +81,7 @@ Window {
Text {
id: heightProgress
font {
pixelSize: 18
pixelSize: 18 * scaleRatio
}
horizontalAlignment: Text.AlignHCenter
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter

View File

@ -29,15 +29,13 @@
import QtQuick 2.0
import moneroComponents.Wallet 1.0
Item {
Rectangle {
id: item
property int fillLevel: 0
height: 22
anchors.margins:15
visible: false
//clip: true
color: "#1C1C1C"
function updateProgress(currentBlock,targetBlock, blocksToSync){
function updateProgress(currentBlock,targetBlock, blocksToSync, statusTxt){
if(targetBlock == 1) {
fillLevel = 0
progressText.text = qsTr("Establishing connection...");
@ -54,53 +52,68 @@ Item {
else
var progressLevel = (100*(currentBlock/targetBlock)).toFixed(0);
fillLevel = progressLevel
progressText.text = qsTr("Blocks remaining: %1").arg(remaining.toFixed(0));
if(typeof statusTxt != "undefined" && statusTxt != "") {
progressText.text = statusTxt + (" %1").arg(remaining.toFixed(0));
} else {
progressText.text = qsTr("Blocks remaining: %1").arg(remaining.toFixed(0));
}
progressBar.visible = currentBlock < targetBlock
}
}
Rectangle {
id: bar
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
height: 22
radius: 2
color: "#FFFFFF"
Item {
anchors.leftMargin: 15 * scaleRatio
anchors.rightMargin: 15 * scaleRatio
anchors.fill: parent
Rectangle {
id: fillRect
id: bar
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.margins: 2
height: bar.height
property int maxWidth: parent.width - 4
width: (maxWidth * fillLevel) / 100
color: {
if(item.fillLevel < 99 ) return "#FF6C3C"
//if(item.fillLevel < 99) return "#FFE00A"
return "#36B25C"
}
height: 22 * scaleRatio
radius: 2 * scaleRatio
color: "#FFFFFF"
}
Rectangle {
color:"#333"
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.leftMargin: 8
Text {
id:progressText
Rectangle {
id: fillRect
anchors.top: parent.top
anchors.bottom: parent.bottom
font.family: "Arial"
font.pixelSize: 12
color: "#000"
text: qsTr("Synchronizing blocks")
height:18
anchors.left: parent.left
anchors.margins: 2 * scaleRatio
height: bar.height
property int maxWidth: parent.width - 4 * scaleRatio
width: (maxWidth * fillLevel) / 100
color: {
if(item.fillLevel < 99 ) return "#FF6C3C"
//if(item.fillLevel < 99) return "#FFE00A"
return "#36B25C"
}
}
Rectangle {
color:"#333"
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 blocks")
height:18 * scaleRatio
}
}
}
}
}

View File

@ -44,7 +44,7 @@ Rectangle {
color: "black"
state: "Stopped"
signal qrcode_decoded(string address, string payment_id, string amount, string tx_description, string recipient_name)
signal qrcode_decoded(string address, string payment_id, string amount, string tx_description, string recipient_name, var extra_parameters)
states: [
State {
@ -83,7 +83,7 @@ Rectangle {
id : finder
objectName: "QrFinder"
onDecoded : {
root.qrcode_decoded(address, payment_id, amount, tx_description, recipient_name)
root.qrcode_decoded(address, payment_id, amount, tx_description, recipient_name, extra_parameters)
root.state = "Stopped"
}
onNotifyError : {
@ -126,7 +126,7 @@ Rectangle {
MessageDialog {
id: messageDialog
title: "Scanning QrCode"
title: qsTr("QrCode Scanned") + translationManager.emptyString
onAccepted: {
root.state = "Stopped"
}

View File

@ -0,0 +1,60 @@
// Copyright (c) 2014-2017, 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 1.2
import QtQuick.Controls.Styles 1.2
import QtQuick 2.2
import QtQuick.Layouts 1.1
GridLayout {
columns: (isMobile) ? 1 : 2
id: root
property alias daemonAddrText: daemonAddr.text
property alias daemonPortText: daemonPort.text
signal editingFinished()
function getAddress() {
return daemonAddr.text.trim() + ":" + daemonPort.text.trim()
}
LineEdit {
id: daemonAddr
Layout.fillWidth: true
placeholderText: qsTr("Remote Node Hostname / IP") + translationManager.emptyString
onEditingFinished: root.editingFinished()
}
LineEdit {
id: daemonPort
Layout.fillWidth: true
placeholderText: qsTr("Port") + translationManager.emptyString
onEditingFinished: root.editingFinished()
}
}

View File

@ -31,19 +31,25 @@ import QtQuick.Layouts 1.1
Item {
id: button
height: 37
property string shadowPressedColor
property string shadowReleasedColor
property string pressedColor
property string releasedColor
height: 37 * 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
property int fontSize: 12 * scaleRatio
property alias text: label.text
signal clicked()
// Dynamic label width
Layout.minimumWidth: (label.contentWidth > 80)? label.contentWidth + 20 : 100
Layout.minimumWidth: (label.contentWidth > 50)? label.contentWidth + 10 : 60
function doClick() {
// Android workaround
releaseFocus();
clicked();
}
Rectangle {
anchors.left: parent.left
@ -98,9 +104,9 @@ Item {
MouseArea {
id: buttonArea
anchors.fill: parent
onClicked: parent.clicked()
onClicked: doClick()
}
Keys.onSpacePressed: clicked()
Keys.onReturnPressed: clicked()
Keys.onSpacePressed: doClick()
Keys.onReturnPressed: doClick()
}

View File

@ -35,10 +35,10 @@ import QtQuick.Window 2.0
import "../components" as MoneroComponents
Window {
Rectangle {
id: root
modality: Qt.ApplicationModal
flags: Qt.Window | Qt.FramelessWindowHint
color: "white"
visible: false
property alias title: dialogTitle.text
property alias text: dialogContent.text
property alias content: root.text
@ -53,6 +53,7 @@ Window {
// same signals as Dialog has
signal accepted()
signal rejected()
signal closeCallback();
// Make window draggable
MouseArea {
@ -64,12 +65,24 @@ Window {
}
function open() {
// Center
if(!isMobile) {
root.x = parent.width/2 - root.width/2
root.y = screenHeight/2 - root.height/2
}
show()
root.z = 11
root.visible = true;
}
function close() {
root.visible = false;
closeCallback();
}
// TODO: implement without hardcoding sizes
width: 480
height: 280
width: isMobile ? screenWidth : 480
height: isMobile ? screenHeight : 280
ColumnLayout {
id: mainLayout
@ -84,7 +97,7 @@ Window {
Label {
id: dialogTitle
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 32
font.pixelSize: 18 * scaleRatio
font.family: "Arial"
color: "#555555"
}
@ -99,7 +112,23 @@ Window {
font.family: "Arial"
textFormat: TextEdit.AutoText
readOnly: true
font.pixelSize: 12
font.pixelSize: 12 * scaleRatio
selectByMouse: false
wrapMode: TextEdit.Wrap
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("Content copied to clipboard"),3)
}
}
}
}
@ -111,8 +140,6 @@ Window {
MoneroComponents.StandardButton {
id: cancelButton
width: 120
fontSize: 14
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
@ -126,13 +153,11 @@ Window {
MoneroComponents.StandardButton {
id: okButton
width: 120
fontSize: 14
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("Ok")
text: qsTr("OK")
KeyNavigation.tab: cancelButton
onClicked: {
root.close()

View File

@ -38,7 +38,10 @@ Item {
property string textColor: "#FFFFFF"
property alias currentIndex: column.currentIndex
property bool expanded: false
height: 37
signal changed();
height: 37 * scaleRatio
onExpandedChanged: if(expanded) appWindow.currentItem = dropdown
function hide() { dropdown.expanded = false }
@ -54,12 +57,18 @@ Item {
return true
}
// 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 {
id: head
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
height: 37
height: 37 * scaleRatio
Rectangle {
anchors.left: parent.left
@ -82,8 +91,8 @@ Item {
Rectangle {
anchors.left: parent.left
anchors.bottom: parent.bottom
height: 3
width: 3
height: 3 * scaleRatio
width: 3 * scaleRatio
color: dropdown.pressedColor
visible: dropdown.expanded || droplist.height > 0
}
@ -91,8 +100,8 @@ Item {
Rectangle {
anchors.right: parent.right
anchors.bottom: parent.bottom
height: 3
width: 3
height: 3 * scaleRatio
width: 3 * scaleRatio
color: dropdown.pressedColor
visible: dropdown.expanded || droplist.height > 0
}
@ -101,26 +110,23 @@ Item {
id: firstColText
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 12
anchors.leftMargin: 12 * scaleRatio
elide: Text.ElideRight
font.family: "Arial"
font.bold: true
font.pixelSize: 12
font.pixelSize: 12 * scaleRatio
color: "#FFFFFF"
text: column.currentIndex < repeater.model.rowCount() ? qsTr(repeater.model.get(column.currentIndex).column1) + translationManager.emptyString : ""
}
Text {
id: secondColText
anchors.verticalCenter: parent.verticalCenter
anchors.right: separator.left
anchors.rightMargin: 12
anchors.rightMargin: 12 * scaleRatio
width: dropdown.expanded ? w : (separator.x - 12) - (firstColText.x + firstColText.width + 5)
font.family: "Arial"
font.pixelSize: 12
font.pixelSize: 12 * scaleRatio
color: "#FFFFFF"
text: column.currentIndex < repeater.model.rowCount() ? qsTr(repeater.model.get(column.currentIndex).column2) + translationManager.emptyString : ""
property int w: 0
Component.onCompleted: w = implicitWidth
}
@ -129,7 +135,7 @@ Item {
id: separator
anchors.right: dropIndicator.left
anchors.verticalCenter: parent.verticalCenter
height: 18
height: 18 * scaleRatio
width: 1
color: "#FFFFFF"
}
@ -139,12 +145,12 @@ Item {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
width: 32
width: 32 * scaleRatio
Image {
anchors.centerIn: parent
source: "../images/whiteDropIndicator.png"
rotation: dropdown.expanded ? 180 : 0
rotation: dropdown.expanded ? 180 * scaleRatio : 0
}
}
@ -168,14 +174,14 @@ Item {
Rectangle {
anchors.left: parent.left
anchors.top: parent.top
width: 3; height: 3
width: 3 * scaleRatio; height: 3 * scaleRatio
color: dropdown.pressedColor
}
Rectangle {
anchors.right: parent.right
anchors.top: parent.top
width: 3; height: 3
width: 3 * scaleRatio; height: 3 * scaleRatio
color: dropdown.pressedColor
}
@ -209,7 +215,7 @@ Item {
delegate: Rectangle {
anchors.left: parent.left
anchors.right: parent.right
height: 30
height: 30 * scaleRatio
//radius: index === repeater.count - 1 ? 4 : 0
color: itemArea.containsMouse || index === column.currentIndex || itemArea.containsMouse ? dropdown.releasedColor : dropdown.pressedColor
@ -217,11 +223,11 @@ Item {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.right: col2Text.left
anchors.leftMargin: 12
anchors.rightMargin: column2.length > 0 ? 12 : 0
anchors.leftMargin: 12 * scaleRatio
anchors.rightMargin: column2.length > 0 ? 12 * scaleRatio: 0
font.family: "Arial"
font.bold: true
font.pixelSize: 12
font.pixelSize: 12 * scaleRatio
color: "#FFFFFF"
text: qsTr(column1) + translationManager.emptyString
}
@ -230,9 +236,9 @@ Item {
id: col2Text
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 45
anchors.rightMargin: 45 * scaleRatio
font.family: "Arial"
font.pixelSize: 12
font.pixelSize: 12 * scaleRatio
color: "#FFFFFF"
text: column2
}
@ -240,14 +246,14 @@ Item {
Rectangle {
anchors.left: parent.left
anchors.top: parent.top
width: 3; height: 3
width: 3 * scaleRatio; height: 3 * scaleRatio
color: parent.color
}
Rectangle {
anchors.right: parent.right
anchors.top: parent.top
width: 3; height: 3
width: 3 * scaleRatio; height: 3 * scaleRatio
color: parent.color
}
@ -258,6 +264,8 @@ Item {
onClicked: {
dropdown.expanded = false
column.currentIndex = index
changed();
dropdown.update()
}
}
}

View File

@ -49,7 +49,7 @@ Item {
anchors.bottomMargin: 2
font.family: "Arial"
font.bold: true
font.pixelSize: 12
font.pixelSize: 12 * scaleRatio
color: "#4A4949"
text: {
if(currentIndex === 0) return qsTr("Normal") + translationManager.emptyString

View File

@ -28,6 +28,7 @@
import QtQuick 2.2
import QtQuick.Window 2.0
import QtQuick.Layouts 1.1
Rectangle {
id: titleBar
@ -37,7 +38,7 @@ Rectangle {
property alias basicButtonVisible: goToBasicVersionButton.visible
property bool customDecorations: true
signal goToBasicVersion(bool yes)
height: customDecorations ? 30 : 0
height: customDecorations && !isMobile ? 30 : 0
y: -height
property string title
property alias maximizeButtonVisible: maximizeButton.visible
@ -53,21 +54,22 @@ Rectangle {
}
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: basicMouseArea.containsMouse || !leftPanel.visible ? "#FFE00A" : "#000000"
height: 30
color: "#FFE00A"
height: 30 * scaleRatio
width: height
visible: isMobile
Image {
width: parent.width * 2/3;
height: width;
anchors.centerIn: parent
rotation: !leftPanel.visible ? 180 : 0
source: parent.customDecorations || !leftPanel.visible ? "../images/goToBasicVersionHovered.png" :
"../images/gotoBasicVersion.png"
source: "../images/menu.png"
}
MouseArea {
@ -75,6 +77,7 @@ Rectangle {
hoverEnabled: true
anchors.fill: parent
onClicked: {
releaseFocus()
parent.checked = !parent.checked
titleBar.goToBasicVersion(leftPanel.visible)
}

View File

@ -71,6 +71,12 @@ bool filter::eventFilter(QObject *obj, QEvent *ev) {
m_tabPressed = false;
QString sks;
#ifdef Q_OS_ANDROID
if(ke->key() == Qt::Key_Back) {
qDebug() << "Android back hit";
sks = "android_back";
}
#endif
if(ke->key() == Qt::Key_Control) {
sks = "Ctrl";
#ifdef Q_OS_MAC

BIN
images/menu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1,4 +1,12 @@
#!/bin/bash -e
# 3 header files required by monero are missing from the IOS SDK. I copied them from iphoneSimulator SDK
# cd /Applications/XCode.app
# sudo cp ./Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/sys/vmmeter.h ./Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/sys/
# sudo cp ./Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/netinet/udp_var.h ./Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/netinet/
# sudo cp ./Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/netinet/ip_var.h ./Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/netinet/
if [ -z $BUILD_TYPE ]; then
BUILD_TYPE=release
fi
@ -18,17 +26,17 @@ if [ -z $OPENSSL_ROOT_DIR ]; then
fi
echo "Building IOS armv7"
rm -r monero/build
rm -r monero/build > /dev/null
mkdir -p monero/build/release
pushd monero/build/release
cmake -D IOS=ON -D ARCH=armv7 -D BOOST_LIBRARYDIR=${BOOST_INCLUDEDIR} -D BOOST_INCLUDEDIR=${BOOST_INCLUDEDIR} -D OPENSSL_INCLUDE_DIR=${OPENSSL_INCLUDE_DIR} -D OPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR} -D CMAKE_BUILD_TYPE=debug -D STATIC=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="/Users/jacob/crypto/monero-core/monero" ../..
make -j4 && make install
popd
echo "Building IOS arm64"
rm -r monero/build
rm -r monero/build > /dev/null
mkdir -p monero/build/release
pushd monero/build/release
cmake -D IOS=ON -D ARCH=arm64 -D BOOST_LIBRARYDIR=${BOOST_INCLUDEDIR} -D BOOST_INCLUDEDIR=${BOOST_INCLUDEDIR} -D OPENSSL_INCLUDE_DIR=${OPENSSL_INCLUDE_DIR} -D OPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR} -D CMAKE_BUILD_TYPE=debug -D STATIC=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="/Users/jacob/crypto/monero-core/monero" ../..
cmake -D IOS=ON -D ARCH=armv8-a -D BOOST_LIBRARYDIR=${BOOST_INCLUDEDIR} -D BOOST_INCLUDEDIR=${BOOST_INCLUDEDIR} -D OPENSSL_INCLUDE_DIR=${OPENSSL_INCLUDE_DIR} -D OPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR} -D CMAKE_BUILD_TYPE=debug -D STATIC=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="/Users/jacob/crypto/monero-core/monero" ../..
make -j4 && make install
popd

View File

@ -32,6 +32,8 @@
#include <QStandardPaths>
#include <QDebug>
#include <QObject>
#include <QDesktopWidget>
#include <QScreen>
#include "clipboardAdapter.h"
#include "filter.h"
#include "oscursor.h"
@ -168,6 +170,7 @@ int main(int argc, char *argv[])
bool isWindows = false;
bool isIOS = false;
bool isMac = false;
bool isAndroid = false;
#ifdef Q_OS_WIN
isWindows = true;
QStringList moneroAccountsRootDir = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
@ -180,9 +183,42 @@ int main(int argc, char *argv[])
#ifdef Q_OS_MAC
isMac = true;
#endif
#ifdef Q_OS_ANDROID
isAndroid = true;
#endif
engine.rootContext()->setContextProperty("isWindows", isWindows);
engine.rootContext()->setContextProperty("isIOS", isIOS);
engine.rootContext()->setContextProperty("isAndroid", isAndroid);
// screen settings
// Mobile is designed on 128dpi
qreal ref_dpi = 128;
QRect geo = QApplication::desktop()->availableGeometry();
QRect rect = QGuiApplication::primaryScreen()->geometry();
qreal height = qMax(rect.width(), rect.height());
qreal width = qMin(rect.width(), rect.height());
qreal dpi = QGuiApplication::primaryScreen()->logicalDotsPerInch();
qreal physicalDpi = QGuiApplication::primaryScreen()->physicalDotsPerInch();
qreal calculated_ratio = physicalDpi/ref_dpi;
engine.rootContext()->setContextProperty("screenWidth", geo.width());
engine.rootContext()->setContextProperty("screenHeight", geo.height());
#ifdef Q_OS_ANDROID
engine.rootContext()->setContextProperty("scaleRatio", calculated_ratio);
#else
engine.rootContext()->setContextProperty("scaleRatio", 1);
#endif
qDebug() << "available width: " << geo.width();
qDebug() << "available height: " << geo.height();
qDebug() << "devicePixelRatio: " << app.devicePixelRatio();
qDebug() << "screen height: " << height;
qDebug() << "screen width: " << width;
qDebug() << "screen logical dpi: " << dpi;
qDebug() << "screen Physical dpi: " << physicalDpi;
qDebug() << "screen calculated ratio: " << calculated_ratio;
if (!moneroAccountsRootDir.empty()) {
QString moneroAccountsDir = moneroAccountsRootDir.at(0) + "/Monero/wallets";

313
main.qml
View File

@ -57,7 +57,7 @@ ApplicationWindow {
property bool isNewWallet: false
property int restoreHeight:0
property bool daemonSynced: false
property int maxWindowHeight: (Screen.height < 900)? 720 : 800;
property int maxWindowHeight: (isAndroid || isIOS)? screenHeight : (screenHeight < 900)? 720 : 800;
property bool daemonRunning: false
property alias toolTip: toolTip
property string walletName
@ -66,8 +66,14 @@ ApplicationWindow {
property int timeToUnlock: 0
property bool qrScannerEnabled: (typeof builtWithScanner != "undefined") && builtWithScanner
property int blocksToSync: 1
property var isMobile: (appWindow.width > 700) ? false : true
property var isMobile: (appWindow.width > 700 && !isAndroid) ? false : true
property var cameraUi
property bool remoteNodeConnected: false
property bool androidCloseTapped: false;
// Default daemon addresses
readonly property string localDaemonAddress : !persistentSettings.testnet ? "localhost:18081" : "localhost:28081"
property string currentDaemonAddress;
property bool startLocalNodeCancelled: false
// true if wallet ever synchronized
property bool walletInitialized : false
@ -164,7 +170,6 @@ ApplicationWindow {
function initialize() {
console.log("initializing..")
walletInitialized = false;
// Use stored log level
if (persistentSettings.logLevel == 5)
@ -186,7 +191,7 @@ ApplicationWindow {
console.log("Daemon change - closing " + currentWallet)
closeWallet();
currentWallet = undefined
} else {
} else if (!walletInitialized) {
// set page to transfer if not changing daemon
middlePanel.state = "Transfer";
@ -194,9 +199,13 @@ ApplicationWindow {
}
walletManager.setDaemonAddress(persistentSettings.daemon_address)
// Local daemon settings
walletManager.setDaemonAddress(localDaemonAddress)
// wallet already opened with wizard, we just need to initialize it
if (typeof wizard.settings['wallet'] !== 'undefined') {
if (typeof wizard.m_wallet !== 'undefined') {
console.log("using wizard wallet")
//Set restoreHeight
if(persistentSettings.restore_height > 0){
@ -204,11 +213,11 @@ ApplicationWindow {
restoreHeight = persistentSettings.restore_height
}
connectWallet(wizard.settings['wallet'])
connectWallet(wizard.m_wallet)
isNewWallet = true
// We don't need the wizard wallet any more - delete to avoid conflict with daemon adress change
delete wizard.settings['wallet']
delete wizard.m_wallet
} else {
var wallet_path = walletPath();
if(isIOS)
@ -236,12 +245,10 @@ ApplicationWindow {
middlePanel.sweepUnmixableClicked.disconnect(handleSweepUnmixable);
middlePanel.checkPaymentClicked.disconnect(handleCheckPayment);
}
currentWallet = undefined;
if (isIOS) {
console.log("closing sync - ios")
walletManager.closeWallet();
} else
walletManager.closeWalletAsync();
walletManager.closeWallet();
}
function connectWallet(wallet) {
@ -270,14 +277,20 @@ ApplicationWindow {
middlePanel.sweepUnmixableClicked.connect(handleSweepUnmixable);
middlePanel.checkPaymentClicked.connect(handleCheckPayment);
console.log("initializing with daemon address: ", persistentSettings.daemon_address)
console.log("Recovering from seed: ", persistentSettings.is_recovering)
console.log("restore Height", persistentSettings.restore_height)
// Use saved daemon rpc login settings
currentWallet.setDaemonLogin(persistentSettings.daemonUsername, persistentSettings.daemonPassword);
currentWallet.setDaemonLogin(persistentSettings.daemonUsername, persistentSettings.daemonPassword)
currentWallet.initAsync(persistentSettings.daemon_address, 0, persistentSettings.is_recovering, persistentSettings.restore_height);
if(persistentSettings.useRemoteNode)
currentDaemonAddress = persistentSettings.remoteNodeAddress
else
currentDaemonAddress = localDaemonAddress
console.log("initializing with daemon address: ", currentDaemonAddress)
currentWallet.initAsync(currentDaemonAddress, 0, persistentSettings.is_recovering, persistentSettings.restore_height);
}
function walletPath() {
@ -302,7 +315,7 @@ ApplicationWindow {
middlePanel.transferView.updatePriorityDropdown();
// If wallet isnt connected and no daemon is running - Ask
if(isDaemonLocal() && !walletInitialized && status === Wallet.ConnectionStatus_Disconnected && !daemonManager.running(persistentSettings.testnet)){
if(!isMobile && isDaemonLocal() && !walletInitialized && status === Wallet.ConnectionStatus_Disconnected && !daemonManager.running(persistentSettings.testnet)){
daemonManagerDialog.open();
}
// initialize transaction history once wallet is initialized first time;
@ -358,10 +371,25 @@ ApplicationWindow {
console.log("New block found - updating history")
currentWallet.history.refresh()
timeToUnlock = currentWallet.history.minutesToUnlock
leftPanel.minutesToUnlockTxt = (timeToUnlock > 0)? (timeToUnlock == 20)? qsTr("Unlocked balance (waiting for block)").arg(timeToUnlock) : qsTr("Unlocked balance (~%1 min)").arg(timeToUnlock) : qsTr("Unlocked balance");
leftPanel.minutesToUnlockTxt = (timeToUnlock > 0)? (timeToUnlock == 20)? qsTr("Unlocked balance (waiting for block)") : qsTr("Unlocked balance (~%1 min)").arg(timeToUnlock) : qsTr("Unlocked balance");
}
}
function connectRemoteNode() {
console.log("connecting remote node");
persistentSettings.useRemoteNode = true;
currentWallet.initAsync(persistentSettings.remoteNodeAddress);
remoteNodeConnected = true;
}
function disconnectRemoteNode() {
console.log("disconnecting remote node");
persistentSettings.useRemoteNode = false;
currentDaemonAddress = localDaemonAddress
currentWallet.initAsync(currentDaemonAddress);
remoteNodeConnected = false;
}
function onWalletRefresh() {
console.log(">>> wallet refreshed")
@ -383,6 +411,31 @@ ApplicationWindow {
// Update transfer page status
middlePanel.updateStatus();
// Use remote node while local daemon is syncing
if (persistentSettings.useRemoteNode) {
var localNodeConnected = walletManager.connected;
var localNodeSynced = localNodeConnected && walletManager.localDaemonSynced()
if (!currentWallet.connected() || !localNodeSynced) {
console.log("Using remote node while local node is syncing")
// Connect to remote node if not already connected
if(!remoteNodeConnected) {
connectRemoteNode();
}
//update local daemon sync progress bar
if(localNodeConnected) {
leftPanel.progressBar.updateProgress(walletManager.blockchainHeight(),walletManager.blockchainTargetHeight(), 0, qsTr("Remaining blocks (local node):"));
leftPanel.progressBar.visible = true
} else if (persistentSettings.startLocalNode && !startLocalNodeCancelled) {
daemonManagerDialog.open()
}
// local daemon is synced - use it!
} else if (localNodeSynced && remoteNodeConnected) {
disconnectRemoteNode();
}
}
// Refresh is succesfull if blockchain height > 1
if (currentWallet.blockChainHeight() > 1){
@ -392,9 +445,6 @@ ApplicationWindow {
console.log("Saving wallet after first refresh");
currentWallet.store()
isNewWallet = false
// Update History
currentWallet.history.refresh();
}
// recovering from seed is finished after first refresh
@ -403,6 +453,10 @@ ApplicationWindow {
}
}
// Update history on every refresh if it's empty
if(currentWallet.history.count == 0)
currentWallet.history.refresh()
onWalletUpdate();
}
@ -462,7 +516,8 @@ ApplicationWindow {
function onWalletMoneyReceived(txId, amount) {
// refresh transaction history here
currentWallet.refresh()
currentWallet.history.refresh() // this will refresh model
console.log("Confirmed money found")
// history refresh is handled by walletUpdated
}
function onWalletUnconfirmedMoneyReceived(txId, amount) {
@ -473,6 +528,7 @@ ApplicationWindow {
function onWalletMoneySent(txId, amount) {
// refresh transaction history here
console.log("money sent found")
currentWallet.refresh()
currentWallet.history.refresh() // this will refresh model
}
@ -706,7 +762,7 @@ ApplicationWindow {
", txid: ", txid,
", txkey: ", txkey);
var result = walletManager.checkPayment(address, txid, txkey, persistentSettings.daemon_address);
var result = walletManager.checkPayment(address, txid, txkey, currentDaemonAddress);
var results = result.split("|");
if (results.length < 4) {
informationPopup.title = qsTr("Error") + translationManager.emptyString;
@ -797,7 +853,7 @@ ApplicationWindow {
objectName: "appWindow"
visible: true
// width: Screen.width //rightPanelExpanded ? 1269 : 1269 - 300
// width: screenWidth //rightPanelExpanded ? 1269 : 1269 - 300
// height: 900 //300//maxWindowHeight;
color: "#FFFFFF"
flags: persistentSettings.customDecorations ? (Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint) : (Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint | Qt.WindowTitleHint | Qt.WindowMaximizeButtonHint)
@ -892,6 +948,9 @@ ApplicationWindow {
property string daemonPassword: ""
property bool transferShowAdvanced: false
property string blockchainDataDir: ""
property bool startLocalNode: true
property bool useRemoteNode: false
property string remoteNodeAddress: ""
}
// Information dialog
@ -899,6 +958,8 @@ ApplicationWindow {
// dynamically change onclose handler
property var onCloseCallback
id: informationPopup
anchors.fill: parent
z: parent.z + 1
cancelVisible: false
onAccepted: {
if (onCloseCallback) {
@ -909,6 +970,7 @@ ApplicationWindow {
// Confrirmation aka question dialog
StandardDialog {
z: parent.z + 1
id: transactionConfirmationPopup
onAccepted: {
close();
@ -935,7 +997,9 @@ ApplicationWindow {
}
StandardDialog {
z: parent.z + 1
id: confirmationDialog
anchors.fill: parent
property var onAcceptedCallback
property var onRejectedCallback
onAccepted: {
@ -955,9 +1019,17 @@ ApplicationWindow {
title: "Please choose a file"
folder: "file://" +moneroAccountsDir
nameFilters: [ "Wallet files (*.keys)"]
sidebarVisible: false
onAccepted: {
persistentSettings.wallet_path = walletManager.urlToLocalPath(fileDialog.fileUrl)
if(isIOS)
persistentSettings.wallet_path = persistentSettings.wallet_path.replace(moneroAccountsDir,"")
console.log("ÖPPPPNA")
console.log(moneroAccountsDir)
console.log(fileDialog.fileUrl)
console.log(persistentSettings.wallet_path)
initialize();
}
onRejected: {
@ -967,9 +1039,63 @@ ApplicationWindow {
}
// Choose blockchain folder
FileDialog {
id: blockchainFileDialog
title: "Please choose a folder"
selectFolder: true
folder: "file://" + persistentSettings.blockchainDataDir
onAccepted: {
var dataDir = walletManager.urlToLocalPath(blockchainFileDialog.fileUrl)
var validator = daemonManager.validateDataDir(dataDir);
if(!validator.valid) {
confirmationDialog.title = qsTr("Warning") + translationManager.emptyString;
confirmationDialog.text = "";
if(validator.readOnly)
confirmationDialog.text += qsTr("Error: Filesystem is read only") + "\n\n"
if(validator.storageAvailable < 20)
confirmationDialog.text += qsTr("Warning: There's only %1 GB available on the device. Blockchain requires ~%30 GB of data.").arg(validator.storageAvailable).arg(15) + "\n\n"
else
confirmationDialog.text += qsTr("Note: There's %1 GB available on the device. Blockchain requires ~%30 GB of data.").arg(validator.storageAvailable).arg(15) + "\n\n"
if(!validator.lmdbExists)
confirmationDialog.text += qsTr("Note: lmdb folder not found. A new folder will be created.") + "\n\n"
confirmationDialog.icon = StandardIcon.Question
confirmationDialog.cancelText = qsTr("Cancel")
// Continue
confirmationDialog.onAcceptedCallback = function() {
persistentSettings.blockchainDataDir = dataDir
}
// Cancel
confirmationDialog.onRejectedCallback = function() {
};
confirmationDialog.open()
} else {
persistentSettings.blockchainDataDir = dataDir
}
delete validator;
}
onRejected: {
console.log("data dir selection canceled")
}
}
PasswordDialog {
id: passwordDialog
visible: false
z: parent.z + 1
anchors.fill: parent
onAccepted: {
appWindow.initialize();
}
@ -988,11 +1114,43 @@ ApplicationWindow {
onAcceptedCallback();
}
}
PasswordDialog {
id: settingsPasswordDialog
z: parent.z + 1
visible:false
anchors.fill: parent
onAccepted: {
if(appWindow.password === settingsPasswordDialog.password){
if(currentWallet.seedLanguage == "") {
console.log("No seed language set. Using English as default");
currentWallet.setSeedLanguage("English");
}
// Load keys page
middlePanel.state = "Keys"
} else {
informationPopup.title = qsTr("Error") + translationManager.emptyString;
informationPopup.text = qsTr("Wrong password");
informationPopup.open()
informationPopup.onCloseCallback = function() {
settingsPasswordDialog.open()
}
}
settingsPasswordDialog.password = ""
}
onRejected: {
appWindow.showPageRequest("Settings");
}
}
DaemonManagerDialog {
id: daemonManagerDialog
onRejected: {
loadPage("Settings");
startLocalNodeCancelled = true
}
}
@ -1001,8 +1159,8 @@ ApplicationWindow {
id: splash
width: appWindow.width / 1.5
height: appWindow.height / 2
x: (appWindow.width - width) / 2 + appWindow.x
y: (appWindow.height - height) / 2 + appWindow.y
x: (appWindow.width - width) / 2
y: (appWindow.height - height) / 2
messageText: qsTr("Please wait...")
}
@ -1020,14 +1178,15 @@ ApplicationWindow {
PropertyChanges { target: middlePanel; visible: false }
PropertyChanges { target: titleBar; basicButtonVisible: false }
PropertyChanges { target: wizard; visible: true }
PropertyChanges { target: appWindow; width: (Screen.width < 930)? Screen.width : 930; }
PropertyChanges { target: appWindow; width: (screenWidth < 930 || isAndroid || isIOS)? screenWidth : 930; }
PropertyChanges { target: appWindow; height: maxWindowHeight; }
PropertyChanges { target: resizeArea; visible: false }
PropertyChanges { target: resizeArea; visible: true }
PropertyChanges { target: titleBar; maximizeButtonVisible: false }
// PropertyChanges { target: frameArea; blocked: true }
PropertyChanges { target: titleBar; visible: false }
PropertyChanges { target: titleBar; y: 0 }
PropertyChanges { target: titleBar; title: qsTr("Program setup wizard") + translationManager.emptyString }
PropertyChanges { target: mobileHeader; visible: false }
}, State {
name: "normal"
PropertyChanges { target: leftPanel; visible: (isMobile)? false : true }
@ -1035,7 +1194,7 @@ ApplicationWindow {
PropertyChanges { target: middlePanel; visible: true }
PropertyChanges { target: titleBar; basicButtonVisible: true }
PropertyChanges { target: wizard; visible: false }
PropertyChanges { target: appWindow; width: (Screen.width < 969)? Screen.width : 969 } //rightPanelExpanded ? 1269 : 1269 - 300;
PropertyChanges { target: appWindow; width: (screenWidth < 969 || isAndroid || isIOS)? screenWidth : 969 } //rightPanelExpanded ? 1269 : 1269 - 300;
PropertyChanges { target: appWindow; height: maxWindowHeight; }
PropertyChanges { target: resizeArea; visible: true }
PropertyChanges { target: titleBar; maximizeButtonVisible: true }
@ -1043,6 +1202,7 @@ ApplicationWindow {
PropertyChanges { target: titleBar; visible: true }
// PropertyChanges { target: titleBar; y: 0 }
PropertyChanges { target: titleBar; title: qsTr("Monero") + translationManager.emptyString }
PropertyChanges { target: mobileHeader; visible: isMobile ? true : false }
}
]
@ -1051,7 +1211,7 @@ ApplicationWindow {
visible: isMobile
anchors.left: parent.left
anchors.right: parent.right
height: visible? 65 : 0
height: visible? 65 * scaleRatio : 0
}
LeftPanel {
@ -1068,6 +1228,7 @@ ApplicationWindow {
onMiningClicked: {middlePanel.state = "Mining"; if(isMobile) hideMenu()}
onSignClicked: {middlePanel.state = "Sign"; if(isMobile) hideMenu()}
onSettingsClicked: {middlePanel.state = "Settings"; if(isMobile) hideMenu()}
onKeysClicked: {settingsPasswordDialog.open(); if(isMobile) hideMenu()}
}
RightPanel {
@ -1094,22 +1255,6 @@ ApplicationWindow {
visible: false
}
// MouseArea {
// id: frameArea
// property bool blocked: false
// anchors.top: parent.top
// anchors.left: parent.left
// anchors.right: parent.right
// height: 30
// z: 1
// hoverEnabled: true
// propagateComposedEvents: true
// onPressed: mouse.accepted = false
// onReleased: mouse.accepted = false
// onMouseXChanged: titleBar.mouseX = mouseX
// onContainsMouseChanged: titleBar.containsMouse = containsMouse
// }
SequentialAnimation {
id: goToBasicAnimation
// PropertyAction {
@ -1324,7 +1469,7 @@ ApplicationWindow {
y: 6
lineHeight: 0.7
font.family: "Arial"
font.pixelSize: 12
font.pixelSize: 12 * scaleRatio
color: "#FFFFFF"
}
}
@ -1335,11 +1480,70 @@ ApplicationWindow {
}
}
// TODO: Make the callback dynamic
Timer {
id: statusMessageTimer
interval: 5;
running: false;
repeat: false
onTriggered: resetAndroidClose()
triggeredOnStart: false
}
Rectangle {
id: statusMessage
z: 99
visible: false
property alias text: statusMessageText.text
anchors.bottom: parent.bottom
width: statusMessageText.contentWidth + 20 * scaleRatio
anchors.horizontalCenter: parent.horizontalCenter
color: "black"
height: 40 * scaleRatio
Text {
id: statusMessageText
anchors.fill: parent
anchors.margins: 10 * scaleRatio
font.pixelSize: 14 * scaleRatio
color: "white"
}
}
function resetAndroidClose() {
console.log("resetting android close");
androidCloseTapped = false;
statusMessage.visible = false
}
function showStatusMessage(msg,timeout) {
console.log("showing status message")
statusMessageTimer.interval = timeout * 1000;
statusMessageTimer.start()
statusMessageText.text = msg;
statusMessage.visible = true
}
onClosing: {
close.accepted = false;
console.log("blocking close event");
if(isAndroid) {
console.log("blocking android exit");
if(qrScannerEnabled)
cameraUi.state = "Stopped"
if(!androidCloseTapped) {
androidCloseTapped = true;
appWindow.showStatusMessage(qsTr("Tap again to close..."),3)
// first close
return;
}
}
// If daemon is running - prompt user before exiting
if(typeof daemonManager != "undefined" && daemonManager.running(persistentSettings.testnet)) {
close.accepted = false;
// Show confirmation dialog
confirmationDialog.title = qsTr("Daemon is running") + translationManager.emptyString;
@ -1363,6 +1567,7 @@ ApplicationWindow {
}
function closeAccepted(){
console.log("close accepted");
// Close wallet non async on exit
daemonManager.exit();
walletManager.closeWallet();
@ -1407,4 +1612,14 @@ ApplicationWindow {
return false
}
function releaseFocus() {
// Workaround to release focus from textfield when scrolling (https://bugreports.qt.io/browse/QTBUG-34867)
if(isAndroid) {
console.log("releasing focus")
middlePanel.focus = true
middlePanel.focus = false
}
}
}

View File

@ -86,7 +86,7 @@ ios:arm64 {
LIBS += \
-L$$PWD/../ofxiOSBoost/build/libs/boost/lib/arm64 \
}
!ios {
!ios:!android {
LIBS += -L$$WALLET_ROOT/lib \
-lwallet_merged \
-lepee \
@ -95,6 +95,17 @@ LIBS += -L$$WALLET_ROOT/lib \
-lreadline \
}
android {
message("Host is Android")
LIBS += -L$$WALLET_ROOT/lib \
-lwallet_merged \
-lepee \
-lunbound \
-leasylogging
}
ios {
message("Host is IOS")
@ -105,7 +116,8 @@ ios {
LIBS += -L$$WALLET_ROOT/lib-ios \
-lwallet_merged \
-lepee \
-lunbound
-lunbound \
-leasylogging
LIBS+= \
-L$$PWD/../OpenSSL-for-iPhone/lib \

View File

@ -33,167 +33,106 @@ import moneroComponents.AddressBook 1.0
import moneroComponents.AddressBookModel 1.0
Rectangle {
color: "#F0EEEE"
id: root
color: "#F0EEEE"
property var model
Text {
id: newEntryText
ColumnLayout {
anchors.margins: 17 * scaleRatio
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.leftMargin: 17
anchors.topMargin: 17
anchors.right: parent.right
spacing: 10 * scaleRatio
elide: Text.ElideRight
font.family: "Arial"
font.pixelSize: 18
color: "#4A4949"
text: qsTr("Add new entry") + translationManager.emptyString
}
Label {
id: addressLabel
anchors.left: parent.left
anchors.top: newEntryText.bottom
anchors.leftMargin: 17
anchors.topMargin: 17
text: qsTr("Address") + translationManager.emptyString
fontSize: 14
}
StandardButton {
id: qrfinderButton
anchors.left: parent.left
anchors.leftMargin: 17
anchors.topMargin: 5
anchors.top: addressLabel.bottom
text: qsTr("QRCODE") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
visible : appWindow.qrScannerEnabled
enabled : visible
width: visible ? 60 : 0
onClicked: {
cameraUi.state = "Capture"
cameraUi.qrcode_decoded.connect(updateFromQrCode)
Label {
id: addressLabel
anchors.left: parent.left
text: qsTr("Address") + translationManager.emptyString
}
}
LineEdit {
id: addressLine
anchors.left: qrfinderButton.right
anchors.right: parent.right
anchors.top: addressLabel.bottom
anchors.rightMargin: 17
anchors.topMargin: 5
error: true;
placeholderText: qsTr("4...") + translationManager.emptyString
}
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
onClicked: {
cameraUi.state = "Capture"
cameraUi.qrcode_decoded.connect(updateFromQrCode)
}
}
Label {
id: paymentIdLabel
anchors.left: parent.left
anchors.top: addressLine.bottom
anchors.leftMargin: 17
anchors.topMargin: 17
text: qsTr("Payment ID <font size='2'>(Optional)</font>") + translationManager.emptyString
fontSize: 14
}
LineEdit {
Layout.fillWidth: true;
id: addressLine
error: true;
placeholderText: qsTr("4...") + translationManager.emptyString
}
}
LineEdit {
id: paymentIdLine
anchors.left: parent.left
anchors.right: parent.right
anchors.top: paymentIdLabel.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 5
placeholderText: qsTr("Paste 64 hexadecimal characters") + translationManager.emptyString
}
Label {
id: paymentIdLabel
text: qsTr("Payment ID <font size='2'>(Optional)</font>") + translationManager.emptyString
tipText: qsTr("<b>Payment ID</b><br/><br/>A unique user name used in<br/>the address book. It is not a<br/>transfer of information sent<br/>during the transfer")
+ translationManager.emptyString
}
Label {
id: descriptionLabel
anchors.left: parent.left
anchors.top: paymentIdLine.bottom
anchors.leftMargin: 17
anchors.topMargin: 17
text: qsTr("Description <font size='2'>(Optional)</font>") + translationManager.emptyString
fontSize: 14
}
LineEdit {
id: paymentIdLine
Layout.fillWidth: true;
placeholderText: qsTr("Paste 64 hexadecimal characters") + translationManager.emptyString
}
LineEdit {
id: descriptionLine
anchors.left: parent.left
anchors.right: parent.right
anchors.top: descriptionLabel.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 5
placeholderText: qsTr("Give this entry a name or description") + translationManager.emptyString
}
Label {
id: descriptionLabel
text: qsTr("Description <font size='2'>(Optional)</font>") + translationManager.emptyString
}
LineEdit {
id: descriptionLine
Layout.fillWidth: true;
placeholderText: qsTr("Give this entry a name or description") + translationManager.emptyString
}
RowLayout {
id: addButton
anchors.left: parent.left
anchors.top: descriptionLine.bottom
anchors.leftMargin: 17
anchors.topMargin: 17
RowLayout {
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.testnet)
StandardButton {
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("Add") + translationManager.emptyString
enabled: checkInformation(addressLine.text, paymentIdLine.text, appWindow.persistentSettings.testnet)
onClicked: {
if (!currentWallet.addressBook.addRow(addressLine.text.trim(), paymentIdLine.text.trim(), descriptionLine.text)) {
informationPopup.title = qsTr("Error") + translationManager.emptyString;
// TODO: check currentWallet.addressBook.errorString() instead.
if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Address)
informationPopup.text = qsTr("Invalid address") + translationManager.emptyString
else if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Payment_Id)
informationPopup.text = currentWallet.addressBook.errorString()
else
informationPopup.text = qsTr("Can't create entry") + translationManager.emptyString
onClicked: {
if (!currentWallet.addressBook.addRow(addressLine.text.trim(), paymentIdLine.text.trim(), descriptionLine.text)) {
informationPopup.title = qsTr("Error") + translationManager.emptyString;
// TODO: check currentWallet.addressBook.errorString() instead.
if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Address)
informationPopup.text = qsTr("Invalid address") + translationManager.emptyString
else if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Payment_Id)
informationPopup.text = currentWallet.addressBook.errorString()
else
informationPopup.text = qsTr("Can't create entry") + translationManager.emptyString
informationPopup.onCloseCallback = null
informationPopup.open();
} else {
addressLine.text = "";
paymentIdLine.text = "";
descriptionLine.text = "";
informationPopup.onCloseCallback = null
informationPopup.open();
} else {
addressLine.text = "";
paymentIdLine.text = "";
descriptionLine.text = "";
}
}
}
}
}
Item {
id: expandItem
property bool expanded: false
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
}
MouseArea {
anchors.fill: parent
onClicked: parent.expanded = !parent.expanded
}
}
Rectangle {
@ -201,8 +140,7 @@ Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: expandItem.expanded ? parent.height - newEntryText.y - newEntryText.height - 17 :
parent.height - addButton.y - addButton.height - 17
height: parent.height - addButton.y - addButton.height - 36 * scaleRatio
color: "#FFFFFF"
Behavior on height {
@ -217,44 +155,6 @@ Rectangle {
color: "#DBDBDB"
}
ListModel {
id: columnsModel
// ListElement { columnName: qsTr("Address") + translationManager.emptyString; columnWidth: 148 }
// ListElement { columnName: qsTr("Payment ID") + translationManager.emptyString; columnWidth: 148 }
// ListElement { columnName: qsTr("Description") + translationManager.emptyString; columnWidth: 148 }
//
}
TableHeader {
id: header
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: 17
anchors.leftMargin: 14
anchors.rightMargin: 14
dataModel: columnsModel
onSortRequest: console.log("column: " + column + " desc: " + desc)
}
ListModel {
id: testModel
ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
ListElement { paymentId: ""; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "" }
ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "Client from Australia" }
ListElement { paymentId: ""; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; description: "" }
}
Scroll {
id: flickableScroll
anchors.right: table.right
@ -268,7 +168,7 @@ Rectangle {
id: table
anchors.left: parent.left
anchors.right: parent.right
anchors.top: header.bottom
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.leftMargin: 14
anchors.rightMargin: 14

View File

@ -80,7 +80,7 @@ Rectangle {
}
onModelChanged: {
if (typeof model !== 'undefined') {
if (typeof model !== 'undefined' && model != null) {
selectedAmount.text = getSelectedAmount()
@ -146,30 +146,6 @@ Rectangle {
fontSize: 14
}
// Filter by Address input (senseless, removing)
/*
Label {
id: addressLabel
anchors.left: parent.left
anchors.top: filterHeaderText.bottom
anchors.leftMargin: 17
anchors.topMargin: 17
text: qsTr("Address")
fontSize: 14
}
LineEdit {
id: addressLine
anchors.left: parent.left
anchors.right: parent.right
anchors.top: addressLabel.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 5
}
*/
// Filter by string
LineEdit {
visible: !isMobile
@ -488,7 +464,7 @@ Rectangle {
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 }
@ -498,12 +474,13 @@ Rectangle {
TableHeader {
id: header
visible: !isMobile
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: 17
anchors.leftMargin: 14
anchors.rightMargin: 14
anchors.topMargin: 17 * scaleRatio
anchors.leftMargin: 14 * scaleRatio
anchors.rightMargin: 14 * scaleRatio
dataModel: columnsModel
offset: 20
onSortRequest: {
@ -532,8 +509,9 @@ Rectangle {
Scroll {
id: flickableScroll
visible: !isMobile
anchors.right: table.right
anchors.rightMargin: -14
anchors.rightMargin: !isMobile ? -14 * scaleRatio : 0
anchors.top: table.top
anchors.bottom: table.bottom
flickable: table
@ -541,19 +519,37 @@ Rectangle {
HistoryTable {
id: table
visible: !isMobile
anchors.left: parent.left
anchors.right: parent.right
anchors.top: header.bottom
anchors.bottom: parent.bottom
anchors.leftMargin: 14
anchors.rightMargin: 14
anchors.leftMargin: 14 * scaleRatio
anchors.rightMargin: 14 * scaleRatio
onContentYChanged: flickableScroll.flickableContentYChanged()
model: root.model
model: !isMobile ? root.model : null
addressBookModel: null
}
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
}
}
function onPageCompleted() {
table.addressBookModel = appWindow.currentWallet ? appWindow.currentWallet.addressBookModel : null
if(currentWallet != null && typeof currentWallet.history !== "undefined" ) {
currentWallet.history.refresh()
table.addressBookModel = currentWallet ? currentWallet.addressBookModel : null
transactionTypeDropdown.update()
}
}
}

221
pages/Keys.qml Normal file
View File

@ -0,0 +1,221 @@
// Copyright (c) 2014-2017, 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.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
Rectangle {
property bool viewOnly: false
id: page
color: "#F0EEEE"
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
Layout.fillWidth: true
//! Manage wallet
ColumnLayout {
Layout.fillWidth: true
Label {
Layout.fillWidth: true
text: qsTr("Mnemonic seed") + translationManager.emptyString
}
Rectangle {
Layout.fillWidth: true
height: 1
color: "#DEDEDE"
}
TextEdit {
id: seedText
wrapMode: TextEdit.Wrap
Layout.fillWidth: true;
font.pixelSize: 14 * scaleRatio
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)
}
}
}
}
ColumnLayout {
Layout.fillWidth: true
Label {
Layout.fillWidth: true
text: qsTr("Keys") + translationManager.emptyString
}
Rectangle {
Layout.fillWidth: true
height: 1
color: "#DEDEDE"
}
TextEdit {
id: keysText
wrapMode: TextEdit.Wrap
Layout.fillWidth: true;
font.pixelSize: 14 * scaleRatio
textFormat: TextEdit.RichText
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("Keys copied to clipboard"),3)
}
}
}
}
ColumnLayout {
Layout.fillWidth: true
Label {
Layout.fillWidth: true
text: qsTr("Export wallet") + translationManager.emptyString
}
Rectangle {
Layout.fillWidth: true
height: 1
color: "#DEDEDE"
}
RowLayout {
StandardButton {
enabled: !fullWalletQRCode.visible
id: showFullQr
text: qsTr("Spendable Wallet") + translationManager.emptyString
onClicked: {
viewOnlyQRCode.visible = false
}
}
StandardButton {
enabled: fullWalletQRCode.visible
id: showViewOnlyQr
text: qsTr("View Only Wallet") + translationManager.emptyString
onClicked: {
viewOnlyQRCode.visible = true
}
}
Layout.bottomMargin: 30 * scaleRatio
}
Image {
visible: !viewOnlyQRCode.visible
id: fullWalletQRCode
Layout.fillWidth: true
Layout.minimumHeight: 180 * scaleRatio
smooth: false
fillMode: Image.PreserveAspectFit
}
Image {
visible: false
id: viewOnlyQRCode
Layout.fillWidth: true
Layout.minimumHeight: 180 * scaleRatio
smooth: false
fillMode: Image.PreserveAspectFit
}
Text {
Layout.fillWidth: true
font.bold: true
font.pixelSize: 16 * scaleRatio
text: (viewOnlyQRCode.visible) ? qsTr("View Only Wallet") + translationManager.emptyString : qsTr("Spendable Wallet") + translationManager.emptyString
horizontalAlignment: Text.AlignHCenter
}
}
}
// fires on every page load
function onPageCompleted() {
console.log("keys page loaded");
keysText.text = "<b>" + qsTr("Secret view key") + ":</b> " + currentWallet.secretViewKey
keysText.text += "<br><br><b>" + qsTr("Public view key") + ":</b> " + currentWallet.publicViewKey
keysText.text += (!currentWallet.viewOnly) ? "<br><br><b>" + qsTr("Secret spend key") + ":</b> " + currentWallet.secretSpendKey : ""
keysText.text += "<br><br><b>" + qsTr("Public spend key") + ":</b> " + currentWallet.publicSpendKey
seedText.text = currentWallet.seed
if(typeof currentWallet != "undefined") {
viewOnlyQRCode.source = "image://qrcode/monero:" + currentWallet.address+"?secret_view_key="+currentWallet.secretViewKey+"&restore_height="+currentWallet.restoreHeight
fullWalletQRCode.source = viewOnlyQRCode.source +"&secret_spend_key="+currentWallet.secretSpendKey
if(currentWallet.viewOnly) {
viewOnlyQRCode.visible = true
showFullQr.visible = false
showViewOnlyQr.visible = false
seedText.text = qsTr("(View Only Wallet - No mnemonic seed available)") + translationManager.emptyString
}
}
}
// fires only once
Component.onCompleted: {
}
}

View File

@ -37,6 +37,15 @@ Rectangle {
color: "#F0EEEE"
property var currentHashRate: 0
function isDaemonLocal() {
if (appWindow.currentDaemonAddress === "")
return false
var daemonHost = appWindow.currentDaemonAddress.split(":")[0]
if (daemonHost === "127.0.0.1" || daemonHost === "localhost")
return true
return false
}
/* main layout */
ColumnLayout {
id: mainLayout

View File

@ -169,24 +169,23 @@ Rectangle {
ColumnLayout {
id: mainLayout
anchors.margins: (isMobile)? 17 : 40
anchors.topMargin: 40
anchors.topMargin: 40 * scaleRatio
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
spacing: 20
property int labelWidth: 120
property int editWidth: 400
property int lineEditFontSize: 12
property int qrCodeSize: 240
spacing: 20 * scaleRatio
property int labelWidth: 120 * scaleRatio
property int editWidth: 400 * scaleRatio
property int lineEditFontSize: 12 * scaleRatio
property int qrCodeSize: 240 * scaleRatio
ColumnLayout {
id: addressRow
Label {
id: addressLabel
fontSize: 14
text: qsTr("Address") + translationManager.emptyString
width: mainLayout.labelWidth
}
@ -206,6 +205,7 @@ Rectangle {
if (addressLine.text.length > 0) {
console.log(addressLine.text + " copied to clipboard")
clipboard.setText(addressLine.text)
appWindow.showStatusMessage(qsTr("Address copied to clipboard"),3)
}
}
}
@ -218,7 +218,6 @@ Rectangle {
Label {
Layout.columnSpan: 2
id: paymentIdLabel
fontSize: 14
text: qsTr("Payment ID") + translationManager.emptyString
width: mainLayout.labelWidth
}
@ -239,6 +238,7 @@ Rectangle {
onClicked: {
if (paymentIdLine.text.length > 0) {
clipboard.setText(paymentIdLine.text)
appWindow.showStatusMessage(qsTr("Payment ID copied to clipboard"),3)
}
}
}
@ -246,7 +246,6 @@ Rectangle {
StandardButton {
id: generatePaymentId
width: 80
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
@ -258,7 +257,6 @@ Rectangle {
StandardButton {
id: clearPaymentId
enabled: !!paymentIdLine.text
width: 80
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
@ -272,7 +270,6 @@ Rectangle {
id: integratedAddressRow
Label {
id: integratedAddressLabel
fontSize: 14
text: qsTr("Integrated address") + translationManager.emptyString
width: mainLayout.labelWidth
}
@ -294,6 +291,7 @@ Rectangle {
onClicked: {
if (integratedAddressLine.text.length > 0) {
clipboard.setText(integratedAddressLine.text)
appWindow.showStatusMessage(qsTr("Integrated address copied to clipboard"),3)
}
}
}
@ -305,7 +303,6 @@ Rectangle {
id: amountRow
Label {
id: amountLabel
fontSize: 14
text: qsTr("Amount") + translationManager.emptyString
width: mainLayout.labelWidth
}
@ -330,10 +327,9 @@ Rectangle {
RowLayout {
id: trackingRow
visible: !isAndroid && !isIOS
Label {
id: trackingLabel
fontSize: 14
textFormat: Text.RichText
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>\
Tracking <font size='2'> (</font><a href='#'>help</a><font size='2'>)</font>")
@ -392,33 +388,33 @@ Rectangle {
}
}
}
Menu {
id: qrMenu
title: "QrCode"
MenuItem {
text: qsTr("Save As") + translationManager.emptyString;
onTriggered: qrFileDialog.open()
}
}
Image {
id: qrCode
anchors.margins: 50
anchors.top: trackingRow.bottom
Layout.fillWidth: true
Layout.minimumHeight: mainLayout.qrCodeSize
smooth: false
fillMode: Image.PreserveAspectFit
source: "image://qrcode/" + makeQRCodeString()
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: {
if (mouse.button == Qt.RightButton)
qrMenu.popup()
ColumnLayout {
Menu {
id: qrMenu
title: "QrCode"
MenuItem {
text: qsTr("Save As") + translationManager.emptyString;
onTriggered: qrFileDialog.open()
}
}
Image {
id: qrCode
anchors.margins: 50 * scaleRatio
Layout.fillWidth: true
Layout.minimumHeight: mainLayout.qrCodeSize
smooth: false
fillMode: Image.PreserveAspectFit
source: "image://qrcode/" + makeQRCodeString()
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: {
if (mouse.button == Qt.RightButton)
qrMenu.popup()
}
onPressAndHold: qrFileDialog.open()
}
onPressAndHold: qrFileDialog.open()
}
}
}

View File

@ -38,7 +38,6 @@ import "../components"
import moneroComponents.Clipboard 1.0
Rectangle {
property var daemonAddress
property bool viewOnly: false
id: page
@ -48,20 +47,15 @@ Rectangle {
function initSettings() {
//runs on every page load
// Daemon settings
daemonAddress = persistentSettings.daemon_address.split(":");
console.log("address: " + persistentSettings.daemon_address)
// try connecting to daemon
}
ColumnLayout {
id: mainLayout
anchors.margins: 17
anchors.margins: 17 * scaleRatio
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
spacing: 10
spacing: 10 * scaleRatio
//! Manage wallet
RowLayout {
@ -70,8 +64,7 @@ Rectangle {
Layout.fillWidth: true
color: "#4A4949"
text: qsTr("Manage wallet") + translationManager.emptyString
fontSize: 16
Layout.topMargin: 10
Layout.topMargin: 10 * scaleRatio
}
}
@ -82,7 +75,7 @@ Rectangle {
}
GridLayout {
columns: (isMobile)? 2 : 4
columns: (isMobile)? 1 : 4
StandardButton {
id: closeWalletButton
text: qsTr("Close wallet") + translationManager.emptyString
@ -111,18 +104,6 @@ Rectangle {
}
}
StandardButton {
id: showSeedButton
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("Show seed & keys") + translationManager.emptyString
onClicked: {
settingsPasswordDialog.open();
}
}
/* Rescan cache - Disabled until we know it's needed
StandardButton {
@ -160,6 +141,7 @@ Rectangle {
*/
StandardButton {
id: rescanSpentButton
enabled: !persistentSettings.useRemoteNode
text: qsTr("Rescan wallet balance") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@ -184,16 +166,53 @@ Rectangle {
}
}
RowLayout {
StandardButton {
id: remoteDisconnect
enabled: persistentSettings.useRemoteNode
Layout.fillWidth: false
text: qsTr("Local Node") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
onClicked: {
appWindow.disconnectRemoteNode();
}
}
StandardButton {
id: remoteConnect
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
Layout.fillWidth: true
color: "#4A4949"
text: qsTr("Manage daemon") + translationManager.emptyString
fontSize: 16
anchors.topMargin: 30
Layout.topMargin: 30
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 {
@ -203,27 +222,28 @@ Rectangle {
}
GridLayout {
visible: !isMobile
id: daemonStatusRow
columns: (isMobile) ? 2 : 4
StandardButton {
visible: true
enabled: !appWindow.daemonRunning
visible: !appWindow.daemonRunning
id: startDaemonButton
text: qsTr("Start daemon") + translationManager.emptyString
text: qsTr("Start Local Node") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
onClicked: {
// Set current daemon address to local
appWindow.currentDaemonAddress = appWindow.localDaemonAddress
appWindow.startDaemon(daemonFlags.text)
}
}
StandardButton {
visible: true
enabled: appWindow.daemonRunning
visible: appWindow.daemonRunning
id: stopDaemonButton
text: qsTr("Stop daemon") + translationManager.emptyString
text: qsTr("Stop Local Node") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
@ -246,16 +266,15 @@ Rectangle {
daemonConsolePopup.open();
}
}
}
RowLayout {
ColumnLayout {
id: blockchainFolderRow
visible: !isMobile
Label {
id: blockchainFolderLabel
color: "#4A4949"
text: qsTr("Blockchain location") + translationManager.emptyString
fontSize: 16
}
LineEdit {
id: blockchainFolder
@ -278,13 +297,14 @@ Rectangle {
}
}
RowLayout {
visible: daemonAdvanced.checked && !isMobile
id: daemonFlagsRow
Label {
id: daemonFlagsLabel
color: "#4A4949"
text: qsTr("Daemon startup flags") + translationManager.emptyString
fontSize: 16
text: qsTr("Local daemon startup flags") + translationManager.emptyString
}
LineEdit {
id: daemonFlags
@ -297,59 +317,21 @@ Rectangle {
RowLayout {
Layout.fillWidth: true
spacing: 10
Label {
id: daemonAddrLabel
Layout.fillWidth: true
color: "#4A4949"
text: qsTr("Daemon address") + translationManager.emptyString
fontSize: 16
}
}
GridLayout {
id: daemonAddrRow
Layout.fillWidth: true
columnSpacing: 10
columns: (isMobile) ? 2 : 3
LineEdit {
id: daemonAddr
Layout.preferredWidth: 100
Layout.fillWidth: true
text: (daemonAddress !== undefined) ? daemonAddress[0] : ""
placeholderText: qsTr("Hostname / IP") + translationManager.emptyString
}
LineEdit {
id: daemonPort
Layout.preferredWidth: 100
Layout.fillWidth: true
text: (daemonAddress !== undefined) ? daemonAddress[1] : "18081"
placeholderText: qsTr("Port") + translationManager.emptyString
}
}
RowLayout {
Layout.fillWidth: true
spacing: 10
visible: daemonAdvanced.checked || isMobile
Label {
id: daemonLoginLabel
Layout.fillWidth: true
color: "#4A4949"
text: qsTr("Login (optional)") + translationManager.emptyString
fontSize: 16
text: qsTr("Node login (optional)") + translationManager.emptyString
}
}
RowLayout {
ColumnLayout {
visible: daemonAdvanced.checked || isMobile
LineEdit {
id: daemonUsername
Layout.preferredWidth: 100
Layout.preferredWidth: 100 * scaleRatio
Layout.fillWidth: true
text: persistentSettings.daemonUsername
placeholderText: qsTr("Username") + translationManager.emptyString
@ -358,50 +340,65 @@ Rectangle {
LineEdit {
id: daemonPassword
Layout.preferredWidth: 100
Layout.preferredWidth: 100 * scaleRatio
Layout.fillWidth: true
text: persistentSettings.daemonPassword
placeholderText: qsTr("Password") + translationManager.emptyString
echoMode: TextInput.Password
}
}
StandardButton {
id: daemonAddrSave
Layout.fillWidth: false
Layout.leftMargin: 30
text: qsTr("Connect") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
onClicked: {
console.log("saving daemon adress settings")
var newDaemon = daemonAddr.text.trim() + ":" + daemonPort.text.trim()
if(persistentSettings.daemon_address != newDaemon) {
persistentSettings.daemon_address = newDaemon
RowLayout {
visible: persistentSettings.useRemoteNode
ColumnLayout {
Label {
color: "#4A4949"
text: qsTr("Remote node") + translationManager.emptyString
}
RemoteNodeEdit {
id: remoteNodeEdit
Layout.minimumWidth: 100 * scaleRatio
daemonAddrText: persistentSettings.remoteNodeAddress.split(":")[0].trim()
daemonPortText: (persistentSettings.remoteNodeAddress.split(":")[1].trim() == "") ? "18081" : persistentSettings.remoteNodeAddress.split(":")[1]
onEditingFinished: {
persistentSettings.remoteNodeAddress = remoteNodeEdit.getAddress();
console.log("setting remote node to " + persistentSettings.remoteNodeAddress)
}
}
// Update daemon login
persistentSettings.daemonUsername = daemonUsername.text;
persistentSettings.daemonPassword = daemonPassword.text;
currentWallet.setDaemonLogin(persistentSettings.daemonUsername, persistentSettings.daemonPassword);
StandardButton {
id: remoteNodeSave
text: qsTr("Connect") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
onClicked: {
// Update daemon login
persistentSettings.remoteNodeAddress = remoteNodeEdit.getAddress();
persistentSettings.daemonUsername = daemonUsername.text;
persistentSettings.daemonPassword = daemonPassword.text;
persistentSettings.useRemoteNode = true
//Reinit wallet
currentWallet.initAsync(newDaemon);
currentWallet.setDaemonLogin(persistentSettings.daemonUsername, persistentSettings.daemonPassword);
appWindow.connectRemoteNode()
}
}
}
}
RowLayout {
visible: !isMobile
Label {
color: "#4A4949"
text: qsTr("Layout settings") + translationManager.emptyString
fontSize: 16
anchors.topMargin: 30
Layout.topMargin: 30
anchors.topMargin: 30 * scaleRatio
Layout.topMargin: 30 * scaleRatio
}
}
Rectangle {
visible: !isMobile
Layout.fillWidth: true
height: 1
color: "#DEDEDE"
@ -409,6 +406,7 @@ Rectangle {
RowLayout {
CheckBox {
visible: !isMobile
id: customDecorationsCheckBox
checked: persistentSettings.customDecorations
onClicked: appWindow.setCustomWindowDecorations(checked)
@ -424,9 +422,8 @@ Rectangle {
Label {
color: "#4A4949"
text: qsTr("Log level") + translationManager.emptyString
fontSize: 16
anchors.topMargin: 30
Layout.topMargin: 30
anchors.topMargin: 30 * scaleRatio
Layout.topMargin: 30 * scaleRatio
}
}
Rectangle {
@ -454,7 +451,6 @@ Rectangle {
LineEdit {
id: logCategories
Layout.preferredWidth: 200
Layout.fillWidth: true
text: appWindow.persistentSettings.logCategories
placeholderText: qsTr("(e.g. *:WARNING,net.p2p:DEBUG)") + translationManager.emptyString
@ -475,8 +471,8 @@ Rectangle {
color: "#4A4949"
text: qsTr("Debug info") + translationManager.emptyString
fontSize: 16
anchors.topMargin: 30
Layout.topMargin: 30
anchors.topMargin: 30 * scaleRatio
Layout.topMargin: 30 * scaleRatio
}
}
Rectangle {
@ -484,13 +480,11 @@ Rectangle {
height: 1
color: "#DEDEDE"
}
TextBlock {
Layout.topMargin: 8
Layout.fillWidth: true
text: qsTr("GUI version: ") + Version.GUI_VERSION + translationManager.emptyString
}
TextBlock {
id: guiMoneroVersion
Layout.fillWidth: true
@ -588,61 +582,6 @@ Rectangle {
}
}
PasswordDialog {
id: settingsPasswordDialog
onAccepted: {
if(appWindow.password === settingsPasswordDialog.password){
if(currentWallet.seedLanguage == "") {
console.log("No seed language set. Using English as default");
currentWallet.setSeedLanguage("English");
}
seedPopup.title = qsTr("Wallet seed & keys") + translationManager.emptyString;
seedPopup.text = "<b>Wallet Mnemonic seed</b> <br>" + currentWallet.seed
+ "<br><br> <b>" + qsTr("Secret view key") + ":</b> " + currentWallet.secretViewKey
+ "<br><b>" + qsTr("Public view key") + ":</b> " + currentWallet.publicViewKey
+ "<br><b>" + qsTr("Secret spend key") + ":</b> " + currentWallet.secretSpendKey
+ "<br><b>" + qsTr("Public spend key") + ":</b> " + currentWallet.publicSpendKey
seedPopup.open()
seedPopup.width = 600
seedPopup.height = 300
seedPopup.onCloseCallback = function() {
seedPopup.text = ""
}
} else {
informationPopup.title = qsTr("Error") + translationManager.emptyString;
informationPopup.text = qsTr("Wrong password");
informationPopup.open()
informationPopup.onCloseCallback = function() {
settingsPasswordDialog.open()
}
}
settingsPasswordDialog.password = ""
}
onRejected: {
}
}
StandardDialog {
id: seedPopup
cancelVisible: false
okVisible: true
width:600
height:400
property var onCloseCallback
onAccepted: {
if (onCloseCallback) {
onCloseCallback()
}
}
}
// Choose blockchain folder
FileDialog {
id: blockchainFileDialog
@ -670,7 +609,6 @@ Rectangle {
if(!validator.lmdbExists) {
confirmationDialog.text += qsTr("Note: lmdb folder not found. A new folder will be created.") + "\n\n"
}
confirmationDialog.icon = StandardIcon.Question
confirmationDialog.cancelText = qsTr("Cancel")
@ -703,7 +641,7 @@ Rectangle {
function onPageCompleted() {
console.log("Settings page loaded");
initSettings();
viewOnly = currentWallet.viewOnly;
if(typeof daemonManager != "undefined")
appWindow.daemonRunning = daemonManager.running(persistentSettings.testnet)
@ -713,8 +651,6 @@ Rectangle {
Component.onCompleted: {
if(typeof daemonManager != "undefined")
daemonManager.daemonConsoleUpdated.connect(onDaemonConsoleUpdated)
}
function onDaemonConsoleUpdated(message){

View File

@ -39,10 +39,6 @@ import moneroComponents.WalletManager 1.0
Rectangle {
id: mainLayout
property int labelWidth: 120
// property int editWidth: 400
property int lineEditFontSize: 12
color: "#F0EEEE"
Clipboard { id: clipboard }
@ -92,35 +88,31 @@ Rectangle {
// sign / verify
ColumnLayout {
anchors.margins: 17
anchors.margins: 17 * scaleRatio
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
spacing: 20
spacing: 20 * scaleRatio
// sign
ColumnLayout {
id: signBox
RowLayout {
ColumnLayout {
spacing: 8
Label {
text: qsTr("Sign a message or file contents with your address:") + translationManager.emptyString
fontSize: 16
wrapMode: Text.Wrap
}
Label {}
Text {
text: qsTr("Sign a message or file contents with your address:") + translationManager.emptyString
wrapMode: Text.Wrap
font.pixelSize: 14 * scaleRatio
Layout.fillWidth: true
}
}
Label {
id: signMessageLabel
fontSize: 14
text: qsTr("Either message:") + translationManager.emptyString
width: mainLayout.labelWidth
}
RowLayout {
@ -133,10 +125,8 @@ Rectangle {
id: signMessageLine
anchors.left: parent.left
anchors.right: signMessageButton.left
fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("Message to sign") + translationManager.emptyString;
readOnly: false
// Layout.fillWidth: true
onTextChanged: signSignatureLine.text = ""
IconButton {
@ -152,7 +142,6 @@ Rectangle {
StandardButton {
id: signMessageButton
anchors.right: parent.right
width: 60
text: qsTr("Sign") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@ -168,9 +157,7 @@ Rectangle {
Label {
id: signMessageFileLabel
fontSize: 14
text: qsTr("Or file:") + translationManager.emptyString
width: mainLayout.labelWidth
}
RowLayout {
@ -192,8 +179,7 @@ Rectangle {
StandardButton {
id: loadFileToSignButton
anchors.rightMargin: 17
width: 60
anchors.rightMargin: 17 * scaleRatio
text: qsTr("Select") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@ -208,7 +194,6 @@ Rectangle {
id: signFileLine
anchors.left: loadFileToSignButton.right
anchors.right: signFileButton.left
fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("Filename with message to sign") + translationManager.emptyString;
readOnly: false
Layout.fillWidth: true
@ -227,7 +212,6 @@ Rectangle {
StandardButton {
id: signFileButton
anchors.right: parent.right
width: 60
text: qsTr("Sign") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@ -241,19 +225,17 @@ Rectangle {
}
}
RowLayout {
ColumnLayout {
id: signSignatureRow
anchors.topMargin: 17
anchors.topMargin: 17 * scaleRatio
Label {
id: signSignatureLabel
fontSize: 14
text: qsTr("Signature") + translationManager.emptyString
}
LineEdit {
id: signSignatureLine
fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("Signature") + translationManager.emptyString;
readOnly: true
Layout.fillWidth: true
@ -275,29 +257,24 @@ Rectangle {
ColumnLayout {
id: verifyBox
RowLayout {
ColumnLayout {
spacing: 8
Label {
text: qsTr("Verify a message or file signature from an address:") + translationManager.emptyString
fontSize: 16
// Layout.fillWidth: true
wrapMode: Text.Wrap
}
Label {}
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
fontSize: 14
text: qsTr("Either message:") + translationManager.emptyString
width: mainLayout.labelWidth
}
RowLayout {
id: verifyMessageRow
anchors.topMargin: 17
anchors.topMargin: 17 * scaleRatio
anchors.left: parent.left
anchors.right: parent.right
@ -305,7 +282,6 @@ Rectangle {
id: verifyMessageLine
anchors.left: parent.left
anchors.right: verifyMessageButton.left
fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("Message to verify") + translationManager.emptyString;
readOnly: false
Layout.fillWidth: true
@ -323,7 +299,6 @@ Rectangle {
StandardButton {
id: verifyMessageButton
anchors.right: parent.right
width: 60
text: qsTr("Verify") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@ -339,16 +314,14 @@ Rectangle {
Label {
id: verifyMessageFileLabel
fontSize: 14
text: qsTr("Or file:") + translationManager.emptyString
width: mainLayout.labelWidth
}
RowLayout {
id: verifyFileRow
anchors.topMargin: 17
anchors.topMargin: 17 * scaleRatio
anchors.left: parent.left
anchors.right: parent.right
anchors.right: parent.right
FileDialog {
id: verifyFileDialog
@ -363,8 +336,7 @@ Rectangle {
StandardButton {
id: loadFileToVerifyButton
anchors.rightMargin: 17
width: 60
anchors.rightMargin: 17 * scaleRatio
text: qsTr("Select") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@ -379,7 +351,6 @@ Rectangle {
id: verifyFileLine
anchors.left: loadFileToVerifyButton.right
anchors.right: verifyFileButton.left
fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("Filename with message to verify") + translationManager.emptyString;
readOnly: false
Layout.fillWidth: true
@ -397,7 +368,6 @@ Rectangle {
StandardButton {
id: verifyFileButton
anchors.right: parent.right
width: 60
text: qsTr("Verify") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@ -411,18 +381,16 @@ Rectangle {
}
}
Label {
Text {
id: verifyAddressLabel
fontSize: 14
width: mainLayout.labelWidth
textFormat: Text.RichText
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>\
Signing address <font size='2'> ( Paste in or select from </font> <a href='#'>Address book</a><font size='2'> )</font>")
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: %1px;}</style>\
Signing address <font size='%2'> ( Paste in or select from </font> <a href='#'>Address book</a><font size='%3'> )</font>").arg(14 * scaleRatio).arg(2 * scaleRatio).arg(2 * scaleRatio)
+ translationManager.emptyString
// Layout.fillWidth: true
wrapMode: Text.Wrap
onLinkActivated: appWindow.showPageRequest("AddressBook")
font.pixelSize: 14 * scaleRatio
Layout.fillWidth: true
textFormat: Text.RichText
onLinkActivated: appWindow.showPageRequest("AddressBook")
}
LineEdit {
@ -430,24 +398,22 @@ Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: verifyAddressLabel.bottom
anchors.topMargin: 5
anchors.topMargin: 5 * scaleRatio
placeholderText: "4..."
// validator: RegExpValidator { regExp: /[0-9A-Fa-f]{95}/g }
}
RowLayout {
ColumnLayout {
id: verifySignatureRow
anchors.topMargin: 17
anchors.topMargin: 17 * scaleRatio
Label {
id: verifySignatureLabel
fontSize: 14
text: qsTr("Signature") + translationManager.emptyString
}
LineEdit {
id: verifySignatureLine
fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("Signature") + translationManager.emptyString;
Layout.fillWidth: true

View File

@ -71,10 +71,10 @@ Rectangle {
}
function updateMixin() {
var fillLevel = privacyLevelItem.fillLevel
var fillLevel = (isMobile) ? privacyLevelItemSmall.fillLevel : privacyLevelItem.fillLevel
var mixin = scaleValueToMixinCount(fillLevel)
print ("PrivacyLevel changed:" + fillLevel)
print ("mixin count: " + mixin)
console.log("PrivacyLevel changed:" + fillLevel)
console.log("mixin count: " + mixin)
privacyLabel.text = qsTr("Privacy level (ringsize %1)").arg(mixin+1) + translationManager.emptyString
}
@ -107,297 +107,226 @@ Rectangle {
}
}
Item {
ColumnLayout {
id: pageRoot
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
height: 400
anchors.margins: 17 * scaleRatio
spacing: 0
Label {
id: amountLabel
anchors.left: parent.left
anchors.top: parent.top
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 17
text: qsTr("Amount") + translationManager.emptyString
fontSize: 14
}
GridLayout {
columns: (isMobile)? 1 : 2
Layout.fillWidth: true
Label {
id: transactionPriority
anchors.top: parent.top
anchors.topMargin: 17
fontSize: 14
x: (parent.width - 17) / 2 + 17
text: qsTr("Transaction priority") + translationManager.emptyString
}
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"
}
}
// Amount input
LineEdit {
Layout.fillWidth: true
id: amountLine
placeholderText: qsTr("") + translationManager.emptyString
width:100
validator: DoubleValidator {
bottom: 0.0
top: 18446744.073709551615
decimals: 12
notation: DoubleValidator.StandardNotation
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)"
}
}
Row {
id: amountRow
anchors.top: amountLabel.bottom
anchors.topMargin: 5
anchors.left: parent.left
anchors.leftMargin: 7
width: (parent.width - 17) / 2 + 10
Item {
width: 37
height: 37
}
Image {
anchors.centerIn: parent
source: "../images/moneroIcon.png"
ColumnLayout {
Layout.fillWidth: true
Label {
id: transactionPriority
text: qsTr("Transaction priority") + translationManager.emptyString
}
// Note: workaround for translations in listElements
// ListElement: cannot use script for property value, so
// code like this wont work:
// 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.
// Priorities before v5
ListModel {
id: priorityModel
ListElement { column1: qsTr("Low (x1 fee)") ; column2: ""; priority: PendingTransaction.Priority_Low }
ListElement { column1: qsTr("Medium (x20 fee)") ; column2: ""; priority: PendingTransaction.Priority_Medium }
ListElement { column1: qsTr("High (x166 fee)") ; column2: ""; priority: PendingTransaction.Priority_High }
}
// Priorites after v5
ListModel {
id: priorityModelV5
ListElement { column1: qsTr("Slow (x0.25 fee)") ; column2: ""; priority: 1}
ListElement { column1: qsTr("Default (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
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
}
}
// Amount input
LineEdit {
id: amountLine
placeholderText: qsTr("") + translationManager.emptyString
width: parent.width - 37 - 17 - 60
validator: DoubleValidator {
bottom: 0.0
top: 18446744.073709551615
decimals: 12
notation: DoubleValidator.StandardNotation
locale: "C"
// Make sure dropdown is on top
z: parent.z + 1
}
ColumnLayout {
Layout.fillWidth: true
Label {
id: addressLabel
textFormat: Text.RichText
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>\
Address <font size='2'> ( Paste in or select from </font> <a href='#'>Address book</a><font size='2'> )</font>")
+ 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)
}
}
}
StandardButton {
id: amountAllButton
//anchors.left: amountLine.right
//anchors.top: amountLine.top
//anchors.bottom: amountLine.bottom
width: 60
text: qsTr("All") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
enabled : true
onClicked: amountLine.text = "(all)"
}
}
// Note: workaround for translations in listElements
// ListElement: cannot use script for property value, so
// code like this wont work:
// 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.
// Priorities before v5
ListModel {
id: priorityModel
ListElement { column1: qsTr("Low (x1 fee)") ; column2: ""; priority: PendingTransaction.Priority_Low }
ListElement { column1: qsTr("Medium (x20 fee)") ; column2: ""; priority: PendingTransaction.Priority_Medium }
ListElement { column1: qsTr("High (x166 fee)") ; column2: ""; priority: PendingTransaction.Priority_High }
}
// Priorites after v5
ListModel {
id: priorityModelV5
ListElement { column1: qsTr("Slow (x0.25 fee)") ; column2: ""; priority: 1}
ListElement { column1: qsTr("Default (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 {
id: priorityDropdown
anchors.top: transactionPriority.bottom
anchors.right: parent.right
anchors.rightMargin: 17
anchors.topMargin: 5
anchors.left: transactionPriority.left
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
z: 1
}
Label {
id: addressLabel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: amountRow.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 30
fontSize: 14
textFormat: Text.RichText
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>\
Address <font size='2'> ( Paste in or select from </font> <a href='#'>Address book</a><font size='2'> )</font>")
+ translationManager.emptyString
onLinkActivated: appWindow.showPageRequest("AddressBook")
}
// recipient address input
RowLayout {
id: addressLineRow
anchors.left: parent.left
anchors.right: parent.right
anchors.top: addressLabel.bottom
StandardButton {
id: qrfinderButton
anchors.left: parent.left
anchors.leftMargin: 17
anchors.topMargin: 5
text: qsTr("QR Code") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
visible : appWindow.qrScannerEnabled
enabled : visible
width: visible ? 60 : 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 }
}
}
LineEdit {
id: addressLine
anchors.left: qrfinderButton.right
anchors.right: resolveButton.left
//anchors.leftMargin: 17
anchors.topMargin: 5
placeholderText: "4..."
// validator: RegExpValidator { regExp: /[0-9A-Fa-f]{95}/g }
}
StandardButton {
id: resolveButton
anchors.right: parent.right
anchors.leftMargin: 17
anchors.topMargin: 17
anchors.rightMargin: 17
width: 60
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.testnet)
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"))
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.testnet)
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"))
}
} 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"))
oa_message(qsTr("Internal error"))
}
} else {
oa_message(qsTr("Internal error"))
oa_message(qsTr("No address found"))
}
} else {
oa_message(qsTr("Internal error"))
}
} else {
oa_message(qsTr("No address found"))
}
}
}
}
Label {
id: paymentIdLabel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: addressLineRow.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 17
fontSize: 14
text: qsTr("Payment ID <font size='2'>( Optional )</font>") + translationManager.emptyString
}
Label {
id: paymentIdLabel
text: qsTr("Payment ID <font size='2'>( Optional )</font>") + translationManager.emptyString
}
// payment id input
LineEdit {
id: paymentIdLine
anchors.left: parent.left
anchors.right: parent.right
anchors.top: paymentIdLabel.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 5
placeholderText: qsTr("16 or 64 hexadecimal characters") + translationManager.emptyString
// validator: DoubleValidator { top: 0.0 }
}
// payment id input
LineEdit {
id: paymentIdLine
placeholderText: qsTr("16 or 64 hexadecimal characters") + translationManager.emptyString
Layout.fillWidth: true
}
Label {
id: descriptionLabel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: paymentIdLine.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 17
fontSize: 14
text: qsTr("Description <font size='2'>( Optional )</font>")
+ translationManager.emptyString
}
Label {
text: qsTr("Description <font size='2'>( Optional )</font>")
+ translationManager.emptyString
}
LineEdit {
id: descriptionLine
anchors.left: parent.left
anchors.right: parent.right
anchors.top: descriptionLabel.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 5
placeholderText: qsTr("Saved to local wallet history") + translationManager.emptyString
}
function checkInformation(amount, address, payment_id, testnet) {
address = address.trim()
payment_id = payment_id.trim()
var amount_ok = amount.length > 0
var address_ok = walletManager.addressValid(address, testnet)
var payment_id_ok = payment_id.length == 0 || walletManager.paymentIdValid(payment_id)
var ipid = walletManager.paymentIdFromAddress(address, testnet)
if (ipid.length > 0 && payment_id.length > 0)
payment_id_ok = false
addressLine.error = !address_ok
amountLine.error = !amount_ok
paymentIdLine.error = !payment_id_ok
return amount_ok && address_ok && payment_id_ok
}
RowLayout {
anchors.left: parent.left
anchors.top: descriptionLine.bottom
anchors.leftMargin: 17
anchors.topMargin: 17
LineEdit {
id: descriptionLine
placeholderText: qsTr("Saved to local wallet history") + translationManager.emptyString
Layout.fillWidth: true
}
StandardButton {
id: sendButton
Layout.bottomMargin: 17 * scaleRatio
Layout.topMargin: 17 * scaleRatio
text: qsTr("Send") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@ -418,6 +347,23 @@ Rectangle {
}
}
function checkInformation(amount, address, payment_id, testnet) {
address = address.trim()
payment_id = payment_id.trim()
var amount_ok = amount.length > 0
var address_ok = walletManager.addressValid(address, testnet)
var payment_id_ok = payment_id.length == 0 || walletManager.paymentIdValid(payment_id)
var ipid = walletManager.paymentIdFromAddress(address, testnet)
if (ipid.length > 0 && payment_id.length > 0)
payment_id_ok = false
addressLine.error = !address_ok
amountLine.error = !amount_ok
paymentIdLine.error = !payment_id_ok
return amount_ok && address_ok && payment_id_ok
}
} // pageRoot
@ -433,8 +379,10 @@ Rectangle {
anchors.top: pageRoot.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 17
spacing:10
anchors.leftMargin: 17 * scaleRatio
anchors.topMargin: 17 * scaleRatio
anchors.bottomMargin: 17 * scaleRatio
spacing: 10 * scaleRatio
enabled: !viewOnly || pageRoot.enabled
RowLayout {
@ -455,13 +403,14 @@ Rectangle {
Layout.fillWidth: true
height: 1
color: "#DEDEDE"
Layout.bottomMargin: 30
Layout.bottomMargin: 30 * scaleRatio
}
RowLayout {
visible: persistentSettings.transferShowAdvanced
anchors.left: parent.left
anchors.right: parent.right
Layout.fillWidth: true
Label {
id: privacyLabel
fontSize: 14
@ -479,17 +428,27 @@ Rectangle {
PrivacyLevel {
visible: persistentSettings.transferShowAdvanced
visible: persistentSettings.transferShowAdvanced && !isMobile
id: privacyLevelItem
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: 17 * scaleRatio
onFillLevelChanged: updateMixin()
}
PrivacyLevelSmall {
visible: persistentSettings.transferShowAdvanced && isMobile
id: privacyLevelItemSmall
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: 17 * scaleRatio
onFillLevelChanged: updateMixin()
}
GridLayout {
visible: persistentSettings.transferShowAdvanced
Layout.topMargin: 50
Layout.topMargin: 50 * scaleRatio
columns: (isMobile) ? 2 : 6
@ -657,8 +616,8 @@ Rectangle {
Rectangle {
x: root.width/2 - width/2
y: root.height/2 - height/2
height:statusText.paintedHeight + 50
width:statusText.paintedWidth + 40
height:statusText.paintedHeight + 50 * scaleRatio
width:statusText.paintedWidth + 40 * scaleRatio
visible: statusText.text != ""
opacity: 0.9
@ -719,6 +678,7 @@ Rectangle {
statusText.text = qsTr("Waiting on daemon synchronization to finish")
} else {
// everything OK, enable transfer page
// Light wallet is always ready
pageRoot.enabled = true;
statusText.text = "";
}

View File

@ -72,6 +72,7 @@
<file>images/expandTable.png</file>
<file>images/dropdownDel.png</file>
<file>components/HistoryTable.qml</file>
<file>components/HistoryTableMobile.qml</file>
<file>images/gotoBasicVersion.png</file>
<file>images/goToBasicVersionHovered.png</file>
<file>BasicPanel.qml</file>
@ -143,5 +144,9 @@
<file>components/Notifier.qml</file>
<file>components/MobileHeader.qml</file>
<file>components/TextBlock.qml</file>
<file>wizard/WizardDaemonSettings.qml</file>
<file>components/RemoteNodeEdit.qml</file>
<file>pages/Keys.qml</file>
<file>images/menu.png</file>
</qresource>
</RCC>

View File

@ -61,15 +61,23 @@ void QrCodeScanner::processCode(int type, const QString &data)
emit notifyError(error);
return;
}
QVariantMap parsed_unknown_parameters;
if(unknown_parameters.size() > 0)
{
qDebug() << "unknown parameters " << unknown_parameters;
foreach(const QString &item, unknown_parameters )
{
QStringList parsed_item = item.split("=");
if(parsed_item.size() == 2) {
parsed_unknown_parameters.insert(parsed_item[0], parsed_item[1]);
}
}
emit notifyError(error, true);
}
qDebug() << "Parsed URI : " << address << " " << payment_id << " " << amount << " " << tx_description << " " << recipient_name << " " << error;
QString s_amount = WalletManager::instance()->displayAmount(amount);
qDebug() << "Amount passed " << s_amount ;
emit decoded(address, payment_id, s_amount, tx_description, recipient_name);
emit decoded(address, payment_id, s_amount, tx_description, recipient_name, parsed_unknown_parameters);
}
void QrCodeScanner::processFrame(QVideoFrame frame)
{
@ -102,3 +110,15 @@ void QrCodeScanner::timerEvent(QTimerEvent *event)
}
}
QrCodeScanner::~QrCodeScanner()
{
m_thread->stop();
m_thread->quit();
if(!m_thread->wait(5000))
{
m_thread->terminate();
m_thread->wait();
}
}

View File

@ -44,7 +44,7 @@ class QrCodeScanner : public QObject
public:
QrCodeScanner(QObject *parent = Q_NULLPTR);
~QrCodeScanner();
void setSource(QCamera*);
bool enabled() const;
@ -57,7 +57,7 @@ public Q_SLOTS:
Q_SIGNALS:
void enabledChanged();
void decoded(const QString &address, const QString &payment_id, const QString &amount, const QString &tx_description, const QString &recipient_name);
void decoded(const QString &address, const QString &payment_id, const QString &amount, const QString &tx_description, const QString &recipient_name, const QVariantMap &extra_parameters);
void decode(int type, const QString &data);
void notifyError(const QString &error, bool warning = false);

View File

@ -110,6 +110,7 @@ void QrScanThread::processVideoFrame(const QVideoFrame &frame)
void QrScanThread::stop()
{
m_running = false;
m_waitCondition.wakeOne();
}
void QrScanThread::addFrame(const QVideoFrame &frame)
@ -124,9 +125,10 @@ void QrScanThread::run()
QVideoFrame frame;
while(m_running) {
QMutexLocker locker(&m_mutex);
while(m_queue.isEmpty())
while(m_queue.isEmpty() && m_running)
m_waitCondition.wait(&m_mutex);
processVideoFrame(m_queue.takeFirst());
if(!m_queue.isEmpty())
processVideoFrame(m_queue.takeFirst());
}
}

View File

@ -44,6 +44,7 @@ class QrScanThread : public QThread, public zbar::Image::Handler
public:
QrScanThread(QObject *parent = Q_NULLPTR);
void addFrame(const QVideoFrame &frame);
virtual void stop();
Q_SIGNALS:
void decoded(int type, const QString &data);
@ -51,7 +52,6 @@ Q_SIGNALS:
protected:
virtual void run();
virtual void stop();
void processVideoFrame(const QVideoFrame &);
void processQImage(const QImage &);
void processZImage(zbar::Image &image);

View File

@ -38,6 +38,8 @@ QString TransactionInfo::displayAmount() const
QString TransactionInfo::fee() const
{
if(m_pimpl->fee() == 0)
return "";
return WalletManager::instance()->displayAmount(m_pimpl->fee());
}

View File

@ -646,6 +646,8 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent)
Wallet::~Wallet()
{
qDebug("~Wallet: Closing wallet");
delete m_addressBook;
m_addressBook = NULL;
delete m_history;
m_history = NULL;

View File

@ -275,6 +275,11 @@ bool WalletManager::stopMining()
return m_pimpl->stopMining();
}
bool WalletManager::localDaemonSynced() const
{
return blockchainHeight() > 1 && blockchainHeight() >= blockchainTargetHeight();
}
QString WalletManager::resolveOpenAlias(const QString &address) const
{
bool dnssec_valid = false;

View File

@ -112,6 +112,7 @@ public:
Q_INVOKABLE quint64 blockchainHeight() const;
Q_INVOKABLE quint64 blockchainTargetHeight() const;
Q_INVOKABLE double miningHashRate() const;
Q_INVOKABLE bool localDaemonSynced() const;
Q_INVOKABLE bool isMining() const;
Q_INVOKABLE bool startMining(const QString &address, quint32 threads, bool backgroundMining, bool ignoreBattery);

View File

@ -78,7 +78,7 @@ ColumnLayout {
// page submitted or b) delete it when program closed before reaching final page
// Always delete the wallet object before creating new - we could be stepping back from recovering wallet
if (typeof settingsObject.wallet !== 'undefined') {
if (typeof m_wallet !== 'undefined') {
walletManager.closeWallet()
console.log("deleting wallet")
}
@ -91,8 +91,8 @@ ColumnLayout {
uiItem.wordsTextItem.memoText = wallet.seed
// saving wallet in "global" settings object
// TODO: wallet should have a property pointing to the file where it stored or loaded from
settingsObject.wallet = wallet
settingsObject.tmp_wallet_filename = tmp_wallet_filename
m_wallet = wallet;
settingsObject['tmp_wallet_filename'] = tmp_wallet_filename
}
WizardManageWalletUI {

View File

@ -0,0 +1,198 @@
// Copyright (c) 2014-2017, 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 moneroComponents.WalletManager 1.0
import QtQuick 2.2
import QtQuick.Layouts 1.1
import "../components"
import "utils.js" as Utils
ColumnLayout {
Layout.leftMargin: wizardLeftMargin
Layout.rightMargin: wizardRightMargin
id: passwordPage
opacity: 0
visible: false
property alias titleText: titleText.text
Behavior on opacity {
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
}
onOpacityChanged: visible = opacity !== 0
function onPageOpened(settingsObject) {
}
function onWizardRestarted(){
}
function onPageClosed(settingsObject) {
appWindow.persistentSettings.useRemoteNode = remoteNode.checked
appWindow.persistentSettings.startLocalNode = localNode.checked
appWindow.persistentSettings.remoteNodeAddress = remoteNodeEdit.getAddress();
return true
}
RowLayout {
id: dotsRow
Layout.alignment: Qt.AlignRight
ListModel {
id: dotsModel
ListElement { dotColor: "#36B05B" }
ListElement { dotColor: "#36B05B" }
ListElement { dotColor: "#FFE00A" }
ListElement { dotColor: "#DBDBDB" }
}
Repeater {
model: dotsModel
delegate: Rectangle {
// Password page is last page when creating view only wallet
// TODO: make this dynamic for all pages in wizard
visible: (wizard.currentPath != "create_view_only_wallet" || index < 2)
width: 12; height: 12
radius: 6
color: dotColor
}
}
}
ColumnLayout {
id: headerColumn
Text {
Layout.fillWidth: true
id: titleText
font.family: "Arial"
font.pixelSize: 28 * scaleRatio
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
//renderType: Text.NativeRendering
color: "#3F3F3F"
text: "Daemon settings"
}
Text {
Layout.fillWidth: true
Layout.topMargin: 30 * scaleRatio
Layout.bottomMargin: 30 * scaleRatio
font.family: "Arial"
font.pixelSize: 18 * scaleRatio
wrapMode: Text.Wrap
//renderType: Text.NativeRendering
color: "#4A4646"
textFormat: Text.RichText
// horizontalAlignment: Text.AlignHCenter
text: qsTr("To be able to communicate with the Monero network your wallet needs to be connected to a Monero node. For best privacy it's recommended to run your own node. \
<br><br> \
If you don't have the option to run an own node there's an option to connect to a remote node.")
+ translationManager.emptyString
}
}
ColumnLayout {
RowLayout {
CheckBox {
id: localNode
text: qsTr("Start a node automatically in background (recommended)") + translationManager.emptyString
background: "#FFFFFF"
fontColor: "#4A4646"
fontSize: 16 * scaleRatio
checkedIcon: "../images/checkedVioletIcon.png"
uncheckedIcon: "../images/uncheckedIcon.png"
checked: appWindow.persistentSettings.startLocalNode && !isAndroid && !isIOS
visible: !isAndroid && !isIOS
}
}
ColumnLayout {
visible: localNode.checked
id: blockchainFolderRow
Label {
Layout.fillWidth: true
Layout.topMargin: 20 * scaleRatio
fontSize: 14 * scaleRatio
text: qsTr("Blockchain location") + translationManager.emptyString
}
LineEdit {
id: blockchainFolder
Layout.preferredWidth: 200 * scaleRatio
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 {
CheckBox {
id: remoteNode
text: (localNode.checked) ? qsTr("Connect to a remote node until my own node has finished syncing") + translationManager.emptyString
: qsTr("Connect to a remote node") + translationManager.emptyString
Layout.topMargin: 20 * scaleRatio
background: "#FFFFFF"
fontColor: "#4A4646"
fontSize: 16 * scaleRatio
checkedIcon: "../images/checkedVioletIcon.png"
uncheckedIcon: "../images/uncheckedIcon.png"
checked: appWindow.persistentSettings.useRemoteNode
}
}
RowLayout {
RemoteNodeEdit {
Layout.minimumWidth: 300 * scaleRatio
opacity: remoteNode.checked
id: remoteNodeEdit
daemonAddrText: persistentSettings.remoteNodeAddress.split(":")[0].trim()
daemonPortText: (persistentSettings.remoteNodeAddress.split(":")[1].trim() == "") ? "18081" : persistentSettings.remoteNodeAddress.split(":")[1]
}
}
}
Component.onCompleted: {
parent.wizardRestarted.connect(onWizardRestarted)
}
}

View File

@ -100,7 +100,7 @@ ColumnLayout {
ListElement { dotColor: "#36B05B" }
ListElement { dotColor: "#36B05B" }
ListElement { dotColor: "#36B05B" }
//ListElement { dotColor: "#36B05B" }
ListElement { dotColor: "#FFE00A" }
}
Repeater {
@ -120,7 +120,7 @@ ColumnLayout {
Text {
Layout.fillWidth: true
font.family: "Arial"
font.pixelSize: 28
font.pixelSize: 28 * scaleRatio
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
//renderType: Text.NativeRendering
@ -132,7 +132,7 @@ ColumnLayout {
Layout.fillWidth: true
id: settingsText
font.family: "Arial"
font.pixelSize: 16
font.pixelSize: 16 * scaleRatio
wrapMode: Text.Wrap
textFormat: Text.RichText
horizontalAlignment: Text.AlignHLeft

View File

@ -40,17 +40,19 @@ ColumnLayout {
property alias nextButton : nextButton
property var settings : ({})
property int currentPage: 0
property int wizardLeftMargin: (!isMobile) ? 150 : 25
property int wizardRightMargin: (!isMobile) ? 150 : 25
property int wizardBottomMargin: (isMobile) ? 150 : 25
property int wizardTopMargin: (isMobile) ? 15 : 50
property int wizardLeftMargin: (!isMobile) ? 150 : 25 * scaleRatio
property int wizardRightMargin: (!isMobile) ? 150 : 25 * scaleRatio
property int wizardBottomMargin: (isMobile) ? 150 : 25 * scaleRatio
property int wizardTopMargin: (isMobile) ? 15 * scaleRatio : 50
// Storing wallet in Settings object doesn't work in qt 5.8 on android
property var m_wallet;
property var paths: {
// "create_wallet" : [welcomePage, optionsPage, createWalletPage, passwordPage, donationPage, finishPage ],
// "recovery_wallet" : [welcomePage, optionsPage, recoveryWalletPage, passwordPage, donationPage, finishPage ],
// disable donation page
"create_wallet" : [welcomePage, optionsPage, createWalletPage, passwordPage, finishPage ],
"recovery_wallet" : [welcomePage, optionsPage, recoveryWalletPage, passwordPage, finishPage ],
"create_wallet" : [welcomePage, optionsPage, createWalletPage, passwordPage, daemonSettingsPage, finishPage ],
"recovery_wallet" : [welcomePage, optionsPage, recoveryWalletPage, passwordPage, daemonSettingsPage, finishPage ],
"create_view_only_wallet" : [ createViewOnlyWalletPage, passwordPage ],
}
@ -81,6 +83,10 @@ ColumnLayout {
}
function switchPage(next) {
// Android focus workaround
releaseFocus();
// save settings for current page;
if (next && typeof pages[currentPage].onPageClosed !== 'undefined') {
if (pages[currentPage].onPageClosed(settings) !== true) {
@ -130,6 +136,8 @@ ColumnLayout {
print ("show recovery wallet page");
currentPath = "recovery_wallet"
pages = paths[currentPath]
// Create temporary wallet
createWalletPage.createWallet(settings)
wizard.nextButton.visible = true
// goto next page
switchPage(true);
@ -137,9 +145,8 @@ ColumnLayout {
function openOpenWalletPage() {
console.log("open wallet from file page");
if (typeof wizard.settings['wallet'] !== 'undefined') {
settings.wallet.destroy();
delete wizard.settings['wallet'];
if (typeof m_wallet !== 'undefined' && m_wallet != null) {
walletManager.closeWallet()
}
optionsPage.onPageClosed(settings)
wizard.openWalletFromFileClicked();
@ -203,11 +210,10 @@ ColumnLayout {
var new_wallet_filename = createWalletPath(settings.wallet_path,settings.account_name)
if(isIOS) {
console.log("saving in ios: "+ moneroAccountsDir + new_wallet_filename)
settings.wallet.store(moneroAccountsDir + new_wallet_filename);
m_wallet.store(moneroAccountsDir + new_wallet_filename);
} else {
console.log("saving in wizard: "+ new_wallet_filename)
settings.wallet.store(new_wallet_filename);
m_wallet.store(new_wallet_filename);
}
@ -217,7 +223,7 @@ ColumnLayout {
oshelper.removeTemporaryWallet(settings.tmp_wallet_filename)
// protecting wallet with password
settings.wallet.setPassword(settings.wallet_password);
m_wallet.setPassword(settings.wallet_password);
// Store password in session to be able to use password protected functions (e.g show seed)
appWindow.password = settings.wallet_password
@ -291,6 +297,12 @@ ColumnLayout {
Layout.topMargin: wizardTopMargin
}
WizardDaemonSettings {
id: daemonSettingsPage
Layout.bottomMargin: wizardBottomMargin
Layout.topMargin: wizardTopMargin
}
WizardDonation {
id: donationPage
Layout.bottomMargin: wizardBottomMargin
@ -308,10 +320,10 @@ ColumnLayout {
anchors.verticalCenter: wizard.verticalCenter
anchors.left: parent.left
anchors.leftMargin: isMobile ? 20 : 50
anchors.bottomMargin: isMobile ? 20 : 50
anchors.bottomMargin: isMobile ? 20 * scaleRatio : 50
visible: parent.currentPage > 0
width: 50; height: 50
width: 50 * scaleRatio; height: 50 * scaleRatio
radius: 25
color: prevArea.containsMouse ? "#FF4304" : "#FF6C3C"
@ -333,10 +345,10 @@ ColumnLayout {
id: nextButton
anchors.verticalCenter: wizard.verticalCenter
anchors.right: parent.right
anchors.rightMargin: isMobile ? 20 : 50
anchors.bottomMargin: isMobile ? 20 : 50
anchors.rightMargin: isMobile ? 20 * scaleRatio : 50
anchors.bottomMargin: isMobile ? 20 * scaleRatio : 50
visible: currentPage > 1 && currentPage < pages.length - 1
width: 50; height: 50
width: 50 * scaleRatio; height: 50 * scaleRatio
radius: 25
color: enabled ? nextArea.containsMouse ? "#FF4304" : "#FF6C3C" : "#DBDBDB"
@ -359,7 +371,7 @@ ColumnLayout {
id: sendButton
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: (isMobile) ? 20 : 50
anchors.margins: (isMobile) ? 20 * scaleRatio : 50 * scaleRatio
text: qsTr("USE MONERO") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@ -376,7 +388,7 @@ ColumnLayout {
id: createViewOnlyWalletButton
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: (isMobile) ? 20 : 50
anchors.margins: (isMobile) ? 20 * scaleRatio : 50
text: qsTr("Create wallet") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@ -408,7 +420,7 @@ ColumnLayout {
id: abortViewOnlyButton
anchors.right: createViewOnlyWalletButton.left
anchors.bottom: parent.bottom
anchors.margins: (isMobile) ? 20 : 50
anchors.margins: (isMobile) ? 20 * scaleRatio : 50
text: qsTr("Abort") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"

View File

@ -86,6 +86,31 @@ ColumnLayout {
return wordsArray.length === 25
}
function updateFromQrCode(address, payment_id, amount, tx_description, recipient_name, extra_parameters) {
// Switch to recover from keys
recoverFromSeedMode = false
spendKeyLine.text = ""
viewKeyLine.text = ""
restoreHeightItem.text = ""
if(typeof extra_parameters.secret_view_key != "undefined") {
viewKeyLine.text = extra_parameters.secret_view_key
}
if(typeof extra_parameters.secret_spend_key != "undefined") {
spendKeyLine.text = extra_parameters.secret_spend_key
}
if(typeof extra_parameters.restore_height != "undefined") {
restoreHeightItem.text = extra_parameters.restore_height
}
addressLine.text = address
cameraUi.qrcode_decoded.disconnect(updateFromQrCode)
// Check if keys are correct
checkNextButton();
}
RowLayout {
id: dotsRow
Layout.alignment: Qt.AlignRight
@ -93,8 +118,8 @@ ColumnLayout {
ListModel {
id: dotsModel
ListElement { dotColor: "#36B05B" }
//ListElement { dotColor: "#DBDBDB" }
ListElement { dotColor: "#FFE00A" }
ListElement { dotColor: "#DBDBDB" }
ListElement { dotColor: "#DBDBDB" }
ListElement { dotColor: "#DBDBDB" }
}
@ -118,7 +143,7 @@ ColumnLayout {
horizontalAlignment: Text.AlignHCenter
id: titleText
font.family: "Arial"
font.pixelSize: 28
font.pixelSize: 28 * scaleRatio
wrapMode: Text.Wrap
color: "#3F3F3F"
}
@ -128,8 +153,8 @@ ColumnLayout {
Layout.bottomMargin: rowSpacing
Label {
Layout.topMargin: 20
fontSize: 14
Layout.topMargin: 20 * scaleRatio
fontSize: 14 * scaleRatio
text: qsTr("Wallet name")
+ translationManager.emptyString
}
@ -137,16 +162,17 @@ ColumnLayout {
LineEdit {
id: accountName
Layout.fillWidth: true
Layout.maximumWidth: 600
Layout.minimumWidth: 200
Layout.maximumWidth: 600 * scaleRatio
Layout.minimumWidth: 200 * scaleRatio
text: defaultAccountName
onTextUpdated: checkNextButton()
}
}
RowLayout{
GridLayout{
columns: (isMobile)? 2 : 4
visible: recoverMode
spacing: 0
StandardButton {
id: recoverFromSeedButton
text: qsTr("Restore from seed") + translationManager.emptyString
@ -174,6 +200,22 @@ ColumnLayout {
checkNextButton();
}
}
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: {
cameraUi.state = "Capture"
cameraUi.qrcode_decoded.connect(updateFromQrCode)
}
}
}
// Recover from seed
@ -183,8 +225,8 @@ ColumnLayout {
WizardMemoTextInput {
id : memoTextItem
Layout.fillWidth: true
Layout.maximumWidth: 600
Layout.minimumWidth: 200
Layout.maximumWidth: 600 * scaleRatio
Layout.minimumWidth: 200 * scaleRatio
}
}
@ -198,24 +240,24 @@ ColumnLayout {
LineEdit {
Layout.fillWidth: true
id: addressLine
Layout.maximumWidth: 600
Layout.minimumWidth: 200
Layout.maximumWidth: 600 * scaleRatio
Layout.minimumWidth: 200 * scaleRatio
placeholderText: qsTr("Account address (public)") + translationManager.emptyString
onTextUpdated: checkNextButton()
}
LineEdit {
Layout.fillWidth: true
id: viewKeyLine
Layout.maximumWidth: 600
Layout.minimumWidth: 200
Layout.maximumWidth: 600 * scaleRatio
Layout.minimumWidth: 200 * scaleRatio
placeholderText: qsTr("View key (private)") + translationManager.emptyString
onTextUpdated: checkNextButton()
}
LineEdit {
Layout.fillWidth: true
Layout.maximumWidth: 600
Layout.minimumWidth: 200
Layout.maximumWidth: 600 * scaleRatio
Layout.minimumWidth: 200 * scaleRatio
id: spendKeyLine
placeholderText: qsTr("Spend key (private)") + translationManager.emptyString
onTextUpdated: checkNextButton()
@ -227,8 +269,8 @@ ColumnLayout {
LineEdit {
id: restoreHeightItem
Layout.fillWidth: true
Layout.maximumWidth: 600
Layout.minimumWidth: 200
Layout.maximumWidth: 600 * scaleRatio
Layout.minimumWidth: 200 * scaleRatio
placeholderText: qsTr("Restore height (optional)") + translationManager.emptyString
validator: IntValidator {
bottom:0
@ -240,15 +282,15 @@ ColumnLayout {
ColumnLayout {
Label {
Layout.fillWidth: true
Layout.topMargin: 20
Layout.topMargin: 20 * scaleRatio
fontSize: 14
text: qsTr("Your wallet is stored in") + ": " + fileUrlInput.text;
}
LineEdit {
Layout.fillWidth: true
Layout.maximumWidth: 600
Layout.minimumWidth: 200
Layout.maximumWidth: 600 * scaleRatio
Layout.minimumWidth: 200 * scaleRatio
id: fileUrlInput
text: moneroAccountsDir + "/"

View File

@ -25,21 +25,21 @@ Column {
TextEdit {
id: memoTextInput
property alias placeholderText: memoTextPlaceholder.text
textMargin: 8
textMargin: 8 * scaleRatio
text: ""
font.family: "Arial"
font.pixelSize: 16
font.pixelSize: 16 * scaleRatio
wrapMode: TextInput.Wrap
width: parent.width
selectByMouse: true
property int minimumHeight: 100
property int minimumHeight: 100 * scaleRatio
height: contentHeight > minimumHeight ? contentHeight : minimumHeight
Text {
id: memoTextPlaceholder
anchors.fill:parent
font.pixelSize: 16
anchors.margins: 8
font.pixelSize: 16 * scaleRatio
anchors.margins: 8 * scaleRatio
font.bold:true
text: qsTr("Enter your 25 word mnemonic seed") + translationManager.emptyString
color: "#BABABA"
@ -59,7 +59,11 @@ Column {
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: clipboard.setText(memoTextInput.text)
onClicked: {
clipboard.setText(memoTextInput.text)
appWindow.showStatusMessage(qsTr("Seed copied to clipboard"),3)
}
}
}
Rectangle {
@ -75,14 +79,14 @@ Column {
Text {
id: wordsTipText
anchors.fill: parent
anchors.topMargin : 16
anchors.bottomMargin: 16
anchors.leftMargin: 16
anchors.rightMargin: 16
anchors.topMargin : 16 * scaleRatio
anchors.bottomMargin: 16 * scaleRatio
anchors.leftMargin: 16 * scaleRatio
anchors.rightMargin: 16 * scaleRatio
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.family: "Arial"
font.pixelSize: 15
font.pixelSize: 15 * scaleRatio
color: "#4A4646"
wrapMode: Text.Wrap
text: qsTr("This seed is <b>very</b> important to write down and keep secret. It is all you need to backup and restore your wallet.")

View File

@ -38,8 +38,8 @@ ColumnLayout {
signal openWalletClicked()
opacity: 0
visible: false
property int buttonSize: (isMobile) ? 80 : 190
property int buttonImageSize: (isMobile) ? buttonSize - 10 : buttonSize - 30
property int buttonSize: (isMobile) ? 80 * scaleRatio : 190 * scaleRatio
property int buttonImageSize: (isMobile) ? buttonSize - 10 * scaleRatio : buttonSize - 30 * scaleRatio
function onPageClosed() {
// Save settings used in open from file.
@ -60,13 +60,13 @@ ColumnLayout {
id: headerColumn
Layout.leftMargin: wizardLeftMargin
Layout.rightMargin: wizardRightMargin
Layout.bottomMargin: (!isMobile) ? 40 : 20
spacing: 30
Layout.bottomMargin: (!isMobile) ? 40 * scaleRatio : 20
spacing: 30 * scaleRatio
Text {
Layout.fillWidth: true
font.family: "Arial"
font.pixelSize: 28
font.pixelSize: 28 * scaleRatio
//renderType: Text.NativeRendering
color: "#3F3F3F"
wrapMode: Text.Wrap
@ -77,7 +77,7 @@ ColumnLayout {
Text {
Layout.fillWidth: true
font.family: "Arial"
font.pixelSize: 18
font.pixelSize: 18 * scaleRatio
//renderType: Text.NativeRendering
color: "#4A4646"
wrapMode: Text.Wrap
@ -91,8 +91,8 @@ ColumnLayout {
Layout.rightMargin: wizardRightMargin
Layout.alignment: Qt.AlignCenter
id: actionButtons
columnSpacing: 40
rowSpacing: 10
columnSpacing: 40 * scaleRatio
rowSpacing: 10 * scaleRatio
Layout.fillWidth: true
Layout.fillHeight: true
flow: isMobile ? GridLayout.TopToBottom : GridLayout.LeftToRight
@ -101,8 +101,8 @@ ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
flow: !isMobile ? GridLayout.TopToBottom : GridLayout.LeftToRight
rowSpacing: 20
columnSpacing: 10
rowSpacing: 20 * scaleRatio
columnSpacing: 10 * scaleRatio
Rectangle {
Layout.preferredHeight: page.buttonSize
@ -132,9 +132,9 @@ ColumnLayout {
}
Text {
Layout.preferredWidth: 190
Layout.preferredWidth: page.buttonSize
font.family: "Arial"
font.pixelSize: 16
font.pixelSize: 16 * scaleRatio
color: "#4A4949"
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
@ -146,8 +146,8 @@ ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
flow: !isMobile ? GridLayout.TopToBottom : GridLayout.LeftToRight
rowSpacing: 20
columnSpacing: 10
rowSpacing: 20 * scaleRatio
columnSpacing: 10 * scaleRatio
Rectangle {
Layout.preferredHeight: page.buttonSize
@ -156,7 +156,7 @@ ColumnLayout {
color: recoverWalletArea.containsMouse ? "#DBDBDB" : "#FFFFFF"
Image {
width: page.buttomImageSize
width: page.buttonImageSize
height: page.buttonImageSize
fillMode: Image.PreserveAspectFit
anchors.centerIn: parent
@ -174,9 +174,9 @@ ColumnLayout {
}
Text {
Layout.preferredWidth: 190
Layout.preferredWidth: page.buttonSize
font.family: "Arial"
font.pixelSize: 16
font.pixelSize: 16 * scaleRatio
color: "#4A4949"
horizontalAlignment: Text.AlignHCenter
text: qsTr("Restore wallet from keys or mnemonic seed") + translationManager.emptyString
@ -189,8 +189,8 @@ ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
flow: !isMobile ? GridLayout.TopToBottom : GridLayout.LeftToRight
rowSpacing: 20
columnSpacing: 10
rowSpacing: 20 * scaleRatio
columnSpacing: 10 * scaleRatio
Rectangle {
Layout.preferredHeight: page.buttonSize
@ -217,9 +217,9 @@ ColumnLayout {
}
Text {
Layout.preferredWidth: 190
Layout.preferredWidth: page.buttonSize
font.family: "Arial"
font.pixelSize: 16
font.pixelSize: 16 * scaleRatio
color: "#4A4949"
horizontalAlignment: Text.AlignHCenter
text: qsTr("Open a wallet from file") + translationManager.emptyString
@ -234,18 +234,18 @@ ColumnLayout {
RowLayout {
Layout.leftMargin: wizardLeftMargin
Layout.rightMargin: wizardRightMargin
Layout.topMargin: 30
Layout.topMargin: 30 * scaleRatio
Layout.alignment: Qt.AlignCenter
Layout.fillWidth: true
Rectangle {
width: 100
width: 100 * scaleRatio
CheckBox {
id: testNet
text: qsTr("Testnet") + translationManager.emptyString
background: "#FFFFFF"
fontColor: "#4A4646"
fontSize: 16
fontSize: 16 * scaleRatio
checkedIcon: "../images/checkedVioletIcon.png"
uncheckedIcon: "../images/uncheckedIcon.png"
checked: appWindow.persistentSettings.testnet;

View File

@ -64,7 +64,6 @@ ColumnLayout {
function onPageClosed(settingsObject) {
// TODO: set password on the final page
// settingsObject.wallet.setPassword(passwordItem.password)
settingsObject['wallet_password'] = passwordUI.password
return true
}
@ -82,8 +81,8 @@ ColumnLayout {
ListModel {
id: dotsModel
ListElement { dotColor: "#36B05B" }
ListElement { dotColor: "#36B05B" }
//ListElement { dotColor: "#FFE00A" }
ListElement { dotColor: "#FFE00A" }
ListElement { dotColor: "#DBDBDB" }
ListElement { dotColor: "#DBDBDB" }
}
@ -107,7 +106,7 @@ ColumnLayout {
Layout.fillWidth: true
id: titleText
font.family: "Arial"
font.pixelSize: 28
font.pixelSize: 28 * scaleRatio
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
//renderType: Text.NativeRendering
@ -117,9 +116,9 @@ ColumnLayout {
Text {
Layout.fillWidth: true
Layout.bottomMargin: 30
Layout.bottomMargin: 30 * scaleRatio
font.family: "Arial"
font.pixelSize: 18
font.pixelSize: 18 * scaleRatio
wrapMode: Text.Wrap
//renderType: Text.NativeRendering
color: "#4A4646"

View File

@ -42,7 +42,7 @@ ColumnLayout {
id : password
focus:true
font.family: "Arial"
font.pixelSize: (isMobile) ? 25 : 26
font.pixelSize: (isMobile) ? 25 * scaleRatio : 26 * scaleRatio
echoMode: TextInput.Password
style: TextFieldStyle {
renderType: Text.NativeRendering

View File

@ -42,19 +42,22 @@ ColumnLayout {
wizard.nextButton.enabled = passwordItem.password === retypePasswordItem.password
// scorePassword returns value from 0 to... lots
var strength = walletManager.getPasswordStrength(passwordItem.password);
// consider anything below 10 bits as dire
strength -= 10
if (strength < 0)
strength = 0
// use a slight parabola to discourage short passwords
strength = strength ^ 1.2 / 3
// mapScope does not clamp
if (strength > 100)
strength = 100
// privacyLevel component uses 1..13 scale
privacyLevel.fillLevel = Utils.mapScope(1, 100, 1, 13, strength)
// TODO: password strength meter segfaults on Android.
if (!isAndroid) {
// scorePassword returns value from 0 to... lots
var strength = walletManager.getPasswordStrength(passwordItem.password);
// consider anything below 10 bits as dire
strength -= 10
if (strength < 0)
strength = 0
// use a slight parabola to discourage short passwords
strength = strength ^ 1.2 / 3
// mapScope does not clamp
if (strength > 100)
strength = 100
// privacyLevel component uses 1..13 scale
privacyLevel.fillLevel = Utils.mapScope(1, 100, 1, 13, strength)
}
}
function resetFocus() {
@ -64,8 +67,8 @@ ColumnLayout {
WizardPasswordInput {
id: passwordItem
Layout.fillWidth: true
Layout.maximumWidth: 300
Layout.minimumWidth: 200
Layout.maximumWidth: 300 * scaleRatio
Layout.minimumWidth: 200 * scaleRatio
Layout.alignment: Qt.AlignHCenter
placeholderText : qsTr("Password") + translationManager.emptyString;
KeyNavigation.tab: retypePasswordItem
@ -76,8 +79,8 @@ ColumnLayout {
WizardPasswordInput {
id: retypePasswordItem
Layout.fillWidth: true
Layout.maximumWidth: 300
Layout.minimumWidth: 200
Layout.maximumWidth: 300 * scaleRatio
Layout.minimumWidth: 200 * scaleRatio
Layout.alignment: Qt.AlignHCenter
placeholderText : qsTr("Confirm password") + translationManager.emptyString;
KeyNavigation.tab: passwordItem
@ -85,7 +88,8 @@ ColumnLayout {
}
PrivacyLevelSmall {
Layout.topMargin: isMobile ? 20 : 40
visible: !isAndroid //TODO: strength meter doesnt work on Android
Layout.topMargin: isAndroid ? 20 * scaleRatio : 40 * scaleRatio
Layout.fillWidth: true
id: privacyLevel
background: "#F0EEEE"

View File

@ -81,6 +81,12 @@ ColumnLayout {
var tmp_wallet_filename = oshelper.temporaryFilename()
console.log("Creating temporary wallet", tmp_wallet_filename)
// delete the temporary wallet object before creating new
if (typeof m_wallet !== 'undefined') {
walletManager.closeWallet()
console.log("deleting temporary wallet")
}
// From seed or keys
if(fromSeed)
var wallet = walletManager.recoveryWallet(tmp_wallet_filename, settingsObject.words, testnet, restoreHeight)
@ -92,7 +98,7 @@ ColumnLayout {
var success = wallet.status === Wallet.Status_Ok;
if (success) {
settingsObject['wallet'] = wallet;
m_wallet = wallet;
settingsObject['is_recovering'] = true;
settingsObject['tmp_wallet_filename'] = tmp_wallet_filename
} else {

View File

@ -60,13 +60,13 @@ ColumnLayout {
id: headerColumn
Layout.leftMargin: wizardLeftMargin
Layout.rightMargin: wizardRightMargin
Layout.bottomMargin: 40
spacing: 20
Layout.bottomMargin: 40 * scaleRatio
spacing: 20 * scaleRatio
Text {
Layout.fillWidth: true
font.family: "Arial"
font.pixelSize: 28
font.pixelSize: 28 * scaleRatio
color: "#3F3F3F"
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
@ -76,7 +76,7 @@ ColumnLayout {
Text {
Layout.fillWidth: true
font.family: "Arial"
font.pixelSize: 18
font.pixelSize: 18 * scaleRatio
color: "#4A4646"
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
@ -116,17 +116,16 @@ ColumnLayout {
property int margin: (isMobile) ? 0 : Math.floor(appWindow.width/12);
id: gridView
cellWidth: 140
cellHeight: 120
cellWidth: 140 * scaleRatio
cellHeight: 120 * scaleRatio
model: languagesModel
// Hack to center the flag grid
property int columns: Math.floor(appWindow.width/140)
Layout.leftMargin: margin + (appWindow.width - cellWidth*columns) /2
property int columns: Math.floor(appWindow.width/cellWidth)
Layout.leftMargin: margin + (appWindow.width - cellWidth*columns) /2
Layout.rightMargin: margin
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
delegate: ColumnLayout {
@ -136,9 +135,9 @@ ColumnLayout {
// Layout.alignment: Qt.AlignHCenter
Rectangle {
id: flagRect
width: 60; height: 60
width: 60 * scaleRatio; height: 60 * scaleRatio
// anchors.centerIn: parent
radius: 30
radius: 30 * scaleRatio
Layout.alignment: Qt.AlignHCenter
color: gridView.currentIndex === index ? "#DBDBDB" : "#FFFFFF"
Image {
@ -149,7 +148,7 @@ ColumnLayout {
Text {
font.family: "Arial"
font.pixelSize: 18
font.pixelSize: 18 * scaleRatio
// anchors.horizontalCenter: parent.horizontalCenter
font.bold: gridView.currentIndex === index
// elide: Text.ElideRight