diff --git a/monero-core.pro b/monero-core.pro index 5cfbbf37..f2e24e46 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -2,10 +2,24 @@ TEMPLATE = app QT += qml quick widgets +HEADERS += \ + filter.h \ + clipboardAdapter.h + + SOURCES += main.cpp \ filter.cpp \ clipboardAdapter.cpp +CONFIG(release, debug|release) { + DESTDIR=release +} + +CONFIG(debug, debug|release) { + DESTDIR=debug +} + + RESOURCES += qml.qrc # Additional import path used to resolve QML modules in Qt Creator's code model @@ -14,6 +28,7 @@ QML_IMPORT_PATH = # Default rules for deployment. include(deployment.pri) -HEADERS += \ - filter.h \ - clipboardAdapter.h +# copy language files (xml and images) to the output directory +copydata.commands = $(COPY_DIR) $$shell_path($$PWD/lang) $$shell_path($$DESTDIR/lang) +QMAKE_EXTRA_TARGETS += copydata +POST_TARGETDEPS += copydata diff --git a/qml.qrc b/qml.qrc index 21dd80a9..aeedc37a 100644 --- a/qml.qrc +++ b/qml.qrc @@ -95,5 +95,6 @@ wizard/WizardConfigure.qml wizard/WizardDonation.qml wizard/WizardFinish.qml + wizard/WizardPasswordInput.qml diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml index 4e4c919e..15e5899d 100644 --- a/wizard/WizardCreateWallet.qml +++ b/wizard/WizardCreateWallet.qml @@ -39,6 +39,12 @@ Item { onOpacityChanged: visible = opacity !== 0 + function saveSettings(settingsObject) { + settingsObject['account_name'] = accountName.text + settingsObject['words'] = wordsText.text + settingsObject['wallet_path'] = fileUrlInput.text + } + Row { id: dotsRow anchors.top: parent.top @@ -106,6 +112,7 @@ Item { height: 62 TextInput { + id: accountName anchors.fill: parent horizontalAlignment: TextInput.AlignHCenter verticalAlignment: TextInput.AlignVCenter diff --git a/wizard/WizardDonation.qml b/wizard/WizardDonation.qml index a52a53f7..d42c266e 100644 --- a/wizard/WizardDonation.qml +++ b/wizard/WizardDonation.qml @@ -38,6 +38,12 @@ Item { onOpacityChanged: visible = opacity !== 0 + function saveSettings(settingsObject) { + settingsObject['auto_donations_enabled'] = enableAutoDonationCheckBox.checked; + settingsObject['auto_donations_amount'] = autoDonationAmountText.text; + settingsObject['allow_background_mining'] = allowBackgroundMiningCheckBox.checked; + } + Row { id: dotsRow anchors.top: parent.top @@ -94,6 +100,7 @@ Item { spacing: 2 CheckBox { + id: enableAutoDonationCheckBox anchors.verticalCenter: parent.verticalCenter text: qsTr("Enable auto-donations of?") background: "#F0EEEE" @@ -110,6 +117,7 @@ Item { width: 41 TextInput { + id: autoDonationAmountText anchors.fill: parent verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter @@ -149,5 +157,34 @@ Item { "as a percentage of that fee, to your transaction to support Monero development. For instance, a 50% " + "autodonation take a transaction fee of 0.005 XMR and add a 0.0025 XMR to support Monero development.") } + Column { + anchors.left: parent.left + anchors.right: parent.right + spacing: 12 + + CheckBox { + id: allowBackgroundMiningCheckBox + text: qsTr("Allow background mining?") + anchors.left: parent.left + anchors.right: parent.right + background: "#F0EEEE" + fontColor: "#4A4646" + fontSize: 18 + checkedIcon: "../images/checkedVioletIcon.png" + uncheckedIcon: "../images/uncheckedIcon.png" + checked: true + } + + Text { + anchors.left: parent.left + anchors.right: parent.right + font.family: "Arial" + font.pixelSize: 15 + color: "#4A4646" + wrapMode: Text.Wrap + text: qsTr("Mining secures the Monero network, and also pays a small reward for the work done. This option " + + "will let Monero mine when your computer is on mains power and is idle. It will stop mining when you continue working.") + } + } } } diff --git a/wizard/WizardFinish.qml b/wizard/WizardFinish.qml index 85ebbdf4..7902c0b2 100644 --- a/wizard/WizardFinish.qml +++ b/wizard/WizardFinish.qml @@ -37,6 +37,22 @@ Item { onOpacityChanged: visible = opacity !== 0 + function buildSettingsString() { + var str = "
" + qsTr("Language: ") + wizard.settings['language'] + "
" + + qsTr("Account name: ") + wizard.settings['account_name'] + "
" + + qsTr("Words: ") + wizard.settings['words'] + "
" + + qsTr("Wallet Path: ") + wizard.settings['wallet_path'] + "
" + + qsTr("Enable auto donation: ") + wizard.settings['auto_donations_enabled'] + "
" + + qsTr("Auto donation amount: ") + wizard.settings['auto_donations_amount'] + "
" + + qsTr("Allow background mining: ") + wizard.settings['allow_background_mining'] + "
" + return str; + } + function updateSettingsSummary() { + settingsText.text = qsTr("An overview of your Monero configuration is below:") + + "
" + + buildSettingsString(); + } + Row { id: dotsRow anchors.top: parent.top @@ -84,14 +100,15 @@ Item { } Text { + id: settingsText anchors.left: parent.left anchors.right: parent.right font.family: "Arial" font.pixelSize: 18 wrapMode: Text.Wrap + textFormat: Text.RichText //renderType: Text.NativeRendering color: "#4A4646" - text: qsTr("An overview of your Monero configuration is below:") } } } diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index 4ad396c6..905e0c5f 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -31,11 +31,50 @@ import "../components" Rectangle { id: wizard + property alias nextButton : nextButton + property var settings : ({}) + property int currentPage: 0 + property var pages: [welcomePage, optionsPage, createWalletPage, passwordPage, /*configurePage,*/ donationPage, finishPage ] + signal useMoneroClicked() border.color: "#DBDBDB" border.width: 1 color: "#FFFFFF" + function switchPage(next) { + + // save settings for current page; + if (typeof pages[currentPage].saveSettings !== 'undefined') { + pages[currentPage].saveSettings(settings); + } + + if(next === false) { + if(currentPage > 0) { + pages[currentPage].opacity = 0 + pages[--currentPage].opacity = 1 + } + } else { + if(currentPage < pages.length - 1) { + pages[currentPage].opacity = 0 + pages[++currentPage].opacity = 1 + } + } + + // disallow "next" button until passwords match + if (pages[currentPage] === passwordPage) { + nextButton.visible = passwordPage.passwordValid + } + + // display settings summary + if (pages[currentPage] === finishPage) { + finishPage.updateSettingsSummary(); + nextButton.visible = false + } else { + nextButton.visible = true + } + } + + Rectangle { id: nextButton anchors.verticalCenter: parent.verticalCenter @@ -61,29 +100,8 @@ Rectangle { } } - property int currentPage: 0 - function switchPage(next) { - var pages = new Array() - pages[0] = welcomePage - pages[1] = optionsPage - pages[2] = createWalletPage - pages[3] = passwordPage - pages[4] = configurePage - pages[5] = donationPage - pages[6] = finishPage - if(next === false) { - if(currentPage > 0) { - pages[currentPage].opacity = 0 - pages[--currentPage].opacity = 1 - } - } else { - if(currentPage < pages.length - 1) { - pages[currentPage].opacity = 0 - pages[++currentPage].opacity = 1 - } - } - } + WizardWelcome { id: welcomePage @@ -126,16 +144,6 @@ Rectangle { anchors.rightMargin: 50 } - WizardConfigure { - id: configurePage - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.right: nextButton.left - anchors.left: prevButton.right - anchors.leftMargin: 50 - anchors.rightMargin: 50 - } - WizardDonation { id: donationPage anchors.top: parent.top @@ -192,7 +200,7 @@ Rectangle { shadowPressedColor: "#B32D00" releasedColor: "#FF6C3C" pressedColor: "#FF4304" - visible: parent.currentPage === 6 + visible: parent.pages[currentPage] === finishPage onClicked: wizard.useMoneroClicked() } } diff --git a/wizard/WizardOptions.qml b/wizard/WizardOptions.qml index 83a8a863..debdee88 100644 --- a/wizard/WizardOptions.qml +++ b/wizard/WizardOptions.qml @@ -137,35 +137,5 @@ Item { text: qsTr("I want to recover my account
from my 24 work seed") } } - - Column { - anchors.verticalCenter: parent.verticalCenter - spacing: 30 - - Rectangle { - width: 202; height: 202 - radius: 101 - color: openAccountArea.containsMouse ? "#DBDBDB" : "#FFFFFF" - - Image { - anchors.centerIn: parent - source: "qrc:///images/openAccount.png" - } - - MouseArea { - id: openAccountArea - anchors.fill: parent - hoverEnabled: true - } - } - - Text { - font.family: "Arial" - font.pixelSize: 16 - color: "#4A4949" - horizontalAlignment: Text.AlignHCenter - text: qsTr("I want to open account file") - } - } } } diff --git a/wizard/WizardPassword.qml b/wizard/WizardPassword.qml index 8c54ad65..2926a9e9 100644 --- a/wizard/WizardPassword.qml +++ b/wizard/WizardPassword.qml @@ -38,6 +38,18 @@ Item { onOpacityChanged: visible = opacity !== 0 + function handlePassword() { + // allow to forward step only if passwords match + // print("pass1: ", passwordItem.password) + // print("pass2: ", retypePasswordItem.password) + // TODO: update password strength + wizard.nextButton.visible = passwordItem.password === retypePasswordItem.password + } + + property bool passwordValid : passwordItem.password != '' + && passwordItem.password === retypePasswordItem.password + + Row { id: dotsRow anchors.top: parent.top @@ -97,36 +109,18 @@ Item { } } - Item { + + WizardPasswordInput { id: passwordItem anchors.top: headerColumn.bottom anchors.horizontalCenter: parent.horizontalCenter anchors.topMargin: 24 width: 300 height: 62 - - TextInput { - anchors.fill: parent - horizontalAlignment: TextInput.AlignHCenter - verticalAlignment: TextInput.AlignVCenter - font.family: "Arial" - font.pixelSize: 32 - renderType: Text.NativeRendering - color: "#35B05A" - passwordCharacter: "•" - echoMode: TextInput.Password - focus: true - } - - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: 1 - color: "#DBDBDB" - } + onChanged: handlePassword() } + PrivacyLevelSmall { id: privacyLevel anchors.left: parent.left @@ -137,33 +131,13 @@ Item { interactive: false } - Item { + WizardPasswordInput { id: retypePasswordItem anchors.top: privacyLevel.bottom anchors.horizontalCenter: parent.horizontalCenter anchors.topMargin: 24 width: 300 height: 62 - - TextInput { - anchors.fill: parent - horizontalAlignment: TextInput.AlignHCenter - verticalAlignment: TextInput.AlignVCenter - font.family: "Arial" - font.pixelSize: 32 - renderType: Text.NativeRendering - color: "#35B05A" - passwordCharacter: "•" - echoMode: TextInput.Password - focus: true - } - - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: 1 - color: "#DBDBDB" - } + onChanged: handlePassword() } } diff --git a/wizard/WizardPasswordInput.qml b/wizard/WizardPasswordInput.qml new file mode 100644 index 00000000..d2bbf44a --- /dev/null +++ b/wizard/WizardPasswordInput.qml @@ -0,0 +1,34 @@ +// WizardPasswordInput.qml + +import QtQuick 2.0 + +Item { + property alias password: password.text + signal changed(string password) + + + TextInput { + id : password + anchors.fill: parent + horizontalAlignment: TextInput.AlignHCenter + verticalAlignment: TextInput.AlignVCenter + font.family: "Arial" + font.pixelSize: 32 + renderType: Text.NativeRendering + color: "#35B05A" + passwordCharacter: "•" + echoMode: TextInput.Password + focus: true + Keys.onReleased: { + changed(text) + } + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + height: 1 + color: "#DBDBDB" + } +} diff --git a/wizard/WizardWelcome.qml b/wizard/WizardWelcome.qml index d1bbf6ce..f627e88d 100644 --- a/wizard/WizardWelcome.qml +++ b/wizard/WizardWelcome.qml @@ -36,6 +36,10 @@ Item { onOpacityChanged: visible = opacity !== 0 + function saveSettings(settingsObject) { + settingsObject['language'] = languagesModel.get(gridView.currentIndex).name + } + Column { id: headerColumn anchors.left: parent.left @@ -76,11 +80,15 @@ Item { XmlRole { name: "name"; query: "@name/string()" } XmlRole { name: "flag"; query: "@flag/string()" } + // TODO: XmlListModel is read only, we should store current language somewhere else + // and set current language accordingly XmlRole { name: "isCurrent"; query: "@enabled/string()" } } - ListView { - id: listView + GridView { + id: gridView + cellWidth: 140 + cellHeight: 120 anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom @@ -89,20 +97,20 @@ Item { anchors.leftMargin: 16 anchors.rightMargin: 16 clip: true - model: languagesModel + delegate: Item { - width: listView.width - height: 80 + id: flagDelegate + width: gridView.cellWidth + height: gridView.cellHeight + Rectangle { id: flagRect - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left width: 60; height: 60 + anchors.centerIn: parent radius: 30 - color: listView.currentIndex === index ? "#DBDBDB" : "#FFFFFF" - + color: gridView.currentIndex === index ? "#DBDBDB" : "#FFFFFF" Image { anchors.centerIn: parent source: "file:///" + applicationDirectory + flag @@ -110,30 +118,22 @@ Item { } Text { - anchors.verticalCenter: parent.verticalCenter - anchors.left: flagRect.right - anchors.right: parent.right - anchors.leftMargin: 16 font.family: "Arial" font.pixelSize: 24 - font.bold: listView.currentIndex === index + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: flagRect.bottom + anchors.topMargin: 10 + font.bold: gridView.currentIndex === index elide: Text.ElideRight color: "#3F3F3F" text: name } - - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: 1 - color: "#DBDBDB" - } - MouseArea { id: delegateArea anchors.fill: parent - onClicked: listView.currentIndex = index + onClicked: { + gridView.currentIndex = index + } } } }