Merge pull request #3

3cfa176 Hiding "next" button on the final page (Ilya Kitaev)
63e4d19 Save settings for each wizard page in "wizard.settings" object and diplay overview at the last page (Ilya Kitaev)
78b5565 password page: checking if passwords match. merged "configuration" and "donation" pages into one (Ilya Kitaev)
29f3abd Copy lang files to the output directory at the "build" step (Ilya Kitaev)
965a875 WizardWelcome: ListView replaced with GridView (Ilya Kitaev)
This commit is contained in:
Riccardo Spagni 2016-01-27 15:56:27 +02:00
commit d546bacdfe
No known key found for this signature in database
GPG key ID: 55432DF31CCD4FCD
10 changed files with 198 additions and 135 deletions

View file

@ -2,10 +2,24 @@ TEMPLATE = app
QT += qml quick widgets QT += qml quick widgets
HEADERS += \
filter.h \
clipboardAdapter.h
SOURCES += main.cpp \ SOURCES += main.cpp \
filter.cpp \ filter.cpp \
clipboardAdapter.cpp clipboardAdapter.cpp
CONFIG(release, debug|release) {
DESTDIR=release
}
CONFIG(debug, debug|release) {
DESTDIR=debug
}
RESOURCES += qml.qrc RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model # 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. # Default rules for deployment.
include(deployment.pri) include(deployment.pri)
HEADERS += \ # copy language files (xml and images) to the output directory
filter.h \ copydata.commands = $(COPY_DIR) $$shell_path($$PWD/lang) $$shell_path($$DESTDIR/lang)
clipboardAdapter.h QMAKE_EXTRA_TARGETS += copydata
POST_TARGETDEPS += copydata

View file

@ -95,5 +95,6 @@
<file>wizard/WizardConfigure.qml</file> <file>wizard/WizardConfigure.qml</file>
<file>wizard/WizardDonation.qml</file> <file>wizard/WizardDonation.qml</file>
<file>wizard/WizardFinish.qml</file> <file>wizard/WizardFinish.qml</file>
<file>wizard/WizardPasswordInput.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View file

@ -39,6 +39,12 @@ Item {
onOpacityChanged: visible = opacity !== 0 onOpacityChanged: visible = opacity !== 0
function saveSettings(settingsObject) {
settingsObject['account_name'] = accountName.text
settingsObject['words'] = wordsText.text
settingsObject['wallet_path'] = fileUrlInput.text
}
Row { Row {
id: dotsRow id: dotsRow
anchors.top: parent.top anchors.top: parent.top
@ -106,6 +112,7 @@ Item {
height: 62 height: 62
TextInput { TextInput {
id: accountName
anchors.fill: parent anchors.fill: parent
horizontalAlignment: TextInput.AlignHCenter horizontalAlignment: TextInput.AlignHCenter
verticalAlignment: TextInput.AlignVCenter verticalAlignment: TextInput.AlignVCenter

View file

@ -38,6 +38,12 @@ Item {
onOpacityChanged: visible = opacity !== 0 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 { Row {
id: dotsRow id: dotsRow
anchors.top: parent.top anchors.top: parent.top
@ -94,6 +100,7 @@ Item {
spacing: 2 spacing: 2
CheckBox { CheckBox {
id: enableAutoDonationCheckBox
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
text: qsTr("Enable auto-donations of?") text: qsTr("Enable auto-donations of?")
background: "#F0EEEE" background: "#F0EEEE"
@ -110,6 +117,7 @@ Item {
width: 41 width: 41
TextInput { TextInput {
id: autoDonationAmountText
anchors.fill: parent anchors.fill: parent
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter 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% " + "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.") "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.")
}
}
} }
} }

View file

@ -37,6 +37,22 @@ Item {
onOpacityChanged: visible = opacity !== 0 onOpacityChanged: visible = opacity !== 0
function buildSettingsString() {
var str = "<br>" + qsTr("<b>Language:</b> ") + wizard.settings['language'] + "<br>"
+ qsTr("<b>Account name:</b> ") + wizard.settings['account_name'] + "<br>"
+ qsTr("<b>Words:</b> ") + wizard.settings['words'] + "<br>"
+ qsTr("<b>Wallet Path: </b>") + wizard.settings['wallet_path'] + "<br>"
+ qsTr("<b>Enable auto donation: </b>") + wizard.settings['auto_donations_enabled'] + "<br>"
+ qsTr("<b>Auto donation amount: </b>") + wizard.settings['auto_donations_amount'] + "<br>"
+ qsTr("<b>Allow background mining: </b>") + wizard.settings['allow_background_mining'] + "<br>"
return str;
}
function updateSettingsSummary() {
settingsText.text = qsTr("An overview of your Monero configuration is below:")
+ "<br>"
+ buildSettingsString();
}
Row { Row {
id: dotsRow id: dotsRow
anchors.top: parent.top anchors.top: parent.top
@ -84,14 +100,15 @@ Item {
} }
Text { Text {
id: settingsText
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
font.family: "Arial" font.family: "Arial"
font.pixelSize: 18 font.pixelSize: 18
wrapMode: Text.Wrap wrapMode: Text.Wrap
textFormat: Text.RichText
//renderType: Text.NativeRendering //renderType: Text.NativeRendering
color: "#4A4646" color: "#4A4646"
text: qsTr("An overview of your Monero configuration is below:")
} }
} }
} }

View file

@ -31,11 +31,50 @@ import "../components"
Rectangle { Rectangle {
id: wizard 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() signal useMoneroClicked()
border.color: "#DBDBDB" border.color: "#DBDBDB"
border.width: 1 border.width: 1
color: "#FFFFFF" 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 { Rectangle {
id: nextButton id: nextButton
anchors.verticalCenter: parent.verticalCenter 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 { WizardWelcome {
id: welcomePage id: welcomePage
@ -126,16 +144,6 @@ Rectangle {
anchors.rightMargin: 50 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 { WizardDonation {
id: donationPage id: donationPage
anchors.top: parent.top anchors.top: parent.top
@ -192,7 +200,7 @@ Rectangle {
shadowPressedColor: "#B32D00" shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C" releasedColor: "#FF6C3C"
pressedColor: "#FF4304" pressedColor: "#FF4304"
visible: parent.currentPage === 6 visible: parent.pages[currentPage] === finishPage
onClicked: wizard.useMoneroClicked() onClicked: wizard.useMoneroClicked()
} }
} }

View file

@ -137,35 +137,5 @@ Item {
text: qsTr("I want to recover my account<br/>from my 24 work seed") text: qsTr("I want to recover my account<br/>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")
}
}
} }
} }

View file

@ -38,6 +38,18 @@ Item {
onOpacityChanged: visible = opacity !== 0 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 { Row {
id: dotsRow id: dotsRow
anchors.top: parent.top anchors.top: parent.top
@ -97,35 +109,17 @@ Item {
} }
} }
Item {
WizardPasswordInput {
id: passwordItem id: passwordItem
anchors.top: headerColumn.bottom anchors.top: headerColumn.bottom
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 24 anchors.topMargin: 24
width: 300 width: 300
height: 62 height: 62
onChanged: handlePassword()
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"
}
}
PrivacyLevelSmall { PrivacyLevelSmall {
id: privacyLevel id: privacyLevel
@ -137,33 +131,13 @@ Item {
interactive: false interactive: false
} }
Item { WizardPasswordInput {
id: retypePasswordItem id: retypePasswordItem
anchors.top: privacyLevel.bottom anchors.top: privacyLevel.bottom
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 24 anchors.topMargin: 24
width: 300 width: 300
height: 62 height: 62
onChanged: handlePassword()
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"
}
} }
} }

View file

@ -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"
}
}

View file

@ -36,6 +36,10 @@ Item {
onOpacityChanged: visible = opacity !== 0 onOpacityChanged: visible = opacity !== 0
function saveSettings(settingsObject) {
settingsObject['language'] = languagesModel.get(gridView.currentIndex).name
}
Column { Column {
id: headerColumn id: headerColumn
anchors.left: parent.left anchors.left: parent.left
@ -76,11 +80,15 @@ Item {
XmlRole { name: "name"; query: "@name/string()" } XmlRole { name: "name"; query: "@name/string()" }
XmlRole { name: "flag"; query: "@flag/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()" } XmlRole { name: "isCurrent"; query: "@enabled/string()" }
} }
ListView { GridView {
id: listView id: gridView
cellWidth: 140
cellHeight: 120
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
@ -89,20 +97,20 @@ Item {
anchors.leftMargin: 16 anchors.leftMargin: 16
anchors.rightMargin: 16 anchors.rightMargin: 16
clip: true clip: true
model: languagesModel model: languagesModel
delegate: Item { delegate: Item {
width: listView.width id: flagDelegate
height: 80 width: gridView.cellWidth
height: gridView.cellHeight
Rectangle { Rectangle {
id: flagRect id: flagRect
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
width: 60; height: 60 width: 60; height: 60
anchors.centerIn: parent
radius: 30 radius: 30
color: listView.currentIndex === index ? "#DBDBDB" : "#FFFFFF" color: gridView.currentIndex === index ? "#DBDBDB" : "#FFFFFF"
Image { Image {
anchors.centerIn: parent anchors.centerIn: parent
source: "file:///" + applicationDirectory + flag source: "file:///" + applicationDirectory + flag
@ -110,30 +118,22 @@ Item {
} }
Text { Text {
anchors.verticalCenter: parent.verticalCenter
anchors.left: flagRect.right
anchors.right: parent.right
anchors.leftMargin: 16
font.family: "Arial" font.family: "Arial"
font.pixelSize: 24 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 elide: Text.ElideRight
color: "#3F3F3F" color: "#3F3F3F"
text: name text: name
} }
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: 1
color: "#DBDBDB"
}
MouseArea { MouseArea {
id: delegateArea id: delegateArea
anchors.fill: parent anchors.fill: parent
onClicked: listView.currentIndex = index onClicked: {
gridView.currentIndex = index
}
} }
} }
} }