From 46db7715f9d37be244c0cb8dd8f9e1b48f2bcbd0 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Fri, 29 Jan 2016 22:01:52 +0300 Subject: [PATCH 01/87] German and English translation files --- monero-core.pro | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/monero-core.pro b/monero-core.pro index 75812a7e..2d608aa8 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -11,6 +11,30 @@ SOURCES += main.cpp \ filter.cpp \ clipboardAdapter.cpp +lupdate_only { +SOURCES = *.qml \ + components/*.qml \ + pages/*.qml \ + wizard/*.qml +} + +# translations files; +TRANSLATIONS = monero-core_en.ts \ # English (could be untranslated) + monero-core_de.ts # Deutsch + + +# extra make targets for lupdate and lrelease invocation +lupdate.commands = lupdate $$_PRO_FILE_ +lupdate.depends = $$SOURCES $$HEADERS $$TRANSLATIONS +lrelease.commands = lrelease $$_PRO_FILE_ +lrelease.depends = lupdate +translate.commands = $(COPY) *.qm ${DESTDIR} +translate.depends = lrelease + +QMAKE_EXTRA_TARGETS += lupdate lrelease + + + CONFIG(release, debug|release) { DESTDIR=release } From bbc35ff484fc99e9d6efcb67eb88d1e9c05843bc Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Fri, 29 Jan 2016 22:08:17 +0300 Subject: [PATCH 02/87] Next button is in "disabled" state on password page --- wizard/WizardMain.qml | 9 +++++---- wizard/WizardPassword.qml | 4 +--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index 6cb26356..6a856e9b 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -60,15 +60,16 @@ Rectangle { } } - // disallow "next" button until passwords match + // disable "next" button until passwords match if (pages[currentPage] === passwordPage) { - nextButton.visible = passwordPage.passwordValid; + nextButton.enabled = passwordPage.passwordValid; } else if (pages[currentPage] === finishPage) { // display settings summary finishPage.updateSettingsSummary(); nextButton.visible = false } else { nextButton.visible = true + nextButton.enabled = true } } @@ -79,10 +80,10 @@ Rectangle { anchors.right: parent.right anchors.rightMargin: 50 visible: wizard.currentPage !== 1 && wizard.currentPage !== 6 - width: 50; height: 50 radius: 25 - color: nextArea.containsMouse ? "#FF4304" : "#FF6C3C" + color: enabled ? nextArea.containsMouse ? "#FF4304" : "#FF6C3C" : "#DBDBDB" + Image { anchors.centerIn: parent diff --git a/wizard/WizardPassword.qml b/wizard/WizardPassword.qml index 2926a9e9..d12409ea 100644 --- a/wizard/WizardPassword.qml +++ b/wizard/WizardPassword.qml @@ -40,10 +40,8 @@ Item { 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 + wizard.nextButton.enabled = passwordItem.password === retypePasswordItem.password } property bool passwordValid : passwordItem.password != '' From fce88a8120182e9cf550393fd87b7541b3b558c7 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 3 Feb 2016 00:09:45 +0300 Subject: [PATCH 03/87] Selection (branching) for recovery path --- monero-core.pro | 3 + qml.qrc | 2 + wizard/WizardCreateWallet.qml | 242 +-------------------------- wizard/WizardMain.qml | 75 +++++++-- wizard/WizardManageWalletUI.qml | 284 ++++++++++++++++++++++++++++++++ wizard/WizardOptions.qml | 2 + wizard/WizardPasswordInput.qml | 28 +++- wizard/WizardRecoveryWallet.qml | 55 +++++++ 8 files changed, 442 insertions(+), 249 deletions(-) create mode 100644 wizard/WizardManageWalletUI.qml create mode 100644 wizard/WizardRecoveryWallet.qml diff --git a/monero-core.pro b/monero-core.pro index 2d608aa8..3f92b5dc 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -52,3 +52,6 @@ QML_IMPORT_PATH = # Default rules for deployment. include(deployment.pri) +DISTFILES += \ + wizard/WizardManageWalletUI.qml + diff --git a/qml.qrc b/qml.qrc index e2e774af..24f3b6b2 100644 --- a/qml.qrc +++ b/qml.qrc @@ -107,5 +107,7 @@ <file>lang/flags/russia.png</file> <file>lang/flags/uk.png</file> <file>lang/flags/usa.png</file> + <file>wizard/WizardManageWalletUI.qml</file> + <file>wizard/WizardRecoveryWallet.qml</file> </qresource> </RCC> diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml index 15e5899d..3b7bcf75 100644 --- a/wizard/WizardCreateWallet.qml +++ b/wizard/WizardCreateWallet.qml @@ -33,6 +33,7 @@ import QtQuick.Dialogs 1.2 Item { opacity: 0 visible: false + Behavior on opacity { NumberAnimation { duration: 100; easing.type: Easing.InQuad } } @@ -40,241 +41,14 @@ Item { onOpacityChanged: visible = opacity !== 0 function saveSettings(settingsObject) { - settingsObject['account_name'] = accountName.text - settingsObject['words'] = wordsText.text - settingsObject['wallet_path'] = fileUrlInput.text + settingsObject['account_name'] = uiItem.accountNameText + settingsObject['words'] = uiItem.wordsTexttext + settingsObject['wallet_path'] = uiItem.walletPath } - Row { - id: dotsRow - anchors.top: parent.top - anchors.right: parent.right - anchors.topMargin: 85 - spacing: 6 - - ListModel { - id: dotsModel - ListElement { dotColor: "#FFE00A" } - ListElement { dotColor: "#DBDBDB" } - ListElement { dotColor: "#DBDBDB" } - ListElement { dotColor: "#DBDBDB" } - } - - Repeater { - model: dotsModel - delegate: Rectangle { - width: 12; height: 12 - radius: 6 - color: dotColor - } - } - } - - Column { - id: headerColumn - anchors.left: parent.left - anchors.right: parent.right - anchors.leftMargin: 16 - anchors.rightMargin: 16 - anchors.top: parent.top - anchors.topMargin: 74 - spacing: 24 - - Text { - anchors.left: parent.left - width: headerColumn.width - dotsRow.width - 16 - font.family: "Arial" - font.pixelSize: 28 - wrapMode: Text.Wrap - //renderType: Text.NativeRendering - color: "#3F3F3F" - text: qsTr("A new wallet has been created for you") - } - - Text { - anchors.left: parent.left - anchors.right: parent.right - font.family: "Arial" - font.pixelSize: 18 - wrapMode: Text.Wrap - //renderType: Text.NativeRendering - color: "#4A4646" - text: qsTr("This is the name of your wallet. You can change it to a different name if you’d like:") - } - } - - Item { - id: walletNameItem - anchors.top: headerColumn.bottom - anchors.horizontalCenter: parent.horizontalCenter - anchors.topMargin: 24 - width: 300 - height: 62 - - TextInput { - id: accountName - anchors.fill: parent - horizontalAlignment: TextInput.AlignHCenter - verticalAlignment: TextInput.AlignVCenter - font.family: "Arial" - font.pixelSize: 32 - renderType: Text.NativeRendering - color: "#FF6C3C" - text: qsTr("My account name") - focus: true - } - - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: 1 - color: "#DBDBDB" - } - } - - Text { - id: frameHeader - anchors.left: parent.left - anchors.right: parent.right - anchors.leftMargin: 16 - anchors.rightMargin: 16 - anchors.top: walletNameItem.bottom - anchors.topMargin: 24 - font.family: "Arial" - font.pixelSize: 18 - //renderType: Text.NativeRendering - color: "#4A4646" - elide: Text.ElideRight - text: qsTr("This is the 24 word mnemonic for your wallet") - } - - Rectangle { - id: wordsRect - anchors.left: parent.left - anchors.right: parent.right - anchors.top: frameHeader.bottom - anchors.topMargin: 16 - height: 182 - border.width: 1 - border.color: "#DBDBDB" - - TextEdit { - id: wordsText - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: tipRect.top - anchors.margins: 16 - font.family: "Arial" - font.pixelSize: 24 - wrapMode: Text.Wrap - selectByMouse: true - readOnly: true - color: "#3F3F3F" - text: "bound class paint gasp task soul forgot past pleasure physical circle appear shore bathroom glove women crap busy beauty bliss idea give needle burden" - } - - Image { - anchors.right: parent.right - anchors.bottom: tipRect.top - source: "qrc:///images/greyTriangle.png" - - Image { - anchors.centerIn: parent - source: "qrc:///images/copyToClipboard.png" - } - - Clipboard { id: clipboard } - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: clipboard.setText(wordsText.text) - } - } - - Rectangle { - id: tipRect - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: 65 - color: "#DBDBDB" - - Text { - anchors.fill: parent - anchors.margins: 16 - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - font.family: "Arial" - font.pixelSize: 15 - color: "#4A4646" - wrapMode: Text.Wrap - text: qsTr("It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.") - } - } - } - - Row { - anchors.left: parent.left - anchors.right: parent.right - anchors.top: wordsRect.bottom - anchors.topMargin: 24 - spacing: 16 - - Text { - anchors.verticalCenter: parent.verticalCenter - font.family: "Arial" - font.pixelSize: 18 - //renderType: Text.NativeRendering - color: "#4A4646" - text: qsTr("Your wallet is stored in") - } - - Item { - anchors.verticalCenter: parent.verticalCenter - width: parent.width - x - height: 34 - - FileDialog { - id: fileDialog - selectMultiple: false - title: "Please choose a file" - onAccepted: { - fileUrlInput.text = fileDialog.fileUrl - fileDialog.visible = false - } - onRejected: { - fileDialog.visible = false - } - } - - TextInput { - id: fileUrlInput - anchors.fill: parent - anchors.leftMargin: 5 - anchors.rightMargin: 5 - clip: true - font.family: "Arial" - font.pixelSize: 18 - color: "#6B0072" - verticalAlignment: Text.AlignVCenter - selectByMouse: true - text: "~/.monero/mywallet/" - onFocusChanged: { - if(focus) { - fileDialog.visible = true - } - } - } - - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: 1 - color: "#DBDBDB" - } - } + WizardManageWalletUI { + id: uiItem + titleText: qsTr("A new wallet has been created for you") + wordsTextTitle: qsTr("This is the 24 word mnemonic for your wallet") } } diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index 6a856e9b..a52c219f 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -34,7 +34,9 @@ Rectangle { property alias nextButton : nextButton property var settings : ({}) property int currentPage: 0 - property var pages: [welcomePage, optionsPage, createWalletPage, passwordPage, /*configurePage,*/ donationPage, finishPage ] + property var pages: [welcomePage, optionsPage, createWalletPage, recoveryWalletPage, + passwordPage,/*configurePage,*/ donationPage, finishPage ] + property string path; signal useMoneroClicked() border.color: "#DBDBDB" @@ -42,24 +44,35 @@ Rectangle { color: "#FFFFFF" function switchPage(next) { - // save settings for current page; if (typeof pages[currentPage].saveSettings !== 'undefined') { pages[currentPage].saveSettings(settings); } + print ("switchpage: start: currentPage: ", currentPage); - 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 + if (currentPage > 0 || currentPage < pages.length - 1) { + + pages[currentPage].opacity = 0 + + var step_value = next ? 1 : -1 + // special case - we stepping backward from password page: + // previous page "createWallet" or "recoveryWallet" + if (!next) { + print ("stepping back: current page: ", currentPage); + if ((pages[currentPage] === passwordPage && path === "create_walled") + || (pages[currentPage] === recoveryWalletPage) ) { + step_value *= 2; + } } + + currentPage += step_value + pages[currentPage].opacity = 1; + handlePageChanged(); } + } + + function handlePageChanged() { // disable "next" button until passwords match if (pages[currentPage] === passwordPage) { nextButton.enabled = passwordPage.passwordValid; @@ -68,11 +81,32 @@ Rectangle { finishPage.updateSettingsSummary(); nextButton.visible = false } else { - nextButton.visible = true - nextButton.enabled = true + var enableButton = pages[currentPage] !== optionsPage; + nextButton.visible = nextButton.enabled = enableButton + print ("nextButtonVisible: ", enableButton) } } + function openCreateWalletPage() { + print ("show create wallet page"); + pages[currentPage].opacity = 0; + createWalletPage.opacity = 1 + path = "create_wallet"; + currentPage = pages.indexOf(createWalletPage) + handlePageChanged() + } + + function openRecoveryWalletPage() { + print ("show recovery wallet page"); + pages[currentPage].opacity = 0 + recoveryWalletPage.opacity = 1 + path = "recovery_wallet" + currentPage = pages.indexOf(recoveryWalletPage) + handlePageChanged() + } + + + Rectangle { id: nextButton @@ -120,7 +154,8 @@ Rectangle { anchors.left: prevButton.right anchors.leftMargin: 50 anchors.rightMargin: 50 - onCreateWalletClicked: wizard.switchPage(true) + onCreateWalletClicked: wizard.openCreateWalletPage() + onRecoveryWalletClicked: wizard.openRecoveryWalletPage() } WizardCreateWallet { @@ -133,6 +168,18 @@ Rectangle { anchors.rightMargin: 50 } + WizardRecoveryWallet { + id: recoveryWalletPage + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: nextButton.left + anchors.left: prevButton.right + anchors.leftMargin: 50 + anchors.rightMargin: 50 + } + + + WizardPassword { id: passwordPage anchors.top: parent.top diff --git a/wizard/WizardManageWalletUI.qml b/wizard/WizardManageWalletUI.qml new file mode 100644 index 00000000..242145a6 --- /dev/null +++ b/wizard/WizardManageWalletUI.qml @@ -0,0 +1,284 @@ +// Copyright (c) 2014-2015, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import QtQuick 2.2 +import moneroComponents 1.0 +import QtQuick.Dialogs 1.2 + +// Reusable component for managing wallet (account name, path, private key) + +Item { + + property alias titleText: titleText.text + property alias accountNameText: accountName.text + property alias wordsTextTitle: frameHeader.text + property alias wordsText: wordsText.text + property alias wordsTextTip: tipRect + property alias walletPath: fileUrlInput.text + + + // TODO extend properties if needed + + anchors.fill: parent + Row { + id: dotsRow + anchors.top: parent.top + anchors.right: parent.right + anchors.topMargin: 85 + spacing: 6 + + ListModel { + id: dotsModel + ListElement { dotColor: "#FFE00A" } + ListElement { dotColor: "#DBDBDB" } + ListElement { dotColor: "#DBDBDB" } + ListElement { dotColor: "#DBDBDB" } + } + + Repeater { + model: dotsModel + delegate: Rectangle { + width: 12; height: 12 + radius: 6 + color: dotColor + } + } + } + + Column { + id: headerColumn + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 16 + anchors.rightMargin: 16 + anchors.top: parent.top + anchors.topMargin: 74 + spacing: 24 + + Text { + id: titleText + anchors.left: parent.left + width: headerColumn.width - dotsRow.width - 16 + font.family: "Arial" + font.pixelSize: 28 + wrapMode: Text.Wrap + //renderType: Text.NativeRendering + color: "#3F3F3F" + } + + Text { + anchors.left: parent.left + anchors.right: parent.right + font.family: "Arial" + font.pixelSize: 18 + wrapMode: Text.Wrap + //renderType: Text.NativeRendering + color: "#4A4646" + text: qsTr("This is the name of your wallet. You can change it to a different name if you’d like:") + } + } + + Item { + id: walletNameItem + anchors.top: headerColumn.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 24 + width: 300 + height: 62 + + TextInput { + id: accountName + anchors.fill: parent + horizontalAlignment: TextInput.AlignHCenter + verticalAlignment: TextInput.AlignVCenter + font.family: "Arial" + font.pixelSize: 32 + renderType: Text.NativeRendering + color: "#FF6C3C" + focus: true + text: qsTr("My account name") + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + height: 1 + color: "#DBDBDB" + } + } + + Text { + id: frameHeader + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 16 + anchors.rightMargin: 16 + anchors.top: walletNameItem.bottom + anchors.topMargin: 24 + font.family: "Arial" + font.pixelSize: 24 + font.bold: true + //renderType: Text.NativeRendering + color: "#4A4646" + elide: Text.ElideRight + + } + + Rectangle { + id: wordsRect + anchors.left: parent.left + anchors.right: parent.right + anchors.top: frameHeader.bottom + anchors.topMargin: 16 + height: 182 + border.width: 1 + border.color: "#DBDBDB" + + TextEdit { + id: wordsText + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: tipRect.top + anchors.margins: 16 + font.family: "Arial" + font.pixelSize: 24 + wrapMode: Text.Wrap + selectByMouse: true + readOnly: true + color: "#3F3F3F" + text: "bound class paint gasp task soul forgot past pleasure physical circle appear shore bathroom glove women crap busy beauty bliss idea give needle burden" + } + + Image { + anchors.right: parent.right + anchors.bottom: tipRect.top + source: "qrc:///images/greyTriangle.png" + + Image { + anchors.centerIn: parent + source: "qrc:///images/copyToClipboard.png" + } + + Clipboard { id: clipboard } + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: clipboard.setText(wordsText.text) + } + } + + Rectangle { + id: tipRect + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + height: 65 + color: "#DBDBDB" + property alias text: wordsTipText.text + + Text { + id: wordsTipText + anchors.fill: parent + anchors.margins: 16 + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font.family: "Arial" + font.pixelSize: 15 + color: "#4A4646" + wrapMode: Text.Wrap + text: qsTr("It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.") + } + } + } + + Row { + anchors.left: parent.left + anchors.right: parent.right + anchors.top: wordsRect.bottom + anchors.topMargin: 24 + spacing: 16 + + Text { + anchors.verticalCenter: parent.verticalCenter + font.family: "Arial" + font.pixelSize: 18 + //renderType: Text.NativeRendering + color: "#4A4646" + text: qsTr("Your wallet is stored in") + } + + Item { + anchors.verticalCenter: parent.verticalCenter + width: parent.width - x + height: 34 + + FileDialog { + id: fileDialog + selectMultiple: false + title: "Please choose a file" + onAccepted: { + fileUrlInput.text = fileDialog.fileUrl + fileDialog.visible = false + } + onRejected: { + fileDialog.visible = false + } + } + + TextInput { + id: fileUrlInput + anchors.fill: parent + anchors.leftMargin: 5 + anchors.rightMargin: 5 + clip: true + font.family: "Arial" + font.pixelSize: 18 + color: "#6B0072" + verticalAlignment: Text.AlignVCenter + selectByMouse: true + text: "~/.monero/mywallet/" + onFocusChanged: { + if(focus) { + fileDialog.visible = true + } + } + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + height: 1 + color: "#DBDBDB" + } + } + } +} + diff --git a/wizard/WizardOptions.qml b/wizard/WizardOptions.qml index debdee88..a6718853 100644 --- a/wizard/WizardOptions.qml +++ b/wizard/WizardOptions.qml @@ -31,6 +31,7 @@ import QtQuick 2.2 Item { id: page signal createWalletClicked() + signal recoveryWalletClicked() opacity: 0 visible: false Behavior on opacity { @@ -126,6 +127,7 @@ Item { id: recoverWalletArea anchors.fill: parent hoverEnabled: true + onClicked: page.recoveryWalletClicked() } } diff --git a/wizard/WizardPasswordInput.qml b/wizard/WizardPasswordInput.qml index d2bbf44a..82597421 100644 --- a/wizard/WizardPasswordInput.qml +++ b/wizard/WizardPasswordInput.qml @@ -1,4 +1,30 @@ -// WizardPasswordInput.qml +// Copyright (c) 2014-2015, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 diff --git a/wizard/WizardRecoveryWallet.qml b/wizard/WizardRecoveryWallet.qml new file mode 100644 index 00000000..0eee3491 --- /dev/null +++ b/wizard/WizardRecoveryWallet.qml @@ -0,0 +1,55 @@ +// Copyright (c) 2014-2015, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import QtQuick 2.2 +import moneroComponents 1.0 +import QtQuick.Dialogs 1.2 + +Item { + opacity: 0 + visible: false + + Behavior on opacity { + NumberAnimation { duration: 100; easing.type: Easing.InQuad } + } + + onOpacityChanged: visible = opacity !== 0 + + function saveSettings(settingsObject) { + settingsObject['account_name'] = uiItem.accountNameText + settingsObject['words'] = uiItem.wordsTexttext + settingsObject['wallet_path'] = uiItem.walletPath + } + + WizardManageWalletUI { + id: uiItem + accountNameText: qsTr("My account name") + titleText: qsTr("We're ready to recover your account") + wordsTextTitle: qsTr("This is the 25 word mnemonic for your wallet") + } +} From 6289e18f6cf7cc7c85c799940099b90081273c4c Mon Sep 17 00:00:00 2001 From: unknown <henrud@Henriks-PC.cad-q.net> Date: Wed, 3 Feb 2016 16:37:10 +0100 Subject: [PATCH 04/87] fix for window drag bug on ubuntu, only tested on windows --- .gitignore | 2 + main.cpp | 5 + main.qml | 22 ++-- monero-core.pro | 9 +- monero-core.pro.user | 251 ------------------------------------------- oscursor.cpp | 10 ++ oscursor.h | 25 +++++ 7 files changed, 61 insertions(+), 263 deletions(-) create mode 100644 .gitignore delete mode 100644 monero-core.pro.user create mode 100644 oscursor.cpp create mode 100644 oscursor.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..a2ce1444 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.user +*.user.* diff --git a/main.cpp b/main.cpp index b1bd1a72..ecc8b626 100644 --- a/main.cpp +++ b/main.cpp @@ -31,6 +31,7 @@ #include <QtQml> #include "clipboardAdapter.h" #include "filter.h" +#include "oscursor.h" int main(int argc, char *argv[]) { @@ -41,6 +42,10 @@ int main(int argc, char *argv[]) qmlRegisterType<clipboardAdapter>("moneroComponents", 1, 0, "Clipboard"); QQmlApplicationEngine engine; + + OSCursor cursor; + engine.rootContext()->setContextProperty("globalCursor", &cursor); + engine.rootContext()->setContextProperty("applicationDirectory", QApplication::applicationDirPath()); engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); QObject *rootObject = engine.rootObjects().first(); diff --git a/main.qml b/main.qml index d629a248..c1a1d5ec 100644 --- a/main.qml +++ b/main.qml @@ -355,17 +355,17 @@ ApplicationWindow { "images/resize.png" } - property int previousX: 0 - property int previousY: 0 + property var previousPosition onPressed: { - previousX = mouseX - previousY = mouseY + previousPosition = globalCursor.getPosition() } onPositionChanged: { if(!pressed) return - var dx = previousX - mouseX - var dy = previousY - mouseY + var pos = globalCursor.getPosition() + //var delta = previousPosition - pos + var dx = previousPosition.x - pos.x + var dy = previousPosition.y - pos.y if(appWindow.width - dx > parent.maxWidth) appWindow.width -= dx @@ -374,6 +374,7 @@ ApplicationWindow { if(appWindow.height - dy > parent.maxHeight) appWindow.height -= dy else appWindow.height = parent.maxHeight + previousPosition = pos } } @@ -390,13 +391,16 @@ ApplicationWindow { property var previousPosition anchors.fill: parent propagateComposedEvents: true - onPressed: previousPosition = Qt.point(mouseX, mouseY) + onPressed: previousPosition = globalCursor.getPosition() onPositionChanged: { if (pressedButtons == Qt.LeftButton) { - var dx = mouseX - previousPosition.x - var dy = mouseY - previousPosition.y + var pos = globalCursor.getPosition() + var dx = pos.x - previousPosition.x + var dy = pos.y - previousPosition.y + appWindow.x += dx appWindow.y += dy + previousPosition = pos } } } diff --git a/monero-core.pro b/monero-core.pro index 3f92b5dc..de48d650 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -4,12 +4,14 @@ QT += qml quick widgets HEADERS += \ filter.h \ - clipboardAdapter.h + clipboardAdapter.h \ + oscursor.h SOURCES += main.cpp \ filter.cpp \ - clipboardAdapter.cpp + clipboardAdapter.cpp \ + oscursor.cpp lupdate_only { SOURCES = *.qml \ @@ -53,5 +55,6 @@ QML_IMPORT_PATH = include(deployment.pri) DISTFILES += \ - wizard/WizardManageWalletUI.qml + wizard/WizardManageWalletUI.qml \ + .gitignore diff --git a/monero-core.pro.user b/monero-core.pro.user deleted file mode 100644 index 7c1cd126..00000000 --- a/monero-core.pro.user +++ /dev/null @@ -1,251 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE QtCreatorProject> -<!-- Written by QtCreator 3.1.2, 2014-08-29T10:43:43. --> -<qtcreator> - <data> - <variable>ProjectExplorer.Project.ActiveTarget</variable> - <value type="int">0</value> - </data> - <data> - <variable>ProjectExplorer.Project.EditorSettings</variable> - <valuemap type="QVariantMap"> - <value type="bool" key="EditorConfiguration.AutoIndent">true</value> - <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value> - <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value> - <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0"> - <value type="QString" key="language">Cpp</value> - <valuemap type="QVariantMap" key="value"> - <value type="QByteArray" key="CurrentPreferences">CppGlobal</value> - </valuemap> - </valuemap> - <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1"> - <value type="QString" key="language">QmlJS</value> - <valuemap type="QVariantMap" key="value"> - <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value> - </valuemap> - </valuemap> - <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value> - <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value> - <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value> - <value type="int" key="EditorConfiguration.IndentSize">4</value> - <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value> - <value type="int" key="EditorConfiguration.MarginColumn">80</value> - <value type="bool" key="EditorConfiguration.MouseHiding">true</value> - <value type="bool" key="EditorConfiguration.MouseNavigation">true</value> - <value type="int" key="EditorConfiguration.PaddingMode">1</value> - <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value> - <value type="bool" key="EditorConfiguration.ShowMargin">false</value> - <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value> - <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value> - <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value> - <value type="int" key="EditorConfiguration.TabSize">8</value> - <value type="bool" key="EditorConfiguration.UseGlobal">true</value> - <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value> - <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value> - <value type="bool" key="EditorConfiguration.cleanIndentation">true</value> - <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value> - <value type="bool" key="EditorConfiguration.inEntireDocument">false</value> - </valuemap> - </data> - <data> - <variable>ProjectExplorer.Project.PluginSettings</variable> - <valuemap type="QVariantMap"/> - </data> - <data> - <variable>ProjectExplorer.Project.Target.0</variable> - <valuemap type="QVariantMap"> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.3 MinGW 32bit</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.3 MinGW 32bit</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.53.win32_mingw482_kit</value> - <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value> - <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value> - <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value> - <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0"> - <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">G:/RPA/build-bitmonero-Desktop_Qt_5_3_0_MinGW_32bit-Debug</value> - <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> - <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> - <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> - <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value> - <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value> - <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> - <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> - </valuemap> - <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> - <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> - <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments"/> - <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value> - <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value> - <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> - </valuemap> - <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">budowania</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> - </valuemap> - <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> - <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> - <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> - <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments"/> - <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value> - <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> - <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> - </valuemap> - <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">czyszczenia</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> - </valuemap> - <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> - <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> - <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> - <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value> - <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value> - </valuemap> - <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1"> - <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">G:/RPA/build-bitmonero-Desktop_Qt_5_3_0_MinGW_32bit-Release</value> - <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> - <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> - <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> - <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value> - <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value> - <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> - <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value> - </valuemap> - <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> - <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> - <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments"/> - <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value> - <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value> - <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> - </valuemap> - <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">budowania</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value> - </valuemap> - <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1"> - <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> - <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value> - <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments"/> - <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value> - <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value> - <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value> - </valuemap> - <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">czyszczenia</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value> - </valuemap> - <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value> - <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value> - <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value> - <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value> - <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value> - </valuemap> - <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value> - <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0"> - <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> - <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">instalacji</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value> - </valuemap> - <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Zainstaluj lokalnie</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value> - </valuemap> - <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value> - <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/> - <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0"> - <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/> - <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value> - <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value> - <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value> - <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value> - <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value> - <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value> - <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value> - <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value> - <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value> - <value type="int" key="Analyzer.Valgrind.NumCallers">25</value> - <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/> - <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value> - <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value> - <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value> - <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value> - <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value> - <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds"> - <value type="int">0</value> - <value type="int">1</value> - <value type="int">2</value> - <value type="int">3</value> - <value type="int">4</value> - <value type="int">5</value> - <value type="int">6</value> - <value type="int">7</value> - <value type="int">8</value> - <value type="int">9</value> - <value type="int">10</value> - <value type="int">11</value> - <value type="int">12</value> - <value type="int">13</value> - <value type="int">14</value> - </valuelist> - <value type="int" key="PE.EnvironmentAspect.Base">2</value> - <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">monero-core</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:G:/RPA/bitmonero/monero-core.pro</value> - <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value> - <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">monero-core.pro</value> - <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value> - <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">false</value> - <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value> - <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value> - <value type="bool" key="RunConfiguration.UseCppDebugger">false</value> - <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value> - <value type="bool" key="RunConfiguration.UseMultiProcess">false</value> - <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value> - <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value> - </valuemap> - <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value> - </valuemap> - </data> - <data> - <variable>ProjectExplorer.Project.TargetCount</variable> - <value type="int">1</value> - </data> - <data> - <variable>ProjectExplorer.Project.Updater.EnvironmentId</variable> - <value type="QByteArray">{20382c58-78e1-43a4-9d27-354b0656be87}</value> - </data> - <data> - <variable>ProjectExplorer.Project.Updater.FileVersion</variable> - <value type="int">15</value> - </data> -</qtcreator> diff --git a/oscursor.cpp b/oscursor.cpp new file mode 100644 index 00000000..0d9c1acc --- /dev/null +++ b/oscursor.cpp @@ -0,0 +1,10 @@ +#include "oscursor.h" +#include <QCursor> +OSCursor::OSCursor(QObject *parent) + : QObject(parent) +{ +} +QPoint OSCursor::getPosition() const +{ + return QCursor::pos(); +} diff --git a/oscursor.h b/oscursor.h new file mode 100644 index 00000000..db19227d --- /dev/null +++ b/oscursor.h @@ -0,0 +1,25 @@ +#ifndef OSCURSOR_H +#define OSCURSOR_H + + +#include <QObject> +#include <QString> +#include <QPoint> +class OSCursor : public QObject +{ + Q_OBJECT + //QObject(); +public: + //QObject(QObject* aParent); + //OSCursor(); + explicit OSCursor(QObject *parent = 0); + Q_INVOKABLE QPoint getPosition() const; +}; + +//OSCursor::OSCursor() : QObject(NULL){ + +//} + + +//Q_DECLARE_METATYPE(OSCursor) +#endif // OSCURSOR_H From e3bea0dd4a3cc1b50ac5d1fe40f335d574fa2412 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Sat, 6 Feb 2016 15:49:31 +0300 Subject: [PATCH 05/87] "word mnemonic input" with clipboard button and hint is reusable component; --- monero-core.pro | 5 ++- qml.qrc | 1 + wizard/WizardCreateWallet.qml | 6 ++- wizard/WizardManageWalletUI.qml | 77 ++++--------------------------- wizard/WizardMemoTextInput.qml | 80 +++++++++++++++++++++++++++++++++ wizard/WizardRecoveryWallet.qml | 6 ++- 6 files changed, 102 insertions(+), 73 deletions(-) create mode 100644 wizard/WizardMemoTextInput.qml diff --git a/monero-core.pro b/monero-core.pro index de48d650..2f7164b1 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -27,7 +27,7 @@ TRANSLATIONS = monero-core_en.ts \ # English (could be untranslated) # extra make targets for lupdate and lrelease invocation lupdate.commands = lupdate $$_PRO_FILE_ -lupdate.depends = $$SOURCES $$HEADERS $$TRANSLATIONS +lupdate.depends = $$SOURCES $$HEADERS lrelease.commands = lrelease $$_PRO_FILE_ lrelease.depends = lupdate translate.commands = $(COPY) *.qm ${DESTDIR} @@ -56,5 +56,6 @@ include(deployment.pri) DISTFILES += \ wizard/WizardManageWalletUI.qml \ - .gitignore + .gitignore \ + wizard/WizardMemoTextInput.qml diff --git a/qml.qrc b/qml.qrc index 24f3b6b2..dbd862f1 100644 --- a/qml.qrc +++ b/qml.qrc @@ -109,5 +109,6 @@ <file>lang/flags/usa.png</file> <file>wizard/WizardManageWalletUI.qml</file> <file>wizard/WizardRecoveryWallet.qml</file> + <file>wizard/WizardMemoTextInput.qml</file> </qresource> </RCC> diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml index 3b7bcf75..65e2e989 100644 --- a/wizard/WizardCreateWallet.qml +++ b/wizard/WizardCreateWallet.qml @@ -49,6 +49,10 @@ Item { WizardManageWalletUI { id: uiItem titleText: qsTr("A new wallet has been created for you") - wordsTextTitle: qsTr("This is the 24 word mnemonic for your wallet") + wordsTextTitle: qsTr("This is the 25 word mnemonic for your wallet") + wordsTextItem.clipboardButtonVisible: true + wordsTextItem.tipTextVisible: true + wordsTextItem.memoTextReadOnly: true + } } diff --git a/wizard/WizardManageWalletUI.qml b/wizard/WizardManageWalletUI.qml index 242145a6..a00814a9 100644 --- a/wizard/WizardManageWalletUI.qml +++ b/wizard/WizardManageWalletUI.qml @@ -37,9 +37,8 @@ Item { property alias titleText: titleText.text property alias accountNameText: accountName.text property alias wordsTextTitle: frameHeader.text - property alias wordsText: wordsText.text - property alias wordsTextTip: tipRect property alias walletPath: fileUrlInput.text + property alias wordsTextItem : memoTextItem // TODO extend properties if needed @@ -147,81 +146,21 @@ Item { //renderType: Text.NativeRendering color: "#4A4646" elide: Text.ElideRight - + horizontalAlignment: Text.AlignHCenter } - Rectangle { - id: wordsRect - anchors.left: parent.left - anchors.right: parent.right - anchors.top: frameHeader.bottom + + WizardMemoTextInput { + id : memoTextItem + width: parent.width + anchors.top : frameHeader.bottom anchors.topMargin: 16 - height: 182 - border.width: 1 - border.color: "#DBDBDB" - - TextEdit { - id: wordsText - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: tipRect.top - anchors.margins: 16 - font.family: "Arial" - font.pixelSize: 24 - wrapMode: Text.Wrap - selectByMouse: true - readOnly: true - color: "#3F3F3F" - text: "bound class paint gasp task soul forgot past pleasure physical circle appear shore bathroom glove women crap busy beauty bliss idea give needle burden" - } - - Image { - anchors.right: parent.right - anchors.bottom: tipRect.top - source: "qrc:///images/greyTriangle.png" - - Image { - anchors.centerIn: parent - source: "qrc:///images/copyToClipboard.png" - } - - Clipboard { id: clipboard } - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: clipboard.setText(wordsText.text) - } - } - - Rectangle { - id: tipRect - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: 65 - color: "#DBDBDB" - property alias text: wordsTipText.text - - Text { - id: wordsTipText - anchors.fill: parent - anchors.margins: 16 - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - font.family: "Arial" - font.pixelSize: 15 - color: "#4A4646" - wrapMode: Text.Wrap - text: qsTr("It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.") - } - } } Row { anchors.left: parent.left anchors.right: parent.right - anchors.top: wordsRect.bottom + anchors.top: memoTextItem.bottom anchors.topMargin: 24 spacing: 16 diff --git a/wizard/WizardMemoTextInput.qml b/wizard/WizardMemoTextInput.qml new file mode 100644 index 00000000..89eadb15 --- /dev/null +++ b/wizard/WizardMemoTextInput.qml @@ -0,0 +1,80 @@ +import QtQuick 2.0 +import moneroComponents 1.0 + +Column { + + property alias memoText : memoTextInput.text + property alias tipText: wordsTipText.text + property alias tipTextVisible: tipRect.visible + property alias memoTextReadOnly : memoTextInput.readOnly + property alias clipboardButtonVisible: clipboardButton.visible + + + Rectangle { + id: memoTextRect + width: parent.width + height: { + memoTextInput.height + // to have less gap between button and text input we reduce overall height by button height + //+ (clipboardButton.visible ? clipboardButton.height : 0) + + (tipRect.visible ? tipRect.height : 0) + } + border.width: 1 + border.color: "#DBDBDB" + + TextEdit { + id: memoTextInput + textMargin: 8 + text: "bound class paint gasp task soul forgot past pleasure physical circle appear shore bathroom glove women crap busy beauty bliss idea give needle burden" + font.family: "Arial" + font.pointSize: 16 + wrapMode: TextInput.Wrap + width: parent.width + selectByMouse: true + property int minimumHeight: 100 + height: contentHeight > minimumHeight ? contentHeight : minimumHeight + } + Image { + id : clipboardButton + anchors.right: parent.right + anchors.bottom: tipRect.top + source: "qrc:///images/greyTriangle.png" + Image { + anchors.centerIn: parent + source: "qrc:///images/copyToClipboard.png" + } + Clipboard { id: clipboard } + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: clipboard.setText(memoTextInput.text) + } + } + Rectangle { + id: tipRect + visible: true + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: memoTextRect.bottom + height: wordsTipText.contentHeight + wordsTipText.anchors.topMargin + color: "#DBDBDB" + property alias text: wordsTipText.text + + Text { + id: wordsTipText + anchors.fill: parent + anchors.topMargin : 16 + anchors.bottomMargin: 16 + anchors.leftMargin: 16 + anchors.rightMargin: 16 + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font.family: "Arial" + font.pixelSize: 15 + color: "#4A4646" + wrapMode: Text.Wrap + text: qsTr("It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.") + } + } + } +} diff --git a/wizard/WizardRecoveryWallet.qml b/wizard/WizardRecoveryWallet.qml index 0eee3491..46af302b 100644 --- a/wizard/WizardRecoveryWallet.qml +++ b/wizard/WizardRecoveryWallet.qml @@ -50,6 +50,10 @@ Item { id: uiItem accountNameText: qsTr("My account name") titleText: qsTr("We're ready to recover your account") - wordsTextTitle: qsTr("This is the 25 word mnemonic for your wallet") + wordsTextTitle: qsTr("Please enter your 25 word private key") + wordsTextItem.clipboardButtonVisible: false + wordsTextItem.tipTextVisible: false + wordsTextItem.memoTextReadOnly: false + wordsTextItem.memoText: "" } } From 496a34c54a46550922a252e56306e23f1c8e0148 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Sat, 6 Feb 2016 15:58:55 +0300 Subject: [PATCH 06/87] Language (qt linguist) files actually added to project. --- monero-core.pro | 14 +- monero-core_de.ts | 688 ++++++++++++++++++++++++++++++++++++++++++++++ monero-core_en.ts | 688 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1387 insertions(+), 3 deletions(-) create mode 100644 monero-core_de.ts create mode 100644 monero-core_en.ts diff --git a/monero-core.pro b/monero-core.pro index 2f7164b1..fece659e 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -26,6 +26,7 @@ TRANSLATIONS = monero-core_en.ts \ # English (could be untranslated) # extra make targets for lupdate and lrelease invocation +# use "make lupdate" to update *.ts files and "make lrelease" to generate *.qm files lupdate.commands = lupdate $$_PRO_FILE_ lupdate.depends = $$SOURCES $$HEADERS lrelease.commands = lrelease $$_PRO_FILE_ @@ -55,7 +56,14 @@ QML_IMPORT_PATH = include(deployment.pri) DISTFILES += \ - wizard/WizardManageWalletUI.qml \ - .gitignore \ - wizard/WizardMemoTextInput.qml + + +OTHER_FILES += \ + .gitignore \ + monero-core_de.ts \ + monero-core_en.ts + + + + diff --git a/monero-core_de.ts b/monero-core_de.ts new file mode 100644 index 00000000..0a99e2fb --- /dev/null +++ b/monero-core_de.ts @@ -0,0 +1,688 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="de_DE"> +<context> + <name>AddressBook</name> + <message> + <location filename="pages/AddressBook.qml" line="47"/> + <source>Add new entry</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="56"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="58"/> + <source><b>Tip tekst test</b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="77"/> + <source>Payment ID <font size='2'>(Optional)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="79"/> + <source><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 thevtransfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="98"/> + <source>Description <font size='2'>(Local database)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="100"/> + <source><b>Tip tekst test</b><br/><br/>test line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="125"/> + <source>ADD</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>AddressBookTable</name> + <message> + <location filename="components/AddressBookTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/AddressBookTable.qml" line="106"/> + <source>Payment ID:</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>BasicPanel</name> + <message> + <location filename="BasicPanel.qml" line="75"/> + <source>Locked Balance:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="89"/> + <source>78.9239845</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="113"/> + <source>Availible Balance:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="127"/> + <source>2324.9239845</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="152"/> + <source>amount...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="160"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="176"/> + <source>destination...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="188"/> + <source>Privacy level</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="209"/> + <source>payment ID (optional)...</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Dashboard</name> + <message> + <location filename="pages/Dashboard.qml" line="57"/> + <source>Quick transfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Dashboard.qml" line="89"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Dashboard.qml" line="102"/> + <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> lookng for security level and address book? go to <a href='#'>Transfer</a> tab</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>DashboardTable</name> + <message> + <location filename="components/DashboardTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/DashboardTable.qml" line="137"/> + <source>Date</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/DashboardTable.qml" line="172"/> + <source>Balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/DashboardTable.qml" line="193"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>History</name> + <message> + <location filename="pages/History.qml" line="47"/> + <source>Filter trasactions history</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="56"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="58"/> + <location filename="pages/History.qml" line="122"/> + <location filename="pages/History.qml" line="142"/> + <location filename="pages/History.qml" line="190"/> + <location filename="pages/History.qml" line="224"/> + <location filename="pages/History.qml" line="245"/> + <source><b>Tip tekst test</b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="77"/> + <source>Payment ID <font size='2'>(Optional)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="79"/> + <source><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 thevtransfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="98"/> + <source>Description <font size='2'>(Local database)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="100"/> + <source><b>Tip tekst test</b><br/><br/>test line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="120"/> + <source>Date from</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="140"/> + <location filename="pages/History.qml" line="243"/> + <source>To</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="160"/> + <source>FILTER</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="169"/> + <source>Advance filtering</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="188"/> + <source>Type of transation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="222"/> + <source>Amount from</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>HistoryTable</name> + <message> + <location filename="components/HistoryTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="129"/> + <source>Payment ID:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="167"/> + <source>Date</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="202"/> + <source>Balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="223"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>LeftPanel</name> + <message> + <location filename="LeftPanel.qml" line="93"/> + <source>Locked balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="96"/> + <source>Test tip 1<br/><br/>line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="127"/> + <source>Unlocked</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="130"/> + <source>Test tip 2<br/><br/>line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="179"/> + <source>Dashboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="180"/> + <source>D</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="202"/> + <source>Transfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="203"/> + <source>T</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="224"/> + <source>History</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="225"/> + <source>H</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="246"/> + <source>Address book</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="247"/> + <source>B</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="268"/> + <source>Mining</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="269"/> + <source>M</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="290"/> + <source>Settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="291"/> + <source>S</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>NetworkStatusItem</name> + <message> + <location filename="components/NetworkStatusItem.qml" line="58"/> + <source>Network status</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/NetworkStatusItem.qml" line="66"/> + <source>Connected</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/NetworkStatusItem.qml" line="66"/> + <source>Disconnected</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>PrivacyLevelSmall</name> + <message> + <location filename="components/PrivacyLevelSmall.qml" line="95"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/PrivacyLevelSmall.qml" line="106"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/PrivacyLevelSmall.qml" line="117"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>RightPanel</name> + <message> + <location filename="RightPanel.qml" line="49"/> + <source>Twitter</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>SearchInput</name> + <message> + <location filename="components/SearchInput.qml" line="69"/> + <source>Search by...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/SearchInput.qml" line="230"/> + <source>SEARCH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>TickDelegate</name> + <message> + <location filename="components/TickDelegate.qml" line="55"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/TickDelegate.qml" line="56"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/TickDelegate.qml" line="57"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Transfer</name> + <message> + <location filename="pages/Transfer.qml" line="42"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="52"/> + <source>Transaction prority</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="72"/> + <source>Amount...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="108"/> + <source>Privacy Level</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="131"/> + <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> Address <font size='2'> ( Type in or select from </font> <a href='#'>Address</a><font size='2'> book )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="156"/> + <source>Payment ID <font size='2'>( Optional )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="178"/> + <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="198"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardConfigure</name> + <message> + <location filename="wizard/WizardConfigure.qml" line="79"/> + <source>We’re almost there - let’s just configure some Monero preferences</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="97"/> + <source>Kickstart the Monero blockchain?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="115"/> + <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="126"/> + <source>Enable disk conservation mode?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="144"/> + <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="156"/> + <source>Allow background mining?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="174"/> + <source>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.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardCreateWallet</name> + <message> + <location filename="wizard/WizardCreateWallet.qml" line="51"/> + <source>A new wallet has been created for you</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardCreateWallet.qml" line="52"/> + <source>This is the 25 word mnemonic for your wallet</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardDonation</name> + <message> + <location filename="wizard/WizardDonation.qml" line="85"/> + <source>Monero development is solely supported by donations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="105"/> + <source>Enable auto-donations of?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="145"/> + <source>% of my fee added to each transaction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="156"/> + <source>For every transaction, a small transaction fee is charged. This option lets you add an additional amount, 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.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="167"/> + <source>Allow background mining?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="185"/> + <source>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.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardFinish</name> + <message> + <location filename="wizard/WizardFinish.qml" line="41"/> + <source><b>Language:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="42"/> + <source><b>Account name:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="43"/> + <source><b>Words:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="44"/> + <source><b>Wallet Path: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="45"/> + <source><b>Enable auto donation: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="46"/> + <source><b>Auto donation amount: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="47"/> + <source><b>Allow background mining: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="51"/> + <source>An overview of your Monero configuration is below:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="99"/> + <source>You’re all setup!</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardMain</name> + <message> + <location filename="wizard/WizardMain.qml" line="244"/> + <source>USE MONERO</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardManageWalletUI</name> + <message> + <location filename="wizard/WizardManageWalletUI.qml" line="101"/> + <source>This is the name of your wallet. You can change it to a different name if you’d like:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardManageWalletUI.qml" line="123"/> + <source>My account name</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardManageWalletUI.qml" line="173"/> + <source>Your wallet is stored in</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardMemoTextInput</name> + <message> + <location filename="wizard/WizardMemoTextInput.qml" line="76"/> + <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardOptions</name> + <message> + <location filename="wizard/WizardOptions.qml" line="61"/> + <source>I want</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardOptions.qml" line="72"/> + <source>Please select one of the following options:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardOptions.qml" line="108"/> + <source>This is my first time, I want to<br/>create a new account</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardOptions.qml" line="139"/> + <source>I want to recover my account<br/>from my 24 work seed</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardPassword</name> + <message> + <location filename="wizard/WizardPassword.qml" line="94"/> + <source>Now that your wallet has been created, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardPassword.qml" line="105"/> + <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> + Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> + <oldsource>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> + Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</oldsource> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardRecoveryWallet</name> + <message> + <location filename="wizard/WizardRecoveryWallet.qml" line="51"/> + <source>My account name</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardRecoveryWallet.qml" line="52"/> + <source>We're ready to recover your account</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardRecoveryWallet.qml" line="53"/> + <source>Please enter your 25 word private key</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardWelcome</name> + <message> + <location filename="wizard/WizardWelcome.qml" line="61"/> + <source>Welcome</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardWelcome.qml" line="72"/> + <source>Please choose a language and regional format.</source> + <translation type="unfinished"></translation> + </message> +</context> +</TS> diff --git a/monero-core_en.ts b/monero-core_en.ts new file mode 100644 index 00000000..e59eb72d --- /dev/null +++ b/monero-core_en.ts @@ -0,0 +1,688 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="en_US"> +<context> + <name>AddressBook</name> + <message> + <location filename="pages/AddressBook.qml" line="47"/> + <source>Add new entry</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="56"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="58"/> + <source><b>Tip tekst test</b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="77"/> + <source>Payment ID <font size='2'>(Optional)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="79"/> + <source><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 thevtransfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="98"/> + <source>Description <font size='2'>(Local database)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="100"/> + <source><b>Tip tekst test</b><br/><br/>test line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="125"/> + <source>ADD</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>AddressBookTable</name> + <message> + <location filename="components/AddressBookTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/AddressBookTable.qml" line="106"/> + <source>Payment ID:</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>BasicPanel</name> + <message> + <location filename="BasicPanel.qml" line="75"/> + <source>Locked Balance:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="89"/> + <source>78.9239845</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="113"/> + <source>Availible Balance:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="127"/> + <source>2324.9239845</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="152"/> + <source>amount...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="160"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="176"/> + <source>destination...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="188"/> + <source>Privacy level</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="209"/> + <source>payment ID (optional)...</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Dashboard</name> + <message> + <location filename="pages/Dashboard.qml" line="57"/> + <source>Quick transfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Dashboard.qml" line="89"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Dashboard.qml" line="102"/> + <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> lookng for security level and address book? go to <a href='#'>Transfer</a> tab</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>DashboardTable</name> + <message> + <location filename="components/DashboardTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/DashboardTable.qml" line="137"/> + <source>Date</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/DashboardTable.qml" line="172"/> + <source>Balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/DashboardTable.qml" line="193"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>History</name> + <message> + <location filename="pages/History.qml" line="47"/> + <source>Filter trasactions history</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="56"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="58"/> + <location filename="pages/History.qml" line="122"/> + <location filename="pages/History.qml" line="142"/> + <location filename="pages/History.qml" line="190"/> + <location filename="pages/History.qml" line="224"/> + <location filename="pages/History.qml" line="245"/> + <source><b>Tip tekst test</b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="77"/> + <source>Payment ID <font size='2'>(Optional)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="79"/> + <source><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 thevtransfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="98"/> + <source>Description <font size='2'>(Local database)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="100"/> + <source><b>Tip tekst test</b><br/><br/>test line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="120"/> + <source>Date from</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="140"/> + <location filename="pages/History.qml" line="243"/> + <source>To</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="160"/> + <source>FILTER</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="169"/> + <source>Advance filtering</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="188"/> + <source>Type of transation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="222"/> + <source>Amount from</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>HistoryTable</name> + <message> + <location filename="components/HistoryTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="129"/> + <source>Payment ID:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="167"/> + <source>Date</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="202"/> + <source>Balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="223"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>LeftPanel</name> + <message> + <location filename="LeftPanel.qml" line="93"/> + <source>Locked balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="96"/> + <source>Test tip 1<br/><br/>line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="127"/> + <source>Unlocked</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="130"/> + <source>Test tip 2<br/><br/>line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="179"/> + <source>Dashboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="180"/> + <source>D</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="202"/> + <source>Transfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="203"/> + <source>T</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="224"/> + <source>History</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="225"/> + <source>H</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="246"/> + <source>Address book</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="247"/> + <source>B</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="268"/> + <source>Mining</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="269"/> + <source>M</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="290"/> + <source>Settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="291"/> + <source>S</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>NetworkStatusItem</name> + <message> + <location filename="components/NetworkStatusItem.qml" line="58"/> + <source>Network status</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/NetworkStatusItem.qml" line="66"/> + <source>Connected</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/NetworkStatusItem.qml" line="66"/> + <source>Disconnected</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>PrivacyLevelSmall</name> + <message> + <location filename="components/PrivacyLevelSmall.qml" line="95"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/PrivacyLevelSmall.qml" line="106"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/PrivacyLevelSmall.qml" line="117"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>RightPanel</name> + <message> + <location filename="RightPanel.qml" line="49"/> + <source>Twitter</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>SearchInput</name> + <message> + <location filename="components/SearchInput.qml" line="69"/> + <source>Search by...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/SearchInput.qml" line="230"/> + <source>SEARCH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>TickDelegate</name> + <message> + <location filename="components/TickDelegate.qml" line="55"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/TickDelegate.qml" line="56"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/TickDelegate.qml" line="57"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Transfer</name> + <message> + <location filename="pages/Transfer.qml" line="42"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="52"/> + <source>Transaction prority</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="72"/> + <source>Amount...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="108"/> + <source>Privacy Level</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="131"/> + <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> Address <font size='2'> ( Type in or select from </font> <a href='#'>Address</a><font size='2'> book )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="156"/> + <source>Payment ID <font size='2'>( Optional )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="178"/> + <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="198"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardConfigure</name> + <message> + <location filename="wizard/WizardConfigure.qml" line="79"/> + <source>We’re almost there - let’s just configure some Monero preferences</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="97"/> + <source>Kickstart the Monero blockchain?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="115"/> + <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="126"/> + <source>Enable disk conservation mode?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="144"/> + <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="156"/> + <source>Allow background mining?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="174"/> + <source>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.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardCreateWallet</name> + <message> + <location filename="wizard/WizardCreateWallet.qml" line="51"/> + <source>A new wallet has been created for you</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardCreateWallet.qml" line="52"/> + <source>This is the 25 word mnemonic for your wallet</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardDonation</name> + <message> + <location filename="wizard/WizardDonation.qml" line="85"/> + <source>Monero development is solely supported by donations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="105"/> + <source>Enable auto-donations of?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="145"/> + <source>% of my fee added to each transaction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="156"/> + <source>For every transaction, a small transaction fee is charged. This option lets you add an additional amount, 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.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="167"/> + <source>Allow background mining?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="185"/> + <source>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.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardFinish</name> + <message> + <location filename="wizard/WizardFinish.qml" line="41"/> + <source><b>Language:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="42"/> + <source><b>Account name:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="43"/> + <source><b>Words:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="44"/> + <source><b>Wallet Path: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="45"/> + <source><b>Enable auto donation: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="46"/> + <source><b>Auto donation amount: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="47"/> + <source><b>Allow background mining: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="51"/> + <source>An overview of your Monero configuration is below:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="99"/> + <source>You’re all setup!</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardMain</name> + <message> + <location filename="wizard/WizardMain.qml" line="244"/> + <source>USE MONERO</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardManageWalletUI</name> + <message> + <location filename="wizard/WizardManageWalletUI.qml" line="101"/> + <source>This is the name of your wallet. You can change it to a different name if you’d like:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardManageWalletUI.qml" line="123"/> + <source>My account name</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardManageWalletUI.qml" line="173"/> + <source>Your wallet is stored in</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardMemoTextInput</name> + <message> + <location filename="wizard/WizardMemoTextInput.qml" line="76"/> + <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardOptions</name> + <message> + <location filename="wizard/WizardOptions.qml" line="61"/> + <source>I want</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardOptions.qml" line="72"/> + <source>Please select one of the following options:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardOptions.qml" line="108"/> + <source>This is my first time, I want to<br/>create a new account</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardOptions.qml" line="139"/> + <source>I want to recover my account<br/>from my 24 work seed</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardPassword</name> + <message> + <location filename="wizard/WizardPassword.qml" line="94"/> + <source>Now that your wallet has been created, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardPassword.qml" line="105"/> + <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> + Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> + <oldsource>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> + Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</oldsource> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardRecoveryWallet</name> + <message> + <location filename="wizard/WizardRecoveryWallet.qml" line="51"/> + <source>My account name</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardRecoveryWallet.qml" line="52"/> + <source>We're ready to recover your account</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardRecoveryWallet.qml" line="53"/> + <source>Please enter your 25 word private key</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardWelcome</name> + <message> + <location filename="wizard/WizardWelcome.qml" line="61"/> + <source>Welcome</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardWelcome.qml" line="72"/> + <source>Please choose a language and regional format.</source> + <translation type="unfinished"></translation> + </message> +</context> +</TS> From 1571118e7b59779629afdbe5d69e0c69ec75f1aa Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Sat, 6 Feb 2016 18:27:47 +0300 Subject: [PATCH 07/87] Refactored wizard paths internal handling --- qml.qrc | 1 + 1 file changed, 1 insertion(+) diff --git a/qml.qrc b/qml.qrc index dbd862f1..bfa55389 100644 --- a/qml.qrc +++ b/qml.qrc @@ -110,5 +110,6 @@ <file>wizard/WizardManageWalletUI.qml</file> <file>wizard/WizardRecoveryWallet.qml</file> <file>wizard/WizardMemoTextInput.qml</file> + <file>wizard/utils.js</file> </qresource> </RCC> From 1364c2b4988d0fad4ef236ca09bff226432764ce Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Sat, 6 Feb 2016 19:19:54 +0300 Subject: [PATCH 08/87] Password strength level updated --- components/PrivacyLevelSmall.qml | 10 +++++- monero-core.pro | 3 +- wizard/WizardMain.qml | 60 +++++++++++++++++--------------- wizard/WizardPassword.qml | 17 ++++++--- wizard/WizardRecoveryWallet.qml | 4 +++ 5 files changed, 60 insertions(+), 34 deletions(-) diff --git a/components/PrivacyLevelSmall.qml b/components/PrivacyLevelSmall.qml index 21c794ef..9321ffbd 100644 --- a/components/PrivacyLevelSmall.qml +++ b/components/PrivacyLevelSmall.qml @@ -36,6 +36,13 @@ Item { height: 40 clip: true + onFillLevelChanged: { + if (!interactive) { + //print("fillLevel: " + fillLevel) + fillRect.width = row.positions[fillLevel].currentX + row.x + } + } + Rectangle { anchors.left: parent.left anchors.right: parent.right @@ -134,6 +141,7 @@ Item { if(index !== -1) { fillRect.width = Qt.binding(function(){ return row.positions[index].currentX + row.x }) item.fillLevel = index + print ("fillLevel: " + item.fillLevel) } } @@ -148,7 +156,7 @@ Item { anchors.rightMargin: 8 anchors.top: bar.bottom anchors.topMargin: 5 - property var positions: new Array() + property var positions: [] Row { id: row2 diff --git a/monero-core.pro b/monero-core.pro index fece659e..dc2a500a 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -55,7 +55,7 @@ QML_IMPORT_PATH = # Default rules for deployment. include(deployment.pri) -DISTFILES += \ + OTHER_FILES += \ @@ -67,3 +67,4 @@ OTHER_FILES += \ + diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index a52c219f..6b25be1d 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -34,9 +34,13 @@ Rectangle { property alias nextButton : nextButton property var settings : ({}) property int currentPage: 0 - property var pages: [welcomePage, optionsPage, createWalletPage, recoveryWalletPage, - passwordPage,/*configurePage,*/ donationPage, finishPage ] - property string path; + + property var paths: { + "create_wallet" : [welcomePage, optionsPage, createWalletPage, passwordPage, donationPage, finishPage ], + "recovery_wallet" : [welcomePage, optionsPage, recoveryWalletPage, passwordPage, donationPage, finishPage ] + } + property string currentPath: "create_wallet" + property var pages: paths[currentPath] signal useMoneroClicked() border.color: "#DBDBDB" @@ -51,20 +55,8 @@ Rectangle { print ("switchpage: start: currentPage: ", currentPage); if (currentPage > 0 || currentPage < pages.length - 1) { - pages[currentPage].opacity = 0 - var step_value = next ? 1 : -1 - // special case - we stepping backward from password page: - // previous page "createWallet" or "recoveryWallet" - if (!next) { - print ("stepping back: current page: ", currentPage); - if ((pages[currentPage] === passwordPage && path === "create_walled") - || (pages[currentPage] === recoveryWalletPage) ) { - step_value *= 2; - } - } - currentPage += step_value pages[currentPage].opacity = 1; handlePageChanged(); @@ -73,25 +65,38 @@ Rectangle { } function handlePageChanged() { - // disable "next" button until passwords match - if (pages[currentPage] === passwordPage) { + switch (pages[currentPage]) { + case passwordPage: + // disable "next" button until passwords match nextButton.enabled = passwordPage.passwordValid; - } else if (pages[currentPage] === finishPage) { + if (currentPath === "create_wallet") { + passwordPage.titleText = qsTr("Now that your wallet has been created, please set a password for the wallet") + } else { + passwordPage.titleText = qsTr("Now that your wallet has been restored, please set a password for the wallet") + } + break; + case finishPage: // display settings summary finishPage.updateSettingsSummary(); - nextButton.visible = false - } else { - var enableButton = pages[currentPage] !== optionsPage; - nextButton.visible = nextButton.enabled = enableButton - print ("nextButtonVisible: ", enableButton) + nextButton.visible = false; + break; + case recoveryWalletPage: + // TODO: disable "next button" until 25 words private key entered + // nextButton.enabled = false; + break + default: + var nextButtonVisible = pages[currentPage] !== optionsPage; + //nextButton.visible = nextButton.enabled = nextButtonVisible; } + } function openCreateWalletPage() { print ("show create wallet page"); pages[currentPage].opacity = 0; createWalletPage.opacity = 1 - path = "create_wallet"; + currentPath = "create_wallet" + pages = paths[currentPath] currentPage = pages.indexOf(createWalletPage) handlePageChanged() } @@ -100,7 +105,8 @@ Rectangle { print ("show recovery wallet page"); pages[currentPage].opacity = 0 recoveryWalletPage.opacity = 1 - path = "recovery_wallet" + currentPath = "recovery_wallet" + pages = paths[currentPath] currentPage = pages.indexOf(recoveryWalletPage) handlePageChanged() } @@ -134,8 +140,6 @@ Rectangle { } - - WizardWelcome { id: welcomePage anchors.top: parent.top @@ -246,7 +250,7 @@ Rectangle { shadowPressedColor: "#B32D00" releasedColor: "#FF6C3C" pressedColor: "#FF4304" - visible: parent.pages[currentPage] === finishPage + visible: parent.paths[currentPath][currentPage] === finishPage onClicked: wizard.useMoneroClicked() } } diff --git a/wizard/WizardPassword.qml b/wizard/WizardPassword.qml index d12409ea..eb9d9c2c 100644 --- a/wizard/WizardPassword.qml +++ b/wizard/WizardPassword.qml @@ -28,10 +28,15 @@ import QtQuick 2.2 import "../components" +import "utils.js" as Utils Item { opacity: 0 visible: false + property bool passwordValid : passwordItem.password != '' + && passwordItem.password === retypePasswordItem.password + + property alias titleText: titleText.text Behavior on opacity { NumberAnimation { duration: 100; easing.type: Easing.InQuad } } @@ -40,12 +45,15 @@ Item { function handlePassword() { // allow to forward step only if passwords match - // TODO: update password strength wizard.nextButton.enabled = passwordItem.password === retypePasswordItem.password + // scorePassword returns value from 1..100 + var strength = Utils.scorePassword(passwordItem.password) + // privacyLevel component uses 1..13 scale + privacyLevel.fillLevel = Utils.mapScope(1, 100, 1, 13, strength) } - property bool passwordValid : passwordItem.password != '' - && passwordItem.password === retypePasswordItem.password + + Row { @@ -84,6 +92,7 @@ Item { spacing: 24 Text { + id: titleText anchors.left: parent.left width: headerColumn.width - dotsRow.width - 16 font.family: "Arial" @@ -91,7 +100,7 @@ Item { wrapMode: Text.Wrap //renderType: Text.NativeRendering color: "#3F3F3F" - text: qsTr("Now that your wallet has been created, please set a password for the wallet") + } Text { diff --git a/wizard/WizardRecoveryWallet.qml b/wizard/WizardRecoveryWallet.qml index 46af302b..9093c59a 100644 --- a/wizard/WizardRecoveryWallet.qml +++ b/wizard/WizardRecoveryWallet.qml @@ -55,5 +55,9 @@ Item { wordsTextItem.tipTextVisible: false wordsTextItem.memoTextReadOnly: false wordsTextItem.memoText: "" + wordsTextItem.onMemoTextChanged: { + var wordsArray = wordsTextItem.memoText.trim().split(" ") + //wizard.nextButton.enabled = wordsArray.length === 25 + } } } From 8bc411c598801642d6f39bc9a797c7c547c3c707 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Mon, 8 Feb 2016 10:12:12 +0300 Subject: [PATCH 09/87] wordings and text alignment according to design --- wizard/WizardFinish.qml | 2 ++ wizard/WizardManageWalletUI.qml | 2 ++ wizard/WizardOptions.qml | 4 +++- wizard/WizardPassword.qml | 2 ++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/wizard/WizardFinish.qml b/wizard/WizardFinish.qml index 7902c0b2..62975d8c 100644 --- a/wizard/WizardFinish.qml +++ b/wizard/WizardFinish.qml @@ -94,6 +94,7 @@ Item { font.family: "Arial" font.pixelSize: 28 wrapMode: Text.Wrap + horizontalAlignment: Text.AlignHCenter //renderType: Text.NativeRendering color: "#3F3F3F" text: qsTr("You’re all setup!") @@ -107,6 +108,7 @@ Item { font.pixelSize: 18 wrapMode: Text.Wrap textFormat: Text.RichText + horizontalAlignment: Text.AlignHCenter //renderType: Text.NativeRendering color: "#4A4646" } diff --git a/wizard/WizardManageWalletUI.qml b/wizard/WizardManageWalletUI.qml index a00814a9..651c7081 100644 --- a/wizard/WizardManageWalletUI.qml +++ b/wizard/WizardManageWalletUI.qml @@ -86,6 +86,7 @@ Item { font.family: "Arial" font.pixelSize: 28 wrapMode: Text.Wrap + horizontalAlignment: Text.AlignHCenter //renderType: Text.NativeRendering color: "#3F3F3F" } @@ -96,6 +97,7 @@ Item { font.family: "Arial" font.pixelSize: 18 wrapMode: Text.Wrap + horizontalAlignment: Text.AlignHCenter //renderType: Text.NativeRendering color: "#4A4646" text: qsTr("This is the name of your wallet. You can change it to a different name if you’d like:") diff --git a/wizard/WizardOptions.qml b/wizard/WizardOptions.qml index a6718853..621cac78 100644 --- a/wizard/WizardOptions.qml +++ b/wizard/WizardOptions.qml @@ -58,7 +58,8 @@ Item { //renderType: Text.NativeRendering color: "#3F3F3F" wrapMode: Text.Wrap - text: qsTr("I want") + horizontalAlignment: Text.AlignHCenter + text: qsTr("Welcome to Monero!") } Text { @@ -69,6 +70,7 @@ Item { //renderType: Text.NativeRendering color: "#4A4646" wrapMode: Text.Wrap + horizontalAlignment: Text.AlignHCenter text: qsTr("Please select one of the following options:") } } diff --git a/wizard/WizardPassword.qml b/wizard/WizardPassword.qml index eb9d9c2c..d3d033aa 100644 --- a/wizard/WizardPassword.qml +++ b/wizard/WizardPassword.qml @@ -98,6 +98,7 @@ Item { font.family: "Arial" font.pixelSize: 28 wrapMode: Text.Wrap + horizontalAlignment: Text.AlignHCenter //renderType: Text.NativeRendering color: "#3F3F3F" @@ -111,6 +112,7 @@ Item { wrapMode: Text.Wrap //renderType: Text.NativeRendering color: "#4A4646" + horizontalAlignment: Text.AlignHCenter text: qsTr("Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.") } From 16020ae2a896633bc197cb3aca624c72329dd994 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Mon, 8 Feb 2016 10:15:25 +0300 Subject: [PATCH 10/87] Wizard: "next button" visibility in backward direction fixed --- wizard/WizardMain.qml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index 6b25be1d..eeefbf17 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -65,6 +65,8 @@ Rectangle { } function handlePageChanged() { + var nextButtonVisible = pages[currentPage] !== optionsPage; + nextButton.visible = nextButtonVisible; switch (pages[currentPage]) { case passwordPage: // disable "next" button until passwords match @@ -85,8 +87,7 @@ Rectangle { // nextButton.enabled = false; break default: - var nextButtonVisible = pages[currentPage] !== optionsPage; - //nextButton.visible = nextButton.enabled = nextButtonVisible; + } } From e555631b40972b0264962f5bbd780ddd3aef5a7c Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Mon, 8 Feb 2016 10:58:01 +0300 Subject: [PATCH 11/87] wallet directrory in "Documents" for Windows and in "home" for *nix --- main.cpp | 15 +++++++++++++++ wizard/WizardManageWalletUI.qml | 6 ++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/main.cpp b/main.cpp index ecc8b626..af429df3 100644 --- a/main.cpp +++ b/main.cpp @@ -29,6 +29,7 @@ #include <QApplication> #include <QQmlApplicationEngine> #include <QtQml> +#include <QStandardPaths> #include "clipboardAdapter.h" #include "filter.h" #include "oscursor.h" @@ -46,6 +47,20 @@ int main(int argc, char *argv[]) OSCursor cursor; engine.rootContext()->setContextProperty("globalCursor", &cursor); +// export to QML monero accounts root directory +// wizard is talking about where +// to save the wallet file (.keys, .bin), they have to be user-accessible for +// backups - I reckon we save that in My Documents\Monero Accounts\ on +// Windows, ~/Monero Accounts/ on nix / osx +#ifdef Q_OS_WIN + QStringList moneroAccountsRootDir = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation); +#elif defined(Q_OS_UNIX) + QStringList moneroAccountsRootDir = QStandardPaths::standardLocations(QStandardPaths::HomeLocation); +#endif + if (!moneroAccountsRootDir.empty()) { + engine.rootContext()->setContextProperty("moneroAccountsDir", moneroAccountsRootDir.at(0) + "/Monero Accounts"); + } + engine.rootContext()->setContextProperty("applicationDirectory", QApplication::applicationDirPath()); engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); QObject *rootObject = engine.rootObjects().first(); diff --git a/wizard/WizardManageWalletUI.qml b/wizard/WizardManageWalletUI.qml index 651c7081..6ea9ea44 100644 --- a/wizard/WizardManageWalletUI.qml +++ b/wizard/WizardManageWalletUI.qml @@ -204,10 +204,12 @@ Item { color: "#6B0072" verticalAlignment: Text.AlignVCenter selectByMouse: true - text: "~/.monero/mywallet/" + + text: moneroAccountsDir + "/My Wallet" onFocusChanged: { if(focus) { - fileDialog.visible = true + fileDialog.folder = text + fileDialog.open() } } } From 921d16a458581d01f55a7ba2f6076d1ba6daaacf Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 10 Feb 2016 21:36:35 +0300 Subject: [PATCH 12/87] Forgotten file with password strength related functions --- wizard/utils.js | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 wizard/utils.js diff --git a/wizard/utils.js b/wizard/utils.js new file mode 100644 index 00000000..6d16951d --- /dev/null +++ b/wizard/utils.js @@ -0,0 +1,39 @@ + +.pragma library + +// grabbed from SO answer page: http://stackoverflow.com/questions/948172/password-strength-meter + +function scorePassword(pass) { + var score = 0; + if (!pass) + return score; + + // award every unique letter until 5 repetitions + var letters = {}; + for (var i=0; i<pass.length; i++) { + letters[pass[i]] = (letters[pass[i]] || 0) + 1; + score += 5.0 / letters[pass[i]]; + } + + // bonus points for mixing it up + var variations = { + digits: /\d/.test(pass), + lower: /[a-z]/.test(pass), + upper: /[A-Z]/.test(pass), + nonWords: /\W/.test(pass), + } + + var variationCount = 0; + for (var check in variations) { + variationCount += (variations[check] === true) ? 1 : 0; + } + score += (variationCount - 1) * 10; + + return parseInt(score); +} + +function mapScope (inputScopeFrom, inputScopeTo, outputScopeFrom, outputScopeTo, value) { + var x = (value - inputScopeFrom) / (inputScopeTo - inputScopeFrom); + var result = outputScopeFrom + ((outputScopeTo - outputScopeFrom) * x); + return result; +} From 1195a89d06956dd91f274182b07774dae8a1c0d2 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Tue, 23 Feb 2016 18:59:26 +0300 Subject: [PATCH 13/87] started integrating wallet library --- Wallet.cpp | 6 ++++++ Wallet.h | 17 +++++++++++++++++ Wallet2Service.cpp | 6 ++++++ Wallet2Service.h | 17 +++++++++++++++++ WalletManager.cpp | 6 ++++++ WalletManager.h | 17 +++++++++++++++++ lang/languages.xml | 22 +++++++++++----------- main.cpp | 5 +++++ monero-core.pro | 13 +++++++++++-- wizard/WizardCreateWallet.qml | 7 ++++++- wizard/WizardMain.qml | 2 ++ wizard/WizardMemoTextInput.qml | 2 +- 12 files changed, 105 insertions(+), 15 deletions(-) create mode 100644 Wallet.cpp create mode 100644 Wallet.h create mode 100644 Wallet2Service.cpp create mode 100644 Wallet2Service.h create mode 100644 WalletManager.cpp create mode 100644 WalletManager.h diff --git a/Wallet.cpp b/Wallet.cpp new file mode 100644 index 00000000..89e448fd --- /dev/null +++ b/Wallet.cpp @@ -0,0 +1,6 @@ +#include "Wallet.h" + +Wallet::Wallet(QObject *parent) : QObject(parent) +{ + +} diff --git a/Wallet.h b/Wallet.h new file mode 100644 index 00000000..130712e6 --- /dev/null +++ b/Wallet.h @@ -0,0 +1,17 @@ +#ifndef WALLET_H +#define WALLET_H + +#include <QObject> + +class Wallet : public QObject +{ + Q_OBJECT +public: + explicit Wallet(QObject *parent = 0); + +signals: + +public slots: +}; + +#endif // WALLET_H \ No newline at end of file diff --git a/Wallet2Service.cpp b/Wallet2Service.cpp new file mode 100644 index 00000000..9637d31a --- /dev/null +++ b/Wallet2Service.cpp @@ -0,0 +1,6 @@ +#include "Wallet2Service.h" + +Wallet2Service::Wallet2Service(QObject *parent) : QObject(parent) +{ + +} diff --git a/Wallet2Service.h b/Wallet2Service.h new file mode 100644 index 00000000..9ed5ad9b --- /dev/null +++ b/Wallet2Service.h @@ -0,0 +1,17 @@ +#ifndef WALLET2SERVICE_H +#define WALLET2SERVICE_H + +#include <QObject> + +class Wallet2Service : public QObject +{ + Q_OBJECT +public: + explicit Wallet2Service(QObject *parent = 0); + +signals: + +public slots: +}; + +#endif // WALLET2SERVICE_H \ No newline at end of file diff --git a/WalletManager.cpp b/WalletManager.cpp new file mode 100644 index 00000000..7812ed34 --- /dev/null +++ b/WalletManager.cpp @@ -0,0 +1,6 @@ +#include "WalletManager.h" + +WalletManager::WalletManager(QObject *parent) : QObject(parent) +{ + +} diff --git a/WalletManager.h b/WalletManager.h new file mode 100644 index 00000000..b6153385 --- /dev/null +++ b/WalletManager.h @@ -0,0 +1,17 @@ +#ifndef WALLETMANAGER_H +#define WALLETMANAGER_H + +#include <QObject> + +class WalletManager : public QObject +{ + Q_OBJECT +public: + explicit WalletManager(QObject *parent = 0); + +signals: + +public slots: +}; + +#endif // WALLETMANAGER_H \ No newline at end of file diff --git a/lang/languages.xml b/lang/languages.xml index eacfcad5..efb84c9c 100644 --- a/lang/languages.xml +++ b/lang/languages.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8"?> <languages> - <language name="US English" flag="/lang/flags/usa.png" qs="none"/> - <language name="UK English" flag="/lang/flags/uk.png" qs="none"/> - <language name="Russia" flag="/lang/flags/russia.png" qs="none"/> - <language name="RPA" flag="/lang/flags/rpa.png" qs="none"/> - <language name="Palestine" flag="/lang/flags/palestine.png" qs="none"/> - <language name="India" flag="/lang/flags/india.png" qs="none"/> - <language name="German" flag="/lang/flags/german.png" qs="none"/> - <language name="China" flag="/lang/flags/china.png" qs="none"/> - <language name="Brazil" flag="/lang/flags/brazil.png" qs="none"/> - <language name="Bangladesh" flag="/lang/flags/bangladesh.png" qs="none"/> -</languages> \ No newline at end of file + <language name="US English" locale="en_US" flag="/lang/flags/usa.png" qs="none"/> + <language name="UK English" locale="en_GB" flag="/lang/flags/uk.png" qs="none"/> + <language name="Russia" locale="ru_RU" flag="/lang/flags/russia.png" qs="none"/> + <language name="RPA" locale="TODO" flag="/lang/flags/rpa.png" qs="none"/> + <language name="Palestine" locale="TODO" flag="/lang/flags/palestine.png" qs="none"/> + <language name="India" locale="hi_IN" flag="/lang/flags/india.png" qs="none"/> + <language name="German" locale="de_DE" flag="/lang/flags/german.png" qs="none"/> + <language name="China" locale="zh_CN" flag="/lang/flags/china.png" qs="none"/> + <language name="Brazil" locale="pt_BR" flag="/lang/flags/brazil.png" qs="none"/> + <language name="Bangladesh" locale="TODO" flag="/lang/flags/bangladesh.png" qs="none"/> +</languages> diff --git a/main.cpp b/main.cpp index af429df3..e3917f80 100644 --- a/main.cpp +++ b/main.cpp @@ -33,6 +33,9 @@ #include "clipboardAdapter.h" #include "filter.h" #include "oscursor.h" +#include "WalletManager.h" +#include "Wallet.h" + int main(int argc, char *argv[]) { @@ -41,11 +44,13 @@ int main(int argc, char *argv[]) app.installEventFilter(eventFilter); qmlRegisterType<clipboardAdapter>("moneroComponents", 1, 0, "Clipboard"); + qmlRegisterType<Wallet>("moneroWallet", 1, 0, "Wallet"); QQmlApplicationEngine engine; OSCursor cursor; engine.rootContext()->setContextProperty("globalCursor", &cursor); + engine.rootContext()->setContextProperty("walletManager", WalletManager::instance()); // export to QML monero accounts root directory // wizard is talking about where diff --git a/monero-core.pro b/monero-core.pro index dc2a500a..f021449c 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -2,16 +2,22 @@ TEMPLATE = app QT += qml quick widgets + HEADERS += \ filter.h \ clipboardAdapter.h \ - oscursor.h + oscursor.h \ + Wallet2Adaptor.h \ + WalletManager.h \ + Wallet.h SOURCES += main.cpp \ filter.cpp \ clipboardAdapter.cpp \ - oscursor.cpp + oscursor.cpp \ + WalletManager.cpp \ + Wallet.cpp lupdate_only { SOURCES = *.qml \ @@ -63,6 +69,9 @@ OTHER_FILES += \ monero-core_de.ts \ monero-core_en.ts +DISTFILES += \ + notes.txt + diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml index 65e2e989..8ce4e760 100644 --- a/wizard/WizardCreateWallet.qml +++ b/wizard/WizardCreateWallet.qml @@ -46,6 +46,12 @@ Item { settingsObject['wallet_path'] = uiItem.walletPath } + function createWallet(settingsObject) { + // print ("Language: " + settingsObject.language); + var wallet = walletManager.createWallet(uiItem.accountNameText, "", settingsObject.language); + uiItem.wordsTextItem.memoText = wallet.seed + } + WizardManageWalletUI { id: uiItem titleText: qsTr("A new wallet has been created for you") @@ -53,6 +59,5 @@ Item { wordsTextItem.clipboardButtonVisible: true wordsTextItem.tipTextVisible: true wordsTextItem.memoTextReadOnly: true - } } diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index eeefbf17..5f51cec8 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -99,7 +99,9 @@ Rectangle { currentPath = "create_wallet" pages = paths[currentPath] currentPage = pages.indexOf(createWalletPage) + createWalletPage.createWallet(settings) handlePageChanged() + } function openRecoveryWalletPage() { diff --git a/wizard/WizardMemoTextInput.qml b/wizard/WizardMemoTextInput.qml index 89eadb15..39f9211b 100644 --- a/wizard/WizardMemoTextInput.qml +++ b/wizard/WizardMemoTextInput.qml @@ -25,7 +25,7 @@ Column { TextEdit { id: memoTextInput textMargin: 8 - text: "bound class paint gasp task soul forgot past pleasure physical circle appear shore bathroom glove women crap busy beauty bliss idea give needle burden" + text: "" font.family: "Arial" font.pointSize: 16 wrapMode: TextInput.Wrap From 625041df1823f2ce98b53fa054bab47876717c15 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 24 Feb 2016 13:25:20 +0300 Subject: [PATCH 14/87] integrating cpp wallet mockups with QML --- Wallet.cpp | 27 +++++++++- Wallet.h | 18 +++++-- Wallet2Service.cpp | 6 --- Wallet2Service.h | 17 ------- WalletManager.cpp | 87 +++++++++++++++++++++++++++++++++ WalletManager.h | 15 +++++- main.cpp | 7 ++- monero-core.pro | 1 - wizard/WizardCreateWallet.qml | 23 +++++++-- wizard/WizardMain.qml | 2 + wizard/WizardManageWalletUI.qml | 5 +- 11 files changed, 172 insertions(+), 36 deletions(-) delete mode 100644 Wallet2Service.cpp delete mode 100644 Wallet2Service.h diff --git a/Wallet.cpp b/Wallet.cpp index 89e448fd..5507f531 100644 --- a/Wallet.cpp +++ b/Wallet.cpp @@ -1,6 +1,31 @@ #include "Wallet.h" -Wallet::Wallet(QObject *parent) : QObject(parent) +struct WalletImpl +{ + // TODO +}; + + + +Wallet::Wallet(QObject *parent) + : QObject(parent) { } + + +QString Wallet::getSeed() const +{ + return "bound class paint gasp task soul forgot past pleasure physical circle " + " appear shore bathroom glove women crap busy beauty bliss idea give needle burden"; +} + +QString Wallet::getSeedLanguage() const +{ + return "English"; +} + +void Wallet::setSeedLaguage(const QString &lang) +{ + // TODO; +} diff --git a/Wallet.h b/Wallet.h index 130712e6..14018a66 100644 --- a/Wallet.h +++ b/Wallet.h @@ -3,15 +3,27 @@ #include <QObject> +struct WalletImpl; + class Wallet : public QObject { Q_OBJECT + Q_PROPERTY(QString seed READ getSeed) public: explicit Wallet(QObject *parent = 0); - + QString getSeed() const; + QString getSeedLanguage() const; + void setSeedLaguage(const QString &lang); signals: - public slots: + +private: + + + friend class WalletManager; + WalletImpl * m_pimpl; + + }; -#endif // WALLET_H \ No newline at end of file +#endif // WALLET_H diff --git a/Wallet2Service.cpp b/Wallet2Service.cpp deleted file mode 100644 index 9637d31a..00000000 --- a/Wallet2Service.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "Wallet2Service.h" - -Wallet2Service::Wallet2Service(QObject *parent) : QObject(parent) -{ - -} diff --git a/Wallet2Service.h b/Wallet2Service.h deleted file mode 100644 index 9ed5ad9b..00000000 --- a/Wallet2Service.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef WALLET2SERVICE_H -#define WALLET2SERVICE_H - -#include <QObject> - -class Wallet2Service : public QObject -{ - Q_OBJECT -public: - explicit Wallet2Service(QObject *parent = 0); - -signals: - -public slots: -}; - -#endif // WALLET2SERVICE_H \ No newline at end of file diff --git a/WalletManager.cpp b/WalletManager.cpp index 7812ed34..992dfa4d 100644 --- a/WalletManager.cpp +++ b/WalletManager.cpp @@ -1,6 +1,93 @@ #include "WalletManager.h" +#include "Wallet.h" +#include <QFile> +#include <QFileInfo> +#include <QDir> +#include <QDebug> +#include <QUrl> + +WalletManager * WalletManager::m_instance = nullptr; + + +namespace { + bool createFileWrapper(const QString &filename) + { + QFile file(filename); + // qDebug("%s: about to create file: %s", __FUNCTION__, qPrintable(filename)); + bool result = file.open(QIODevice::WriteOnly); + if (!result ){ + qWarning("%s: error creating file '%s' : '%s'", + __FUNCTION__, + qPrintable(filename), + qPrintable(file.errorString())); + } + return result; + } +} + + +WalletManager *WalletManager::instance() +{ + if (!m_instance) { + m_instance = new WalletManager; + } + + return m_instance; +} + +Wallet *WalletManager::createWallet(const QString &path, const QString &password, + const QString &language) +{ + Wallet * wallet = new Wallet(this); + // Create dummy files for testing + QFileInfo fi(path); + QDir tempDir; + tempDir.mkpath(fi.absolutePath()); + createFileWrapper(path); + createFileWrapper(path + ".keys"); + createFileWrapper(path + ".address.txt"); + return wallet; +} + +Wallet *WalletManager::openWallet(const QString &path, const QString &language) +{ + return nullptr; +} + +bool WalletManager::moveWallet(const QString &src, const QString &dst_) +{ + QFile walletFile(src); + if (!walletFile.exists()) { + qWarning("%s: source file [%s] doesn't exits", __FUNCTION__, + qPrintable(src)); + return false; + } + QString dst = QUrl(dst_).toLocalFile(); + QString walletKeysFile = src + ".keys"; + QString walletAddressFile = src + ".address.txt"; + + QString dstWalletKeysFile = dst + ".keys"; + QString dstWalletAddressFile = dst + ".address.txt"; + + if (!walletFile.rename(dst)) { + qWarning("Error renaming file: '%s' to '%s' : (%s)", + qPrintable(src), + qPrintable(dst), + qPrintable(walletFile.errorString())); + return false; + } + QFile::rename(walletKeysFile, dstWalletKeysFile); + QFile::rename(walletAddressFile, dstWalletAddressFile); + + return QFile::exists(dst) && QFile::exists(dstWalletKeysFile) + && QFile::exists(dstWalletAddressFile); + + +} WalletManager::WalletManager(QObject *parent) : QObject(parent) { } + + diff --git a/WalletManager.h b/WalletManager.h index b6153385..ffb498d7 100644 --- a/WalletManager.h +++ b/WalletManager.h @@ -3,15 +3,26 @@ #include <QObject> +class Wallet; + class WalletManager : public QObject { Q_OBJECT public: - explicit WalletManager(QObject *parent = 0); + static WalletManager * instance(); + Q_INVOKABLE Wallet * createWallet(const QString &path, const QString &password, + const QString &language); + Q_INVOKABLE Wallet * openWallet(const QString &path, const QString &language); + Q_INVOKABLE bool moveWallet(const QString &src, const QString &dst); signals: public slots: + +private: + explicit WalletManager(QObject *parent = 0); + static WalletManager * m_instance; + }; -#endif // WALLETMANAGER_H \ No newline at end of file +#endif // WALLETMANAGER_H diff --git a/main.cpp b/main.cpp index e3917f80..0e996b84 100644 --- a/main.cpp +++ b/main.cpp @@ -57,13 +57,18 @@ int main(int argc, char *argv[]) // to save the wallet file (.keys, .bin), they have to be user-accessible for // backups - I reckon we save that in My Documents\Monero Accounts\ on // Windows, ~/Monero Accounts/ on nix / osx + #ifdef Q_OS_WIN QStringList moneroAccountsRootDir = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation); #elif defined(Q_OS_UNIX) QStringList moneroAccountsRootDir = QStandardPaths::standardLocations(QStandardPaths::HomeLocation); #endif + if (!moneroAccountsRootDir.empty()) { - engine.rootContext()->setContextProperty("moneroAccountsDir", moneroAccountsRootDir.at(0) + "/Monero Accounts"); + QString moneroAccountsDir = moneroAccountsRootDir.at(0) + "/Monero Accounts"; + QDir tempDir; + tempDir.mkpath(moneroAccountsDir); + engine.rootContext()->setContextProperty("moneroAccountsDir", moneroAccountsDir); } engine.rootContext()->setContextProperty("applicationDirectory", QApplication::applicationDirPath()); diff --git a/monero-core.pro b/monero-core.pro index f021449c..bee7eb17 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -7,7 +7,6 @@ HEADERS += \ filter.h \ clipboardAdapter.h \ oscursor.h \ - Wallet2Adaptor.h \ WalletManager.h \ Wallet.h diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml index 8ce4e760..91b7447e 100644 --- a/wizard/WizardCreateWallet.qml +++ b/wizard/WizardCreateWallet.qml @@ -44,12 +44,29 @@ Item { settingsObject['account_name'] = uiItem.accountNameText settingsObject['words'] = uiItem.wordsTexttext settingsObject['wallet_path'] = uiItem.walletPath + + + var new_wallet_filename = settingsObject.wallet_path + "/" + + settingsObject.account_name; + + // moving wallet files to the new destination, if user changed it + if (new_wallet_filename !== settingsObject.wallet_filename) { + walletManager.moveWallet(settingsObject.wallet_filename, new_wallet_filename); + } } function createWallet(settingsObject) { - // print ("Language: " + settingsObject.language); - var wallet = walletManager.createWallet(uiItem.accountNameText, "", settingsObject.language); - uiItem.wordsTextItem.memoText = wallet.seed + var wallet_filename = uiItem.walletPath + "/" + uiItem.accountNameText + if (typeof settingsObject.wallet === 'undefined') { + var wallet = walletManager.createWallet(wallet_filename, "", settingsObject.language) + 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 + } else { + print("wallet already created. we just stepping back"); + } + settingsObject.wallet_filename = wallet_filename } WizardManageWalletUI { diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index 5f51cec8..51e0baf3 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -67,6 +67,7 @@ Rectangle { function handlePageChanged() { var nextButtonVisible = pages[currentPage] !== optionsPage; nextButton.visible = nextButtonVisible; + print ("next button visible: " + nextButtonVisible); switch (pages[currentPage]) { case passwordPage: // disable "next" button until passwords match @@ -87,6 +88,7 @@ Rectangle { // nextButton.enabled = false; break default: + nextButton.enabled = true } diff --git a/wizard/WizardManageWalletUI.qml b/wizard/WizardManageWalletUI.qml index 6ea9ea44..ce035f0a 100644 --- a/wizard/WizardManageWalletUI.qml +++ b/wizard/WizardManageWalletUI.qml @@ -183,9 +183,10 @@ Item { FileDialog { id: fileDialog selectMultiple: false - title: "Please choose a file" + selectFolder: true + title: "Please choose a directory" onAccepted: { - fileUrlInput.text = fileDialog.fileUrl + fileUrlInput.text = fileDialog.folder fileDialog.visible = false } onRejected: { From 7d9306ca1a661da015c59a0a991e028aeec0ee44 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Mon, 29 Feb 2016 17:39:39 +0300 Subject: [PATCH 15/87] Qt wrapper for libwallet - in-progress --- Wallet.cpp | 175 ++++++++++++++++++++++++++++++-- Wallet.h | 33 ++++-- WalletManager.cpp | 66 +++++++----- WalletManager.h | 24 ++++- wizard/WizardCreateWallet.qml | 9 +- wizard/WizardFinish.qml | 2 +- wizard/WizardPassword.qml | 6 +- wizard/WizardRecoveryWallet.qml | 4 + 8 files changed, 275 insertions(+), 44 deletions(-) diff --git a/Wallet.cpp b/Wallet.cpp index 5507f531..61998ab5 100644 --- a/Wallet.cpp +++ b/Wallet.cpp @@ -1,11 +1,82 @@ #include "Wallet.h" +#include <QFile> +#include <QDir> +#include <QDebug> +#include <QUrl> + +namespace { + QString TEST_SEED = "bound class paint gasp task soul forgot past pleasure physical circle " + " appear shore bathroom glove women crap busy beauty bliss idea give needle burden"; + + namespace { + bool createFileWrapper(const QString &filename) + { + QFile file(filename); + // qDebug("%s: about to create file: %s", __FUNCTION__, qPrintable(filename)); + bool result = file.open(QIODevice::WriteOnly); + if (!result ){ + qWarning("%s: error creating file '%s' : '%s'", + __FUNCTION__, + qPrintable(filename), + qPrintable(file.errorString())); + } + return result; + } + } + +} struct WalletImpl { - // TODO + + QString basename() const; + void setBasename(const QString &name); + + QString keysName() const; + QString addressName() const; + +// Bitmonero::Wallet * m_walletImpl; + QString m_basename; + QString m_seed; + QString m_password; + QString m_language; + + static QString keysName(const QString &basename); + static QString addressName(const QString &basename); + }; +QString WalletImpl::basename() const +{ + return m_basename; +} + +void WalletImpl::setBasename(const QString &name) +{ + m_basename = name; +} + +QString WalletImpl::keysName() const +{ + return keysName(m_basename); +} + +QString WalletImpl::addressName() const +{ + return addressName(m_basename); +} + +QString WalletImpl::keysName(const QString &basename) +{ + return basename + ".keys"; +} + +QString WalletImpl::addressName(const QString &basename) +{ + return basename + ".address.txt"; +} + Wallet::Wallet(QObject *parent) : QObject(parent) @@ -13,11 +84,9 @@ Wallet::Wallet(QObject *parent) } - QString Wallet::getSeed() const { - return "bound class paint gasp task soul forgot past pleasure physical circle " - " appear shore bathroom glove women crap busy beauty bliss idea give needle burden"; + return m_pimpl->m_seed; } QString Wallet::getSeedLanguage() const @@ -25,7 +94,101 @@ QString Wallet::getSeedLanguage() const return "English"; } -void Wallet::setSeedLaguage(const QString &lang) +//void Wallet::setSeedLaguage(const QString &lang) +//{ +// // TODO: call libwallet's appropriate method +//} + +bool Wallet::setPassword(const QString &password) { - // TODO; + // set/change password implies: + // recovery wallet with existing path, seed and lang + qDebug("%s: recovering wallet with path=%s, seed=%s, lang=%s and new password=%s", + __FUNCTION__, + qPrintable(this->getBasename()), + qPrintable(this->getSeed()), + qPrintable(this->getSeedLanguage()), + qPrintable(password)); + return true; } + +QString Wallet::getPassword() const +{ + return m_pimpl->m_password; +} + +bool Wallet::rename(const QString &name) +{ + + QString dst = QUrl(name).toLocalFile(); + + if (dst.isEmpty()) + dst = name; + + qDebug("%s: renaming '%s' to '%s'", + __FUNCTION__, + qPrintable(m_pimpl->basename()), + qPrintable(dst)); + + QString walletKeysFile = m_pimpl->keysName(); + QString walletAddressFile = m_pimpl->addressName(); + + QString dstWalletKeysFile = WalletImpl::keysName(dst); + QString dstWalletAddressFile = WalletImpl::addressName(dst); + + QFile walletFile(this->getBasename()); + + if (!walletFile.rename(dst)) { + qWarning("Error renaming file: '%s' to '%s' : (%s)", + qPrintable(m_pimpl->basename()), + qPrintable(dst), + qPrintable(walletFile.errorString())); + return false; + } + QFile::rename(walletKeysFile, dstWalletKeysFile); + QFile::rename(walletAddressFile, dstWalletAddressFile); + + bool result = QFile::exists(dst) && QFile::exists(dstWalletKeysFile) + && QFile::exists(dstWalletAddressFile); + + if (result) { + m_pimpl->m_basename = dst; + } + + return result; +} + +QString Wallet::getBasename() const +{ + return m_pimpl->basename(); +} + +int Wallet::error() const +{ + return 0; +} + +QString Wallet::errorString() const +{ + return m_pimpl->m_seed; +} + +Wallet::Wallet(const QString &path, const QString &password, const QString &language) +{ + m_pimpl = new WalletImpl; + m_pimpl->m_basename = path; + m_pimpl->m_password = password; + m_pimpl->m_language = language; + m_pimpl->m_seed = TEST_SEED; + + // Create dummy files for testing + QFileInfo fi(path); + QDir tempDir; + tempDir.mkpath(fi.absolutePath()); + createFileWrapper(m_pimpl->basename()); + createFileWrapper(m_pimpl->keysName()); + createFileWrapper(m_pimpl->addressName()); +} + + + diff --git a/Wallet.h b/Wallet.h index 14018a66..221d3d43 100644 --- a/Wallet.h +++ b/Wallet.h @@ -4,26 +4,41 @@ #include <QObject> struct WalletImpl; - class Wallet : public QObject { Q_OBJECT Q_PROPERTY(QString seed READ getSeed) public: explicit Wallet(QObject *parent = 0); - QString getSeed() const; - QString getSeedLanguage() const; - void setSeedLaguage(const QString &lang); -signals: -public slots: + + //! returns mnemonic seed + Q_INVOKABLE QString getSeed() const; + + //! returns seed language + Q_INVOKABLE QString getSeedLanguage() const; + + + //! changes the password using existing parameters (path, seed, seed lang) + Q_INVOKABLE bool setPassword(const QString &password); + //! returns curret wallet password + Q_INVOKABLE QString getPassword() const; + + //! renames/moves wallet files + Q_INVOKABLE bool rename(const QString &name); + + //! returns current wallet name (basename, as wallet consists of several files) + Q_INVOKABLE QString getBasename() const; + + Q_INVOKABLE int error() const; + Q_INVOKABLE QString errorString() const; private: + Wallet(const QString &path, const QString &password, const QString &language); - +private: friend class WalletManager; + //! pimpl wrapper for libwallet; WalletImpl * m_pimpl; - - }; #endif // WALLET_H diff --git a/WalletManager.cpp b/WalletManager.cpp index 992dfa4d..4a2f0c8f 100644 --- a/WalletManager.cpp +++ b/WalletManager.cpp @@ -9,21 +9,7 @@ WalletManager * WalletManager::m_instance = nullptr; -namespace { - bool createFileWrapper(const QString &filename) - { - QFile file(filename); - // qDebug("%s: about to create file: %s", __FUNCTION__, qPrintable(filename)); - bool result = file.open(QIODevice::WriteOnly); - if (!result ){ - qWarning("%s: error creating file '%s' : '%s'", - __FUNCTION__, - qPrintable(filename), - qPrintable(file.errorString())); - } - return result; - } -} + WalletManager *WalletManager::instance() @@ -38,24 +24,40 @@ WalletManager *WalletManager::instance() Wallet *WalletManager::createWallet(const QString &path, const QString &password, const QString &language) { - Wallet * wallet = new Wallet(this); - // Create dummy files for testing QFileInfo fi(path); - QDir tempDir; - tempDir.mkpath(fi.absolutePath()); - createFileWrapper(path); - createFileWrapper(path + ".keys"); - createFileWrapper(path + ".address.txt"); + if (fi.exists()) { + qCritical("%s: already exists", __FUNCTION__); + // TODO: set error and error string + // return nullptr; + } + Wallet * wallet = new Wallet(path, password, language); return wallet; } -Wallet *WalletManager::openWallet(const QString &path, const QString &language) +Wallet *WalletManager::openWallet(const QString &path, const QString &language, const QString &password) { + QFileInfo fi(path); + if (fi.exists()) { + qCritical("%s: not exists", __FUNCTION__); + // TODO: set error and error string + // return nullptr; + } + // TODO: call the libwallet api here; + Wallet * wallet = new Wallet(path, password, language); + + return wallet; +} + +Wallet *WalletManager::recoveryWallet(const QString &path, const QString &memo, const QString &language) +{ + // TODO: call the libwallet api here; + return nullptr; } bool WalletManager::moveWallet(const QString &src, const QString &dst_) { + // TODO: move this to libwallet; QFile walletFile(src); if (!walletFile.exists()) { qWarning("%s: source file [%s] doesn't exits", __FUNCTION__, @@ -81,8 +83,26 @@ bool WalletManager::moveWallet(const QString &src, const QString &dst_) return QFile::exists(dst) && QFile::exists(dstWalletKeysFile) && QFile::exists(dstWalletAddressFile); +} +void WalletManager::closeWallet(Wallet *wallet) +{ + delete wallet; +} +QString WalletManager::walletLanguage(const QString &locale) +{ + return "English"; +} + +int WalletManager::error() const +{ + return 0; +} + +QString WalletManager::errorString() const +{ + return tr("Unknown error"); } WalletManager::WalletManager(QObject *parent) : QObject(parent) diff --git a/WalletManager.h b/WalletManager.h index ffb498d7..231f104c 100644 --- a/WalletManager.h +++ b/WalletManager.h @@ -10,11 +10,32 @@ class WalletManager : public QObject Q_OBJECT public: static WalletManager * instance(); + // wizard: createWallet path; Q_INVOKABLE Wallet * createWallet(const QString &path, const QString &password, const QString &language); - Q_INVOKABLE Wallet * openWallet(const QString &path, const QString &language); + // just for future use + Q_INVOKABLE Wallet * openWallet(const QString &path, const QString &language, + const QString &password); + + // wizard: recoveryWallet path; hint: internally it recorvers wallet and set password = "" + Q_INVOKABLE Wallet * recoveryWallet(const QString &path, const QString &memo, + const QString &language); + + // wizard: both "create" and "recovery" paths. + // TODO: probably move it to "Wallet" interface Q_INVOKABLE bool moveWallet(const QString &src, const QString &dst); + //! utils: close wallet to free memory + Q_INVOKABLE void closeWallet(Wallet * wallet); + + //! returns libwallet language name for given locale + Q_INVOKABLE QString walletLanguage(const QString &locale); + + //! returns last error happened in WalletManager + Q_INVOKABLE int error() const; + + //! returns error description in human language + Q_INVOKABLE QString errorString() const; signals: public slots: @@ -22,7 +43,6 @@ public slots: private: explicit WalletManager(QObject *parent = 0); static WalletManager * m_instance; - }; #endif // WALLETMANAGER_H diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml index 91b7447e..ce573e86 100644 --- a/wizard/WizardCreateWallet.qml +++ b/wizard/WizardCreateWallet.qml @@ -46,13 +46,19 @@ Item { settingsObject['wallet_path'] = uiItem.walletPath + var new_wallet_filename = settingsObject.wallet_path + "/" + settingsObject.account_name; // moving wallet files to the new destination, if user changed it if (new_wallet_filename !== settingsObject.wallet_filename) { - walletManager.moveWallet(settingsObject.wallet_filename, new_wallet_filename); + // using previously saved wallet; + settingsObject.wallet.rename(new_wallet_filename); + //walletManager.moveWallet(settingsObject.wallet_filename, new_wallet_filename); } + + // saving wallet_filename; + settingsObject['wallet_filename'] = new_wallet_filename; } function createWallet(settingsObject) { @@ -66,6 +72,7 @@ Item { } else { print("wallet already created. we just stepping back"); } + settingsObject.wallet_filename = wallet_filename } diff --git a/wizard/WizardFinish.qml b/wizard/WizardFinish.qml index 62975d8c..311dfd62 100644 --- a/wizard/WizardFinish.qml +++ b/wizard/WizardFinish.qml @@ -40,7 +40,7 @@ Item { 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>Words:</b> ") + wizard.settings['wallet'].seed + "<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>" diff --git a/wizard/WizardPassword.qml b/wizard/WizardPassword.qml index d3d033aa..1bcc6213 100644 --- a/wizard/WizardPassword.qml +++ b/wizard/WizardPassword.qml @@ -43,6 +43,10 @@ Item { onOpacityChanged: visible = opacity !== 0 + function saveSettings(settingsObject) { + settingsObject.wallet.setPassword(passwordItem.password) + } + function handlePassword() { // allow to forward step only if passwords match wizard.nextButton.enabled = passwordItem.password === retypePasswordItem.password @@ -54,8 +58,6 @@ Item { - - Row { id: dotsRow anchors.top: parent.top diff --git a/wizard/WizardRecoveryWallet.qml b/wizard/WizardRecoveryWallet.qml index 9093c59a..572d776b 100644 --- a/wizard/WizardRecoveryWallet.qml +++ b/wizard/WizardRecoveryWallet.qml @@ -46,6 +46,10 @@ Item { settingsObject['wallet_path'] = uiItem.walletPath } + function recoveryWallet() { + + } + WizardManageWalletUI { id: uiItem accountNameText: qsTr("My account name") From 6d0179f1a7e28d8a858ba569df1dae7c199ea059 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Tue, 1 Mar 2016 18:41:30 +0300 Subject: [PATCH 16/87] wizard: saving locale instead of language; wallet interface continued --- wizard/WizardCreateWallet.qml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml index ce573e86..346627dc 100644 --- a/wizard/WizardCreateWallet.qml +++ b/wizard/WizardCreateWallet.qml @@ -45,8 +45,6 @@ Item { settingsObject['words'] = uiItem.wordsTexttext settingsObject['wallet_path'] = uiItem.walletPath - - var new_wallet_filename = settingsObject.wallet_path + "/" + settingsObject.account_name; @@ -64,7 +62,7 @@ Item { function createWallet(settingsObject) { var wallet_filename = uiItem.walletPath + "/" + uiItem.accountNameText if (typeof settingsObject.wallet === 'undefined') { - var wallet = walletManager.createWallet(wallet_filename, "", settingsObject.language) + var wallet = walletManager.createWallet(wallet_filename, "", settingsObject.locale) 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 From 382fa30283155f94654a7b62902136dfc4609b94 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Tue, 8 Mar 2016 12:08:24 +0300 Subject: [PATCH 17/87] explicitely enabled c++11 for g++ compiler --- monero-core.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/monero-core.pro b/monero-core.pro index bee7eb17..1f4d97d4 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -2,6 +2,7 @@ TEMPLATE = app QT += qml quick widgets +CONFIG += c++11 HEADERS += \ filter.h \ From f9e091677698d27e3e5c94dab5435d1320959ad7 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Tue, 17 May 2016 16:03:59 +0300 Subject: [PATCH 18/87] integrating libwallet --- WalletManager.cpp | 3 +++ get_libwallet_api.sh | 39 +++++++++++++++++++++++++++++++++++++++ monero-core.pro | 14 ++++++++------ 3 files changed, 50 insertions(+), 6 deletions(-) create mode 100755 get_libwallet_api.sh diff --git a/WalletManager.cpp b/WalletManager.cpp index 4a2f0c8f..cb0ffbac 100644 --- a/WalletManager.cpp +++ b/WalletManager.cpp @@ -1,5 +1,6 @@ #include "WalletManager.h" #include "Wallet.h" +#include "wallet/wallet2_api.h" #include <QFile> #include <QFileInfo> #include <QDir> @@ -17,6 +18,8 @@ WalletManager *WalletManager::instance() if (!m_instance) { m_instance = new WalletManager; } + // Checking linkage (doesn't work, TODO: have every dependencies linked statically into libwallet) + Bitmonero::WalletManager * wallet_manager_impl = Bitmonero::WalletManagerFactory::getWalletManager(); return m_instance; } diff --git a/get_libwallet_api.sh b/get_libwallet_api.sh new file mode 100755 index 00000000..9e2f65ce --- /dev/null +++ b/get_libwallet_api.sh @@ -0,0 +1,39 @@ +#!/bin/bash + + +BITMONERO_URL=https://github.com/mbg033/bitmonero +CPU_CORE_COUNT=$(grep -c ^processor /proc/cpuinfo) +pushd $(pwd) +ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + + +INSTALL_DIR=$ROOT_DIR/wallet +BITMONERO_DIR=$ROOT_DIR/bitmonero + + +if [ ! -d $BITMONERO_DIR ]; then + git clone --depth=1 $BITMONERO_URL $BITMONERO_DIR +fi + +rm -fr $BITMONERO_DIR/build +mkdir -p $BITMONERO_DIR/build/release +pushd $BITMONERO_DIR/build/release + +cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX="$BITMONERO_DIR" ../.. + +pushd $BITMONERO_DIR/build/release/src/wallet +make -j$CPU_CORE_COUNT +make install -j$CPU_CORE_COUNT +popd +popd + + + + + + + + + + + diff --git a/monero-core.pro b/monero-core.pro index 1f4d97d4..8574205f 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -2,8 +2,14 @@ TEMPLATE = app QT += qml quick widgets +WALLET_ROOT=$$PWD/bitmonero + CONFIG += c++11 +INCLUDEPATH += $$WALLET_ROOT/include + +message($$INCLUDEPATH) + HEADERS += \ filter.h \ clipboardAdapter.h \ @@ -26,6 +32,8 @@ SOURCES = *.qml \ wizard/*.qml } +LIBS += -L$$WALLET_ROOT/lib -lwallet + # translations files; TRANSLATIONS = monero-core_en.ts \ # English (could be untranslated) monero-core_de.ts # Deutsch @@ -71,9 +79,3 @@ OTHER_FILES += \ DISTFILES += \ notes.txt - - - - - - From 238d582b1741b885408f62bdeb94a6e2ecef0bd9 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Fri, 27 May 2016 11:00:26 +0300 Subject: [PATCH 19/87] build against libwallet_merged and boost libs --- get_libwallet_api.sh | 2 +- monero-core.pro | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/get_libwallet_api.sh b/get_libwallet_api.sh index 9e2f65ce..34c2e6b3 100755 --- a/get_libwallet_api.sh +++ b/get_libwallet_api.sh @@ -19,7 +19,7 @@ rm -fr $BITMONERO_DIR/build mkdir -p $BITMONERO_DIR/build/release pushd $BITMONERO_DIR/build/release -cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX="$BITMONERO_DIR" ../.. +cmake -D CMAKE_BUILD_TYPE=Release -D STATIC=ON -D CMAKE_INSTALL_PREFIX="$BITMONERO_DIR" ../.. pushd $BITMONERO_DIR/build/release/src/wallet make -j$CPU_CORE_COUNT diff --git a/monero-core.pro b/monero-core.pro index 8574205f..4b071fb1 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -8,7 +8,6 @@ CONFIG += c++11 INCLUDEPATH += $$WALLET_ROOT/include -message($$INCLUDEPATH) HEADERS += \ filter.h \ @@ -32,7 +31,16 @@ SOURCES = *.qml \ wizard/*.qml } -LIBS += -L$$WALLET_ROOT/lib -lwallet +LIBS += -L$$WALLET_ROOT/lib \ + -lwallet_merged \ + -lboost_serialization \ + -lboost_thread \ + -lboost_system \ + -lboost_date_time \ + -lboost_filesystem \ + -lboost_regex + + # translations files; TRANSLATIONS = monero-core_en.ts \ # English (could be untranslated) From 493e290956453ad068aa43b9a2fbefacd3550192 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Fri, 3 Jun 2016 17:30:19 +0300 Subject: [PATCH 20/87] libwallet integration --- main.cpp | 3 ++- monero-core.pro | 11 ++++++----- Wallet.cpp => src/libwalletqt/Wallet.cpp | 0 Wallet.h => src/libwalletqt/Wallet.h | 0 .../libwalletqt/WalletManager.cpp | 0 WalletManager.h => src/libwalletqt/WalletManager.h | 0 6 files changed, 8 insertions(+), 6 deletions(-) rename Wallet.cpp => src/libwalletqt/Wallet.cpp (100%) rename Wallet.h => src/libwalletqt/Wallet.h (100%) rename WalletManager.cpp => src/libwalletqt/WalletManager.cpp (100%) rename WalletManager.h => src/libwalletqt/WalletManager.h (100%) diff --git a/main.cpp b/main.cpp index 0e996b84..b486c5f0 100644 --- a/main.cpp +++ b/main.cpp @@ -44,7 +44,8 @@ int main(int argc, char *argv[]) app.installEventFilter(eventFilter); qmlRegisterType<clipboardAdapter>("moneroComponents", 1, 0, "Clipboard"); - qmlRegisterType<Wallet>("moneroWallet", 1, 0, "Wallet"); + //qmlRegisterType<Wallet>("moneroWallet", 1, 0, "Wallet"); + qmlRegisterType<Wallet>(); QQmlApplicationEngine engine; diff --git a/monero-core.pro b/monero-core.pro index 4b071fb1..7b05829f 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -6,23 +6,24 @@ WALLET_ROOT=$$PWD/bitmonero CONFIG += c++11 -INCLUDEPATH += $$WALLET_ROOT/include +INCLUDEPATH += $$WALLET_ROOT/include \ + $$PWD/src/libwalletqt HEADERS += \ filter.h \ clipboardAdapter.h \ oscursor.h \ - WalletManager.h \ - Wallet.h + src/libwalletqt/WalletManager.h \ + src/libwalletqt/Wallet.h SOURCES += main.cpp \ filter.cpp \ clipboardAdapter.cpp \ oscursor.cpp \ - WalletManager.cpp \ - Wallet.cpp + src/libwalletqt/WalletManager.cpp \ + src/libwalletqt/Wallet.cpp lupdate_only { SOURCES = *.qml \ diff --git a/Wallet.cpp b/src/libwalletqt/Wallet.cpp similarity index 100% rename from Wallet.cpp rename to src/libwalletqt/Wallet.cpp diff --git a/Wallet.h b/src/libwalletqt/Wallet.h similarity index 100% rename from Wallet.h rename to src/libwalletqt/Wallet.h diff --git a/WalletManager.cpp b/src/libwalletqt/WalletManager.cpp similarity index 100% rename from WalletManager.cpp rename to src/libwalletqt/WalletManager.cpp diff --git a/WalletManager.h b/src/libwalletqt/WalletManager.h similarity index 100% rename from WalletManager.h rename to src/libwalletqt/WalletManager.h From da1b74a707da4e21a1c749c372ab9c8b1df1e5e1 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Tue, 7 Jun 2016 16:26:25 +0300 Subject: [PATCH 21/87] Start in normal mode if wallet exists. Resolves #9 --- main.cpp | 4 +- main.qml | 11 ++ src/libwalletqt/Wallet.cpp | 189 +++++------------------------- src/libwalletqt/Wallet.h | 34 ++++-- src/libwalletqt/WalletManager.cpp | 94 ++++++--------- src/libwalletqt/WalletManager.h | 33 ++++-- 6 files changed, 120 insertions(+), 245 deletions(-) diff --git a/main.cpp b/main.cpp index b486c5f0..6c529ed0 100644 --- a/main.cpp +++ b/main.cpp @@ -44,8 +44,8 @@ int main(int argc, char *argv[]) app.installEventFilter(eventFilter); qmlRegisterType<clipboardAdapter>("moneroComponents", 1, 0, "Clipboard"); - //qmlRegisterType<Wallet>("moneroWallet", 1, 0, "Wallet"); - qmlRegisterType<Wallet>(); + qmlRegisterInterface<Wallet>("Wallet"); + QQmlApplicationEngine engine; diff --git a/main.qml b/main.qml index c1a1d5ec..a36a3755 100644 --- a/main.qml +++ b/main.qml @@ -110,6 +110,15 @@ ApplicationWindow { } + function walletsFound() { + var wallets = walletManager.findWallets(moneroAccountsDir); + if (wallets.length === 0) { + wallets = walletManager.findWallets(applicationDirectory); + } + print(wallets); + return wallets.length > 0; + } + visible: true width: rightPanelExpanded ? 1269 : 1269 - 300 height: 800 @@ -120,6 +129,8 @@ ApplicationWindow { Component.onCompleted: { x = (Screen.width - width) / 2 y = (Screen.height - height) / 2 + // + rootItem.state = walletsFound() ? "normal" : "wizard"; } Item { diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 61998ab5..2ede062c 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -1,194 +1,61 @@ #include "Wallet.h" +#include "wallet/wallet2_api.h" + #include <QFile> #include <QDir> #include <QDebug> #include <QUrl> namespace { - QString TEST_SEED = "bound class paint gasp task soul forgot past pleasure physical circle " - " appear shore bathroom glove women crap busy beauty bliss idea give needle burden"; - namespace { - bool createFileWrapper(const QString &filename) - { - QFile file(filename); - // qDebug("%s: about to create file: %s", __FUNCTION__, qPrintable(filename)); - bool result = file.open(QIODevice::WriteOnly); - if (!result ){ - qWarning("%s: error creating file '%s' : '%s'", - __FUNCTION__, - qPrintable(filename), - qPrintable(file.errorString())); - } - return result; - } - } } -struct WalletImpl -{ - - QString basename() const; - void setBasename(const QString &name); - - QString keysName() const; - QString addressName() const; - -// Bitmonero::Wallet * m_walletImpl; - QString m_basename; - QString m_seed; - QString m_password; - QString m_language; - - static QString keysName(const QString &basename); - static QString addressName(const QString &basename); - -}; - - -QString WalletImpl::basename() const -{ - return m_basename; -} - -void WalletImpl::setBasename(const QString &name) -{ - m_basename = name; -} - -QString WalletImpl::keysName() const -{ - return keysName(m_basename); -} - -QString WalletImpl::addressName() const -{ - return addressName(m_basename); -} - -QString WalletImpl::keysName(const QString &basename) -{ - return basename + ".keys"; -} - -QString WalletImpl::addressName(const QString &basename) -{ - return basename + ".address.txt"; -} - - -Wallet::Wallet(QObject *parent) - : QObject(parent) -{ - -} QString Wallet::getSeed() const { - return m_pimpl->m_seed; + return QString::fromStdString(m_walletImpl->seed()); } QString Wallet::getSeedLanguage() const { - return "English"; + return QString::fromStdString(m_walletImpl->getSeedLanguage()); } -//void Wallet::setSeedLaguage(const QString &lang) -//{ -// // TODO: call libwallet's appropriate method -//} - -bool Wallet::setPassword(const QString &password) +int Wallet::status() const { - // set/change password implies: - // recovery wallet with existing path, seed and lang - qDebug("%s: recovering wallet with path=%s, seed=%s, lang=%s and new password=%s", - __FUNCTION__, - qPrintable(this->getBasename()), - qPrintable(this->getSeed()), - qPrintable(this->getSeedLanguage()), - qPrintable(password)); - return true; -} - -QString Wallet::getPassword() const -{ - return m_pimpl->m_password; -} - -bool Wallet::rename(const QString &name) -{ - - QString dst = QUrl(name).toLocalFile(); - - if (dst.isEmpty()) - dst = name; - - qDebug("%s: renaming '%s' to '%s'", - __FUNCTION__, - qPrintable(m_pimpl->basename()), - qPrintable(dst)); - - QString walletKeysFile = m_pimpl->keysName(); - QString walletAddressFile = m_pimpl->addressName(); - - QString dstWalletKeysFile = WalletImpl::keysName(dst); - QString dstWalletAddressFile = WalletImpl::addressName(dst); - - QFile walletFile(this->getBasename()); - - if (!walletFile.rename(dst)) { - qWarning("Error renaming file: '%s' to '%s' : (%s)", - qPrintable(m_pimpl->basename()), - qPrintable(dst), - qPrintable(walletFile.errorString())); - return false; - } - QFile::rename(walletKeysFile, dstWalletKeysFile); - QFile::rename(walletAddressFile, dstWalletAddressFile); - - bool result = QFile::exists(dst) && QFile::exists(dstWalletKeysFile) - && QFile::exists(dstWalletAddressFile); - - if (result) { - m_pimpl->m_basename = dst; - } - - return result; -} - -QString Wallet::getBasename() const -{ - return m_pimpl->basename(); -} - -int Wallet::error() const -{ - return 0; + return m_walletImpl->status(); } QString Wallet::errorString() const { - return m_pimpl->m_seed; + return QString::fromStdString(m_walletImpl->errorString()); } -Wallet::Wallet(const QString &path, const QString &password, const QString &language) +bool Wallet::setPassword(const QString &password) { - m_pimpl = new WalletImpl; - m_pimpl->m_basename = path; - m_pimpl->m_password = password; - m_pimpl->m_language = language; - m_pimpl->m_seed = TEST_SEED; + return m_walletImpl->setPassword(password.toStdString()); +} - // Create dummy files for testing - QFileInfo fi(path); - QDir tempDir; - tempDir.mkpath(fi.absolutePath()); - createFileWrapper(m_pimpl->basename()); - createFileWrapper(m_pimpl->keysName()); - createFileWrapper(m_pimpl->addressName()); +QString Wallet::address() const +{ + return QString::fromStdString(m_walletImpl->address()); +} + +bool Wallet::store(const QString &path) +{ + return m_walletImpl->store(path.toStdString()); } +Wallet::Wallet(Bitmonero::Wallet *w, QObject *parent) + : QObject(parent), m_walletImpl(w) +{ + +} + +Wallet::~Wallet() +{ + Bitmonero::WalletManagerFactory::getWalletManager()->closeWallet(m_walletImpl); +} diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index 221d3d43..79655cb4 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -3,13 +3,18 @@ #include <QObject> -struct WalletImpl; +namespace Bitmonero { + class Wallet; // forward declaration +} class Wallet : public QObject { Q_OBJECT Q_PROPERTY(QString seed READ getSeed) public: - explicit Wallet(QObject *parent = 0); + enum Status { + Status_Ok = 0, + Status_Error = 1 + }; //! returns mnemonic seed Q_INVOKABLE QString getSeed() const; @@ -17,28 +22,31 @@ public: //! returns seed language Q_INVOKABLE QString getSeedLanguage() const; + //! returns last operation's status + Q_INVOKABLE int status() const; + + //! returns last operation's error message + Q_INVOKABLE QString errorString() const; //! changes the password using existing parameters (path, seed, seed lang) Q_INVOKABLE bool setPassword(const QString &password); - //! returns curret wallet password - Q_INVOKABLE QString getPassword() const; - //! renames/moves wallet files - Q_INVOKABLE bool rename(const QString &name); + //! returns wallet's public address + Q_INVOKABLE QString address() const; + + //! saves wallet to the file by given path + Q_INVOKABLE bool store(const QString &path); - //! returns current wallet name (basename, as wallet consists of several files) - Q_INVOKABLE QString getBasename() const; - Q_INVOKABLE int error() const; - Q_INVOKABLE QString errorString() const; private: - Wallet(const QString &path, const QString &password, const QString &language); + Wallet(Bitmonero::Wallet *w, QObject * parent = 0); + ~Wallet(); private: friend class WalletManager; - //! pimpl wrapper for libwallet; - WalletImpl * m_pimpl; + //! libwallet's + Bitmonero::Wallet * m_walletImpl; }; #endif // WALLET_H diff --git a/src/libwalletqt/WalletManager.cpp b/src/libwalletqt/WalletManager.cpp index cb0ffbac..646e47f5 100644 --- a/src/libwalletqt/WalletManager.cpp +++ b/src/libwalletqt/WalletManager.cpp @@ -7,6 +7,8 @@ #include <QDebug> #include <QUrl> + + WalletManager * WalletManager::m_instance = nullptr; @@ -18,89 +20,55 @@ WalletManager *WalletManager::instance() if (!m_instance) { m_instance = new WalletManager; } - // Checking linkage (doesn't work, TODO: have every dependencies linked statically into libwallet) - Bitmonero::WalletManager * wallet_manager_impl = Bitmonero::WalletManagerFactory::getWalletManager(); return m_instance; } Wallet *WalletManager::createWallet(const QString &path, const QString &password, - const QString &language) + const QString &language, bool testnet) { - QFileInfo fi(path); - if (fi.exists()) { - qCritical("%s: already exists", __FUNCTION__); - // TODO: set error and error string - // return nullptr; - } - Wallet * wallet = new Wallet(path, password, language); + Bitmonero::Wallet * w = m_pimpl->createWallet(path.toStdString(), password.toStdString(), + language.toStdString(), testnet); + Wallet * wallet = new Wallet(w); return wallet; } -Wallet *WalletManager::openWallet(const QString &path, const QString &language, const QString &password) +Wallet *WalletManager::openWallet(const QString &path, const QString &password, bool testnet) { - QFileInfo fi(path); - if (fi.exists()) { - qCritical("%s: not exists", __FUNCTION__); - // TODO: set error and error string - // return nullptr; - } // TODO: call the libwallet api here; - Wallet * wallet = new Wallet(path, password, language); + Bitmonero::Wallet * w = m_pimpl->openWallet(path.toStdString(), password.toStdString(), testnet); + Wallet * wallet = new Wallet(w); return wallet; } -Wallet *WalletManager::recoveryWallet(const QString &path, const QString &memo, const QString &language) -{ - // TODO: call the libwallet api here; - return nullptr; +Wallet *WalletManager::recoveryWallet(const QString &path, const QString &memo, bool testnet) +{ + Bitmonero::Wallet * w = m_pimpl->recoveryWallet(path.toStdString(), memo.toStdString(), testnet); + Wallet * wallet = new Wallet(w); + return wallet; } -bool WalletManager::moveWallet(const QString &src, const QString &dst_) -{ - // TODO: move this to libwallet; - QFile walletFile(src); - if (!walletFile.exists()) { - qWarning("%s: source file [%s] doesn't exits", __FUNCTION__, - qPrintable(src)); - return false; - } - QString dst = QUrl(dst_).toLocalFile(); - QString walletKeysFile = src + ".keys"; - QString walletAddressFile = src + ".address.txt"; - - QString dstWalletKeysFile = dst + ".keys"; - QString dstWalletAddressFile = dst + ".address.txt"; - - if (!walletFile.rename(dst)) { - qWarning("Error renaming file: '%s' to '%s' : (%s)", - qPrintable(src), - qPrintable(dst), - qPrintable(walletFile.errorString())); - return false; - } - QFile::rename(walletKeysFile, dstWalletKeysFile); - QFile::rename(walletAddressFile, dstWalletAddressFile); - - return QFile::exists(dst) && QFile::exists(dstWalletKeysFile) - && QFile::exists(dstWalletAddressFile); -} void WalletManager::closeWallet(Wallet *wallet) { delete wallet; } -QString WalletManager::walletLanguage(const QString &locale) +bool WalletManager::walletExists(const QString &path) const { - return "English"; + return m_pimpl->walletExists(path.toStdString()); } -int WalletManager::error() const +QStringList WalletManager::findWallets(const QString &path) { - return 0; + std::vector<std::string> found_wallets = m_pimpl->findWallets(path.toStdString()); + QStringList result; + for (const auto &w : found_wallets) { + result.append(QString::fromStdString(w)); + } + return result; } QString WalletManager::errorString() const @@ -108,9 +76,21 @@ QString WalletManager::errorString() const return tr("Unknown error"); } -WalletManager::WalletManager(QObject *parent) : QObject(parent) +bool WalletManager::moveWallet(const QString &src, const QString &dst) { - + return true; +} + + +QString WalletManager::walletLanguage(const QString &locale) +{ + return "English"; +} + + +WalletManager::WalletManager(QObject *parent) : QObject(parent) +{ + m_pimpl = Bitmonero::WalletManagerFactory::getWalletManager(); } diff --git a/src/libwalletqt/WalletManager.h b/src/libwalletqt/WalletManager.h index 231f104c..c40fec54 100644 --- a/src/libwalletqt/WalletManager.h +++ b/src/libwalletqt/WalletManager.h @@ -4,6 +4,9 @@ #include <QObject> class Wallet; +namespace Bitmonero { + class WalletManager; +} class WalletManager : public QObject { @@ -12,37 +15,43 @@ public: static WalletManager * instance(); // wizard: createWallet path; Q_INVOKABLE Wallet * createWallet(const QString &path, const QString &password, - const QString &language); + const QString &language, bool testnet = false); // just for future use - Q_INVOKABLE Wallet * openWallet(const QString &path, const QString &language, - const QString &password); + Q_INVOKABLE Wallet * openWallet(const QString &path, const QString &password, bool testnet = false); // wizard: recoveryWallet path; hint: internally it recorvers wallet and set password = "" Q_INVOKABLE Wallet * recoveryWallet(const QString &path, const QString &memo, - const QString &language); - - // wizard: both "create" and "recovery" paths. - // TODO: probably move it to "Wallet" interface - Q_INVOKABLE bool moveWallet(const QString &src, const QString &dst); + bool testnet = false); //! utils: close wallet to free memory Q_INVOKABLE void closeWallet(Wallet * wallet); - //! returns libwallet language name for given locale - Q_INVOKABLE QString walletLanguage(const QString &locale); + //! checks is given filename is a wallet; + Q_INVOKABLE bool walletExists(const QString &path) const; - //! returns last error happened in WalletManager - Q_INVOKABLE int error() const; + //! returns list with wallet's filenames, if found by given path + Q_INVOKABLE QStringList findWallets(const QString &path); //! returns error description in human language Q_INVOKABLE QString errorString() const; + + + // wizard: both "create" and "recovery" paths. + // TODO: probably move it to "Wallet" interface + Q_INVOKABLE bool moveWallet(const QString &src, const QString &dst); + //! returns libwallet language name for given locale + Q_INVOKABLE QString walletLanguage(const QString &locale); + signals: public slots: private: + explicit WalletManager(QObject *parent = 0); static WalletManager * m_instance; + Bitmonero::WalletManager * m_pimpl; + }; #endif // WALLETMANAGER_H From 5c10be325103d668884fc5e463aaa59c726d4f8e Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 8 Jun 2016 13:53:24 +0300 Subject: [PATCH 22/87] Qt wrappers for libwallet API classes --- monero-core.pro | 10 +++- src/libwalletqt/PendingTransaction.cpp | 37 +++++++++++++++ src/libwalletqt/PendingTransaction.h | 41 ++++++++++++++++ src/libwalletqt/TransactionHistory.cpp | 50 +++++++++++++++++++ src/libwalletqt/TransactionHistory.h | 42 ++++++++++++++++ src/libwalletqt/TransactionInfo.cpp | 55 +++++++++++++++++++++ src/libwalletqt/TransactionInfo.h | 54 +++++++++++++++++++++ src/libwalletqt/Wallet.cpp | 66 ++++++++++++++++++++++++-- src/libwalletqt/Wallet.h | 63 +++++++++++++++++++++--- src/libwalletqt/WalletManager.cpp | 5 ++ src/libwalletqt/WalletManager.h | 3 ++ 11 files changed, 414 insertions(+), 12 deletions(-) create mode 100644 src/libwalletqt/PendingTransaction.cpp create mode 100644 src/libwalletqt/PendingTransaction.h create mode 100644 src/libwalletqt/TransactionHistory.cpp create mode 100644 src/libwalletqt/TransactionHistory.h create mode 100644 src/libwalletqt/TransactionInfo.cpp create mode 100644 src/libwalletqt/TransactionInfo.h diff --git a/monero-core.pro b/monero-core.pro index 7b05829f..f521c9ec 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -15,7 +15,10 @@ HEADERS += \ clipboardAdapter.h \ oscursor.h \ src/libwalletqt/WalletManager.h \ - src/libwalletqt/Wallet.h + src/libwalletqt/Wallet.h \ + src/libwalletqt/PendingTransaction.h \ + src/libwalletqt/TransactionHistory.h \ + src/libwalletqt/TransactionInfo.h SOURCES += main.cpp \ @@ -23,7 +26,10 @@ SOURCES += main.cpp \ clipboardAdapter.cpp \ oscursor.cpp \ src/libwalletqt/WalletManager.cpp \ - src/libwalletqt/Wallet.cpp + src/libwalletqt/Wallet.cpp \ + src/libwalletqt/PendingTransaction.cpp \ + src/libwalletqt/TransactionHistory.cpp \ + src/libwalletqt/TransactionInfo.cpp lupdate_only { SOURCES = *.qml \ diff --git a/src/libwalletqt/PendingTransaction.cpp b/src/libwalletqt/PendingTransaction.cpp new file mode 100644 index 00000000..a5dc458d --- /dev/null +++ b/src/libwalletqt/PendingTransaction.cpp @@ -0,0 +1,37 @@ +#include "PendingTransaction.h" + +PendingTransaction::Status PendingTransaction::status() const +{ + return static_cast<Status>(m_pimpl->status()); +} + +QString PendingTransaction::errorString() const +{ + return QString::fromStdString(m_pimpl->errorString()); +} + +bool PendingTransaction::commit() +{ + return m_pimpl->commit(); +} + +quint64 PendingTransaction::amount() const +{ + return m_pimpl->amount(); +} + +quint64 PendingTransaction::dust() const +{ + return m_pimpl->dust(); +} + +quint64 PendingTransaction::fee() const +{ + return m_pimpl->fee(); +} + +PendingTransaction::PendingTransaction(Bitmonero::PendingTransaction *pt, QObject *parent) + : QObject(parent), m_pimpl(pt) +{ + +} diff --git a/src/libwalletqt/PendingTransaction.h b/src/libwalletqt/PendingTransaction.h new file mode 100644 index 00000000..29fa7cb4 --- /dev/null +++ b/src/libwalletqt/PendingTransaction.h @@ -0,0 +1,41 @@ +#ifndef PENDINGTRANSACTION_H +#define PENDINGTRANSACTION_H + +#include <QObject> + +#include <wallet/wallet2_api.h> + +//namespace Bitmonero { +//class PendingTransaction; +//} + +class PendingTransaction : public QObject +{ + Q_OBJECT + Q_PROPERTY(Status status READ status) + Q_PROPERTY(QString errorString READ errorString) + Q_PROPERTY(quint64 amount READ amount) + Q_PROPERTY(quint64 dust READ dust) + Q_PROPERTY(quint64 fee READ fee) + +public: + enum Status { + Status_Ok = Bitmonero::PendingTransaction::Status_Ok, + Status_Error = Bitmonero::PendingTransaction::Status_Error + }; + + Status status() const; + QString errorString() const; + Q_INVOKABLE bool commit(); + quint64 amount() const; + quint64 dust() const; + quint64 fee() const; +private: + explicit PendingTransaction(Bitmonero::PendingTransaction * pt, QObject *parent = 0); + +private: + friend class Wallet; + Bitmonero::PendingTransaction * m_pimpl; +}; + +#endif // PENDINGTRANSACTION_H diff --git a/src/libwalletqt/TransactionHistory.cpp b/src/libwalletqt/TransactionHistory.cpp new file mode 100644 index 00000000..2c2c9f73 --- /dev/null +++ b/src/libwalletqt/TransactionHistory.cpp @@ -0,0 +1,50 @@ +#include "TransactionHistory.h" +#include "TransactionInfo.h" +#include <wallet/wallet2_api.h> + + +int TransactionHistory::count() const +{ + return m_pimpl->count(); +} + +TransactionInfo *TransactionHistory::transaction(int index) +{ + // box up Bitmonero::TransactionInfo + Bitmonero::TransactionInfo * impl = m_pimpl->transaction(index); + TransactionInfo * result = new TransactionInfo(impl, this); + return result; +} + +TransactionInfo *TransactionHistory::transaction(const QString &id) +{ + // box up Bitmonero::TransactionInfo + Bitmonero::TransactionInfo * impl = m_pimpl->transaction(id.toStdString()); + TransactionInfo * result = new TransactionInfo(impl, this); + return result; +} + +QList<TransactionInfo *> TransactionHistory::getAll() const +{ + qDeleteAll(m_tinfo); + m_tinfo.clear(); + TransactionHistory * parent = const_cast<TransactionHistory*>(this); + for (const auto i : m_pimpl->getAll()) { + TransactionInfo * ti = new TransactionInfo(i, parent); + m_tinfo.append(ti); + } + return m_tinfo; +} + +void TransactionHistory::refresh() +{ + // XXX this invalidates previously saved history that might be used by clients + m_pimpl->refresh(); + emit invalidated(); +} + +TransactionHistory::TransactionHistory(Bitmonero::TransactionHistory *pimpl, QObject *parent) + : QObject(parent), m_pimpl(pimpl) +{ + +} diff --git a/src/libwalletqt/TransactionHistory.h b/src/libwalletqt/TransactionHistory.h new file mode 100644 index 00000000..a6287506 --- /dev/null +++ b/src/libwalletqt/TransactionHistory.h @@ -0,0 +1,42 @@ +#ifndef TRANSACTIONHISTORY_H +#define TRANSACTIONHISTORY_H + +#include <QObject> +#include <QList> + +namespace Bitmonero { +class TransactionHistory; +} + +class TransactionInfo; + +class TransactionHistory : public QObject +{ + Q_OBJECT + Q_PROPERTY(int count READ count) + +public: + int count() const; + Q_INVOKABLE TransactionInfo *transaction(int index); + Q_INVOKABLE TransactionInfo * transaction(const QString &id); + Q_INVOKABLE QList<TransactionInfo*> getAll() const; + Q_INVOKABLE void refresh(); + +signals: + void invalidated(); + +public slots: + + +private: + explicit TransactionHistory(Bitmonero::TransactionHistory * pimpl, QObject *parent = 0); + +private: + friend class Wallet; + + Bitmonero::TransactionHistory * m_pimpl; + mutable QList<TransactionInfo*> m_tinfo; + +}; + +#endif // TRANSACTIONHISTORY_H diff --git a/src/libwalletqt/TransactionInfo.cpp b/src/libwalletqt/TransactionInfo.cpp new file mode 100644 index 00000000..192e85e5 --- /dev/null +++ b/src/libwalletqt/TransactionInfo.cpp @@ -0,0 +1,55 @@ +#include "TransactionInfo.h" +#include <QDateTime> + +TransactionInfo::Direction TransactionInfo::direction() const +{ + return static_cast<Direction>(m_pimpl->direction()); +} + +bool TransactionInfo::isPending() const +{ + return m_pimpl->isPending(); +} + +bool TransactionInfo::isFailed() const +{ + return m_pimpl->isFailed(); +} + +quint64 TransactionInfo::amount() const +{ + return m_pimpl->amount(); +} + +quint64 TransactionInfo::fee() const +{ + return m_pimpl->fee(); + +} + +quint64 TransactionInfo::blockHeight() const +{ + return m_pimpl->blockHeight(); +} + +QString TransactionInfo::hash() const +{ + return QString::fromStdString(m_pimpl->hash()); +} + +QString TransactionInfo::timestamp() +{ + QString result = QDateTime::fromTime_t(m_pimpl->timestamp()).toString(Qt::ISODate); + return result; +} + +QString TransactionInfo::paymentId() +{ + return QString::fromStdString(m_pimpl->paymentId()); +} + +TransactionInfo::TransactionInfo(Bitmonero::TransactionInfo *pimpl, QObject *parent) + : QObject(parent), m_pimpl(pimpl) +{ + +} diff --git a/src/libwalletqt/TransactionInfo.h b/src/libwalletqt/TransactionInfo.h new file mode 100644 index 00000000..62c26e2f --- /dev/null +++ b/src/libwalletqt/TransactionInfo.h @@ -0,0 +1,54 @@ +#ifndef TRANSACTIONINFO_H +#define TRANSACTIONINFO_H + +#include <QObject> +#include <wallet/wallet2_api.h> + +class TransactionInfo : public QObject +{ + Q_OBJECT + Q_PROPERTY(Direction direction READ direction) + Q_PROPERTY(bool isPending READ isPending) + Q_PROPERTY(bool isFailed READ isFailed) + Q_PROPERTY(quint64 amount READ amount) + Q_PROPERTY(quint64 fee READ fee) + Q_PROPERTY(quint64 blockHeight READ blockHeight) + Q_PROPERTY(QString hash READ hash) + Q_PROPERTY(QString timestamp READ timestamp) + Q_PROPERTY(QString paymentId READ paymentId) + +public: + enum Direction { + Direction_In = Bitmonero::TransactionInfo::Direction_In, + Direction_Out = Bitmonero::TransactionInfo::Direction_Out + }; + +// TODO: implement as separate class; + +// struct Transfer { +// Transfer(uint64_t _amount, const std::string &address); +// const uint64_t amount; +// const std::string address; +// }; + Direction direction() const; + bool isPending() const; + bool isFailed() const; + quint64 amount() const; + quint64 fee() const; + quint64 blockHeight() const; + //! transaction_id + QString hash() const; + QString timestamp(); + QString paymentId(); + + // TODO: implement it + //! only applicable for output transactions + // virtual const std::vector<Transfer> & transfers() const = 0; +private: + explicit TransactionInfo(Bitmonero::TransactionInfo * pimpl, QObject *parent = 0); +private: + friend class TransactionHistory; + Bitmonero::TransactionInfo * m_pimpl; +}; + +#endif // TRANSACTIONINFO_H diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 2ede062c..77901b0c 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -1,4 +1,6 @@ #include "Wallet.h" +#include "PendingTransaction.h" +#include "TransactionHistory.h" #include "wallet/wallet2_api.h" #include <QFile> @@ -22,9 +24,14 @@ QString Wallet::getSeedLanguage() const return QString::fromStdString(m_walletImpl->getSeedLanguage()); } -int Wallet::status() const +void Wallet::setSeedLanguage(const QString &lang) { - return m_walletImpl->status(); + m_walletImpl->setSeedLanguage(lang.toStdString()); +} + +Wallet::Status Wallet::status() const +{ + return static_cast<Status>(m_walletImpl->status()); } QString Wallet::errorString() const @@ -47,10 +54,63 @@ bool Wallet::store(const QString &path) return m_walletImpl->store(path.toStdString()); } +bool Wallet::init(const QString &daemonAddress, quint64 upperTransactionLimit) +{ + return m_walletImpl->init(daemonAddress.toStdString(), upperTransactionLimit); +} + +bool Wallet::connectToDaemon() +{ + return m_walletImpl->connectToDaemon(); +} + +void Wallet::setTrustedDaemon(bool arg) +{ + m_walletImpl->setTrustedDaemon(arg); +} + +quint64 Wallet::balance() const +{ + return m_walletImpl->balance(); +} + +quint64 Wallet::unlockedBalance() const +{ + return m_walletImpl->unlockedBalance(); +} + +bool Wallet::refresh() +{ + return m_walletImpl->refresh(); +} + +PendingTransaction *Wallet::createTransaction(const QString &dst_addr, quint64 amount) +{ + Bitmonero::PendingTransaction * ptImpl = m_walletImpl->createTransaction( + dst_addr.toStdString(), amount); + PendingTransaction * result = new PendingTransaction(ptImpl, this); + return result; +} + +void Wallet::disposeTransaction(PendingTransaction *t) +{ + m_walletImpl->disposeTransaction(t->m_pimpl); + delete t; +} + +TransactionHistory *Wallet::history() +{ + if (!m_history) { + Bitmonero::TransactionHistory * impl = m_walletImpl->history(); + m_history = new TransactionHistory(impl, this); + } + return m_history; +} + Wallet::Wallet(Bitmonero::Wallet *w, QObject *parent) - : QObject(parent), m_walletImpl(w) + : QObject(parent), m_walletImpl(w), m_history(nullptr) { } diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index 79655cb4..7d391429 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -3,41 +3,88 @@ #include <QObject> +#include "wallet/wallet2_api.h" // we need to access Status enum here; + namespace Bitmonero { class Wallet; // forward declaration } + +class PendingTransaction; +class TransactionHistory; + class Wallet : public QObject { Q_OBJECT Q_PROPERTY(QString seed READ getSeed) + Q_PROPERTY(QString seedLanguage READ getSeedLanguage) + Q_PROPERTY(Status status READ status) + Q_PROPERTY(QString errorString READ errorString) + Q_PROPERTY(QString address READ address) + Q_PROPERTY(quint64 balance READ balance) + Q_PROPERTY(quint64 unlockedBalance READ unlockedBalance) + Q_PROPERTY(TransactionHistory * history READ history) + public: enum Status { - Status_Ok = 0, - Status_Error = 1 + Status_Ok = Bitmonero::Wallet::Status_Ok, + Status_Error = Bitmonero::Wallet::Status_Error }; + Q_ENUM(Status) + //! returns mnemonic seed - Q_INVOKABLE QString getSeed() const; + QString getSeed() const; //! returns seed language - Q_INVOKABLE QString getSeedLanguage() const; + QString getSeedLanguage() const; + + //! set seed language + Q_INVOKABLE void setSeedLanguage(const QString &lang); //! returns last operation's status - Q_INVOKABLE int status() const; + Status status() const; //! returns last operation's error message - Q_INVOKABLE QString errorString() const; + QString errorString() const; //! changes the password using existing parameters (path, seed, seed lang) Q_INVOKABLE bool setPassword(const QString &password); //! returns wallet's public address - Q_INVOKABLE QString address() const; + QString address() const; //! saves wallet to the file by given path Q_INVOKABLE bool store(const QString &path); + //! initializes wallet + Q_INVOKABLE bool init(const QString &daemonAddress, quint64 upperTransactionLimit); + //! connects to daemon + Q_INVOKABLE bool connectToDaemon(); + + //! indicates id daemon is trusted + Q_INVOKABLE void setTrustedDaemon(bool arg); + + //! returns balance + quint64 balance() const; + + //! returns unlocked balance + quint64 unlockedBalance() const; + + //! refreshes the wallet + Q_INVOKABLE bool refresh(); + + //! creates transaction + Q_INVOKABLE PendingTransaction * createTransaction(const QString &dst_addr, + quint64 amount); + + //! deletes transaction and frees memory + Q_INVOKABLE void disposeTransaction(PendingTransaction * t); + + //! returns transaction history + TransactionHistory * history(); + + // TODO: setListenter() when it implemented in API private: Wallet(Bitmonero::Wallet *w, QObject * parent = 0); @@ -47,6 +94,8 @@ private: friend class WalletManager; //! libwallet's Bitmonero::Wallet * m_walletImpl; + // history lifetime managed by wallet; + TransactionHistory * m_history; }; #endif // WALLET_H diff --git a/src/libwalletqt/WalletManager.cpp b/src/libwalletqt/WalletManager.cpp index 646e47f5..6ad81e2a 100644 --- a/src/libwalletqt/WalletManager.cpp +++ b/src/libwalletqt/WalletManager.cpp @@ -87,6 +87,11 @@ QString WalletManager::walletLanguage(const QString &locale) return "English"; } +QString WalletManager::displayAmount(quint64 amount) +{ + return QString::fromStdString(Bitmonero::Wallet::displayAmount(amount)); +} + WalletManager::WalletManager(QObject *parent) : QObject(parent) { diff --git a/src/libwalletqt/WalletManager.h b/src/libwalletqt/WalletManager.h index c40fec54..30e6b02a 100644 --- a/src/libwalletqt/WalletManager.h +++ b/src/libwalletqt/WalletManager.h @@ -42,6 +42,9 @@ public: //! returns libwallet language name for given locale Q_INVOKABLE QString walletLanguage(const QString &locale); + + //! since we can't call static method from QML, move it to this class + Q_INVOKABLE QString displayAmount(quint64 amount); signals: public slots: From fd50e6f9a3bc445cb3c0d21b7a0f584e95b44450 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Fri, 10 Jun 2016 16:41:13 +0300 Subject: [PATCH 23/87] new wallet wizard: wallet created in temporary directory and moved to the destination at the final step --- get_libwallet_api.sh | 3 +++ lang/languages.xml | 20 ++++++++++---------- main.cpp | 6 ++++++ monero-core.pro | 6 ++++-- oshelper.cpp | 24 ++++++++++++++++++++++++ oshelper.h | 22 ++++++++++++++++++++++ wizard/WizardCreateWallet.qml | 25 ++++++++++++++++++++----- wizard/WizardDonation.qml | 2 +- wizard/WizardMain.qml | 7 +++---- wizard/WizardManageWalletUI.qml | 2 +- wizard/WizardPassword.qml | 2 +- wizard/WizardRecoveryWallet.qml | 2 +- wizard/WizardWelcome.qml | 13 +++++++++---- 13 files changed, 105 insertions(+), 29 deletions(-) create mode 100644 oshelper.cpp create mode 100644 oshelper.h diff --git a/get_libwallet_api.sh b/get_libwallet_api.sh index 34c2e6b3..c9f67ff8 100755 --- a/get_libwallet_api.sh +++ b/get_libwallet_api.sh @@ -13,6 +13,9 @@ BITMONERO_DIR=$ROOT_DIR/bitmonero if [ ! -d $BITMONERO_DIR ]; then git clone --depth=1 $BITMONERO_URL $BITMONERO_DIR +else + cd $BITMONERO_DIR; + git pull; fi rm -fr $BITMONERO_DIR/build diff --git a/lang/languages.xml b/lang/languages.xml index efb84c9c..449d415c 100644 --- a/lang/languages.xml +++ b/lang/languages.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8"?> <languages> - <language name="US English" locale="en_US" flag="/lang/flags/usa.png" qs="none"/> - <language name="UK English" locale="en_GB" flag="/lang/flags/uk.png" qs="none"/> - <language name="Russia" locale="ru_RU" flag="/lang/flags/russia.png" qs="none"/> - <language name="RPA" locale="TODO" flag="/lang/flags/rpa.png" qs="none"/> - <language name="Palestine" locale="TODO" flag="/lang/flags/palestine.png" qs="none"/> - <language name="India" locale="hi_IN" flag="/lang/flags/india.png" qs="none"/> - <language name="German" locale="de_DE" flag="/lang/flags/german.png" qs="none"/> - <language name="China" locale="zh_CN" flag="/lang/flags/china.png" qs="none"/> - <language name="Brazil" locale="pt_BR" flag="/lang/flags/brazil.png" qs="none"/> - <language name="Bangladesh" locale="TODO" flag="/lang/flags/bangladesh.png" qs="none"/> + <language display_name="US English" locale="en_US" wallet_name="English" flag="/lang/flags/usa.png" qs="none"/> + <language display_name="UK English" locale="en_GB" wallet_name="English" flag="/lang/flags/uk.png" qs="none"/> + <language display_name="Russia" locale="ru_RU" wallet_name="English" flag="/lang/flags/russia.png" qs="none"/> + <language display_name="RPA" locale="TODO" wallet_name="English" flag="/lang/flags/rpa.png" qs="none"/> + <language display_name="Palestine" locale="TODO" wallet_name="English" flag="/lang/flags/palestine.png" qs="none"/> + <language display_name="India" locale="hi_IN" wallet_name="English" flag="/lang/flags/india.png" qs="none"/> + <language display_name="German" locale="de_DE" wallet_name="English" flag="/lang/flags/german.png" qs="none"/> + <language display_name="China" locale="zh_CN" wallet_name="English" flag="/lang/flags/china.png" qs="none"/> + <language display_name="Brazil" locale="pt_BR" wallet_name="English" flag="/lang/flags/brazil.png" qs="none"/> + <language display_name="Bangladesh" locale="TODO" wallet_name="English" flag="/lang/flags/bangladesh.png" qs="none"/> </languages> diff --git a/main.cpp b/main.cpp index 6c529ed0..39e4635d 100644 --- a/main.cpp +++ b/main.cpp @@ -33,10 +33,13 @@ #include "clipboardAdapter.h" #include "filter.h" #include "oscursor.h" +#include "oshelper.h" #include "WalletManager.h" #include "Wallet.h" + + int main(int argc, char *argv[]) { QApplication app(argc, argv); @@ -51,6 +54,9 @@ int main(int argc, char *argv[]) OSCursor cursor; engine.rootContext()->setContextProperty("globalCursor", &cursor); + OSHelper osHelper; + engine.rootContext()->setContextProperty("oshelper", &osHelper); + engine.rootContext()->setContextProperty("walletManager", WalletManager::instance()); // export to QML monero accounts root directory diff --git a/monero-core.pro b/monero-core.pro index f521c9ec..8ce4a16a 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -18,7 +18,8 @@ HEADERS += \ src/libwalletqt/Wallet.h \ src/libwalletqt/PendingTransaction.h \ src/libwalletqt/TransactionHistory.h \ - src/libwalletqt/TransactionInfo.h + src/libwalletqt/TransactionInfo.h \ + oshelper.h SOURCES += main.cpp \ @@ -29,7 +30,8 @@ SOURCES += main.cpp \ src/libwalletqt/Wallet.cpp \ src/libwalletqt/PendingTransaction.cpp \ src/libwalletqt/TransactionHistory.cpp \ - src/libwalletqt/TransactionInfo.cpp + src/libwalletqt/TransactionInfo.cpp \ + oshelper.cpp lupdate_only { SOURCES = *.qml \ diff --git a/oshelper.cpp b/oshelper.cpp new file mode 100644 index 00000000..cecae38e --- /dev/null +++ b/oshelper.cpp @@ -0,0 +1,24 @@ +#include "oshelper.h" +#include <QTemporaryFile> +#include <QDir> + +OSHelper::OSHelper(QObject *parent) : QObject(parent) +{ + +} + +QString OSHelper::temporaryFilename() const +{ + QString tempFileName; + { + QTemporaryFile f; + f.open(); + tempFileName = f.fileName(); + } + return tempFileName; +} + +QString OSHelper::temporaryPath() const +{ + return QDir::tempPath(); +} diff --git a/oshelper.h b/oshelper.h new file mode 100644 index 00000000..809058cb --- /dev/null +++ b/oshelper.h @@ -0,0 +1,22 @@ +#ifndef OSHELPER_H +#define OSHELPER_H + +#include <QObject> +/** + * @brief The OSHelper class - exports to QML some OS-related functions + */ +class OSHelper : public QObject +{ + Q_OBJECT +public: + explicit OSHelper(QObject *parent = 0); + + Q_INVOKABLE QString temporaryFilename() const; + Q_INVOKABLE QString temporaryPath() const; + +signals: + +public slots: +}; + +#endif // OSHELPER_H diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml index 346627dc..653db251 100644 --- a/wizard/WizardCreateWallet.qml +++ b/wizard/WizardCreateWallet.qml @@ -40,18 +40,23 @@ Item { onOpacityChanged: visible = opacity !== 0 - function saveSettings(settingsObject) { + //! function called each time we display this page + + function onPageClosed(settingsObject) { settingsObject['account_name'] = uiItem.accountNameText settingsObject['words'] = uiItem.wordsTexttext settingsObject['wallet_path'] = uiItem.walletPath + // put wallet files to the subdirectory with the same name as + // wallet name var new_wallet_filename = settingsObject.wallet_path + "/" + + settingsObject.account_name + "/" + settingsObject.account_name; // moving wallet files to the new destination, if user changed it if (new_wallet_filename !== settingsObject.wallet_filename) { // using previously saved wallet; - settingsObject.wallet.rename(new_wallet_filename); + settingsObject.wallet.store(new_wallet_filename); //walletManager.moveWallet(settingsObject.wallet_filename, new_wallet_filename); } @@ -59,10 +64,18 @@ Item { settingsObject['wallet_filename'] = new_wallet_filename; } + //! function called each time we hide this page + // + + function createWallet(settingsObject) { - var wallet_filename = uiItem.walletPath + "/" + uiItem.accountNameText + // TODO: create wallet in temporary filename and a) move it to the path specified by user after the final + // page submitted or b) delete it when program closed before reaching final page + + var wallet_filename = oshelper.temporaryFilename(); if (typeof settingsObject.wallet === 'undefined') { - var wallet = walletManager.createWallet(wallet_filename, "", settingsObject.locale) + //var wallet = walletManager.createWallet(wallet_filename, "", settingsObject.language) + var wallet = walletManager.createWallet(wallet_filename, "", settingsObject.wallet_language) 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 @@ -70,10 +83,12 @@ Item { } else { print("wallet already created. we just stepping back"); } - settingsObject.wallet_filename = wallet_filename } + + + WizardManageWalletUI { id: uiItem titleText: qsTr("A new wallet has been created for you") diff --git a/wizard/WizardDonation.qml b/wizard/WizardDonation.qml index d42c266e..51a28029 100644 --- a/wizard/WizardDonation.qml +++ b/wizard/WizardDonation.qml @@ -38,7 +38,7 @@ Item { onOpacityChanged: visible = opacity !== 0 - function saveSettings(settingsObject) { + function onPageClosed(settingsObject) { settingsObject['auto_donations_enabled'] = enableAutoDonationCheckBox.checked; settingsObject['auto_donations_amount'] = autoDonationAmountText.text; settingsObject['allow_background_mining'] = allowBackgroundMiningCheckBox.checked; diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index 51e0baf3..a19c622c 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -49,8 +49,8 @@ Rectangle { function switchPage(next) { // save settings for current page; - if (typeof pages[currentPage].saveSettings !== 'undefined') { - pages[currentPage].saveSettings(settings); + if (typeof pages[currentPage].onPageClosed !== 'undefined') { + pages[currentPage].onPageClosed(settings); } print ("switchpage: start: currentPage: ", currentPage); @@ -61,7 +61,6 @@ Rectangle { pages[currentPage].opacity = 1; handlePageChanged(); } - } function handlePageChanged() { @@ -91,9 +90,9 @@ Rectangle { nextButton.enabled = true } - } + function openCreateWalletPage() { print ("show create wallet page"); pages[currentPage].opacity = 0; diff --git a/wizard/WizardManageWalletUI.qml b/wizard/WizardManageWalletUI.qml index ce035f0a..58f4e59a 100644 --- a/wizard/WizardManageWalletUI.qml +++ b/wizard/WizardManageWalletUI.qml @@ -206,7 +206,7 @@ Item { verticalAlignment: Text.AlignVCenter selectByMouse: true - text: moneroAccountsDir + "/My Wallet" + text: moneroAccountsDir + "/" onFocusChanged: { if(focus) { fileDialog.folder = text diff --git a/wizard/WizardPassword.qml b/wizard/WizardPassword.qml index 1bcc6213..aca45d4d 100644 --- a/wizard/WizardPassword.qml +++ b/wizard/WizardPassword.qml @@ -43,7 +43,7 @@ Item { onOpacityChanged: visible = opacity !== 0 - function saveSettings(settingsObject) { + function onPageClosed(settingsObject) { settingsObject.wallet.setPassword(passwordItem.password) } diff --git a/wizard/WizardRecoveryWallet.qml b/wizard/WizardRecoveryWallet.qml index 572d776b..e7fd6c0d 100644 --- a/wizard/WizardRecoveryWallet.qml +++ b/wizard/WizardRecoveryWallet.qml @@ -40,7 +40,7 @@ Item { onOpacityChanged: visible = opacity !== 0 - function saveSettings(settingsObject) { + function onPageClosed(settingsObject) { settingsObject['account_name'] = uiItem.accountNameText settingsObject['words'] = uiItem.wordsTexttext settingsObject['wallet_path'] = uiItem.walletPath diff --git a/wizard/WizardWelcome.qml b/wizard/WizardWelcome.qml index 208a7994..bdd88b70 100644 --- a/wizard/WizardWelcome.qml +++ b/wizard/WizardWelcome.qml @@ -36,8 +36,11 @@ Item { onOpacityChanged: visible = opacity !== 0 - function saveSettings(settingsObject) { - settingsObject['language'] = languagesModel.get(gridView.currentIndex).name + function onPageClosed(settingsObject) { + var lang = languagesModel.get(gridView.currentIndex); + settingsObject['language'] = lang.display_name; + settingsObject['wallet_language'] = lang.wallet_name; + settingsObject['locale'] = lang.locale; } Column { @@ -78,7 +81,9 @@ Item { source: "/lang/languages.xml" query: "/languages/language" - XmlRole { name: "name"; query: "@name/string()" } + XmlRole { name: "display_name"; query: "@display_name/string()" } + XmlRole { name: "locale"; query: "@locale/string()" } + XmlRole { name: "wallet_name"; query: "@wallet_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 @@ -126,7 +131,7 @@ Item { font.bold: gridView.currentIndex === index elide: Text.ElideRight color: "#3F3F3F" - text: name + text: display_name } MouseArea { id: delegateArea From b7787dc6704ee8395ba20adf0f09af6fc3eb9f8a Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Tue, 14 Jun 2016 12:40:29 +0300 Subject: [PATCH 24/87] Moving wallet to the user defined location at the "donation" page (pre- final) --- wizard/WizardCreateWallet.qml | 12 ------------ wizard/WizardDonation.qml | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml index 653db251..2332dd5c 100644 --- a/wizard/WizardCreateWallet.qml +++ b/wizard/WizardCreateWallet.qml @@ -49,19 +49,7 @@ Item { // put wallet files to the subdirectory with the same name as // wallet name - var new_wallet_filename = settingsObject.wallet_path + "/" - + settingsObject.account_name + "/" - + settingsObject.account_name; - // moving wallet files to the new destination, if user changed it - if (new_wallet_filename !== settingsObject.wallet_filename) { - // using previously saved wallet; - settingsObject.wallet.store(new_wallet_filename); - //walletManager.moveWallet(settingsObject.wallet_filename, new_wallet_filename); - } - - // saving wallet_filename; - settingsObject['wallet_filename'] = new_wallet_filename; } //! function called each time we hide this page diff --git a/wizard/WizardDonation.qml b/wizard/WizardDonation.qml index 51a28029..8cfc68f2 100644 --- a/wizard/WizardDonation.qml +++ b/wizard/WizardDonation.qml @@ -42,6 +42,23 @@ Item { settingsObject['auto_donations_enabled'] = enableAutoDonationCheckBox.checked; settingsObject['auto_donations_amount'] = autoDonationAmountText.text; settingsObject['allow_background_mining'] = allowBackgroundMiningCheckBox.checked; + + // here we need to actually move wallet to the new location + // put wallet files to the subdirectory with the same name as + // wallet name + var new_wallet_filename = settingsObject.wallet_path + "/" + + settingsObject.account_name + "/" + + settingsObject.account_name; + + // moving wallet files to the new destination, if user changed it + if (new_wallet_filename !== settingsObject.wallet_filename) { + // using previously saved wallet; + settingsObject.wallet.store(new_wallet_filename); + //walletManager.moveWallet(settingsObject.wallet_filename, new_wallet_filename); + } + + // saving wallet_filename; + settingsObject['wallet_filename'] = new_wallet_filename; } Row { From 1eac46ae734d31df568cf0f51dd1d5b7e7244cdc Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Tue, 14 Jun 2016 16:09:14 +0300 Subject: [PATCH 25/87] "new wallet" and "recovery wallet" flows are implemented using libwallet api --- main.cpp | 2 +- wizard/WizardCreateWallet.qml | 5 +---- wizard/WizardDonation.qml | 15 +------------ wizard/WizardFinish.qml | 2 ++ wizard/WizardMain.qml | 40 +++++++++++++++++++++++++++++---- wizard/WizardPassword.qml | 1 + wizard/WizardRecoveryWallet.qml | 22 ++++++++++++++---- wizard/WizardWelcome.qml | 1 + 8 files changed, 61 insertions(+), 27 deletions(-) diff --git a/main.cpp b/main.cpp index 39e4635d..a4a79947 100644 --- a/main.cpp +++ b/main.cpp @@ -47,7 +47,7 @@ int main(int argc, char *argv[]) app.installEventFilter(eventFilter); qmlRegisterType<clipboardAdapter>("moneroComponents", 1, 0, "Clipboard"); - qmlRegisterInterface<Wallet>("Wallet"); + qmlRegisterUncreatableType<Wallet>("Bitmonero.Wallet", 1, 0, "Wallet", "Wallet can't be instantiated directly"); QQmlApplicationEngine engine; diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml index 2332dd5c..0aad0052 100644 --- a/wizard/WizardCreateWallet.qml +++ b/wizard/WizardCreateWallet.qml @@ -46,10 +46,7 @@ Item { settingsObject['account_name'] = uiItem.accountNameText settingsObject['words'] = uiItem.wordsTexttext settingsObject['wallet_path'] = uiItem.walletPath - - // put wallet files to the subdirectory with the same name as - // wallet name - + return true; } //! function called each time we hide this page diff --git a/wizard/WizardDonation.qml b/wizard/WizardDonation.qml index 8cfc68f2..e0b73df8 100644 --- a/wizard/WizardDonation.qml +++ b/wizard/WizardDonation.qml @@ -43,22 +43,9 @@ Item { settingsObject['auto_donations_amount'] = autoDonationAmountText.text; settingsObject['allow_background_mining'] = allowBackgroundMiningCheckBox.checked; - // here we need to actually move wallet to the new location - // put wallet files to the subdirectory with the same name as - // wallet name - var new_wallet_filename = settingsObject.wallet_path + "/" - + settingsObject.account_name + "/" - + settingsObject.account_name; - // moving wallet files to the new destination, if user changed it - if (new_wallet_filename !== settingsObject.wallet_filename) { - // using previously saved wallet; - settingsObject.wallet.store(new_wallet_filename); - //walletManager.moveWallet(settingsObject.wallet_filename, new_wallet_filename); - } - // saving wallet_filename; - settingsObject['wallet_filename'] = new_wallet_filename; + return true; } Row { diff --git a/wizard/WizardFinish.qml b/wizard/WizardFinish.qml index 311dfd62..427a2340 100644 --- a/wizard/WizardFinish.qml +++ b/wizard/WizardFinish.qml @@ -53,6 +53,8 @@ Item { + buildSettingsString(); } + + Row { id: dotsRow anchors.top: parent.top diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index a19c622c..da3a9824 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -49,8 +49,12 @@ Rectangle { function switchPage(next) { // save settings for current page; - if (typeof pages[currentPage].onPageClosed !== 'undefined') { - pages[currentPage].onPageClosed(settings); + if (next && typeof pages[currentPage].onPageClosed !== 'undefined') { + if (pages[currentPage].onPageClosed(settings) !== true) { + print ("Can't go to the next page"); + return; + }; + } print ("switchpage: start: currentPage: ", currentPage); @@ -59,6 +63,10 @@ Rectangle { var step_value = next ? 1 : -1 currentPage += step_value pages[currentPage].opacity = 1; + + if (next && typeof pages[currentPage].onPageOpened !== 'undefined') { + pages[currentPage].onPageOpened(settings) + } handlePageChanged(); } } @@ -84,7 +92,7 @@ Rectangle { break; case recoveryWalletPage: // TODO: disable "next button" until 25 words private key entered - // nextButton.enabled = false; + nextButton.enabled = false break default: nextButton.enabled = true @@ -115,6 +123,27 @@ Rectangle { handlePageChanged() } + //! actually writes the wallet + function applySettings() { + print ("Here we apply the settings"); + // here we need to actually move wallet to the new location + // put wallet files to the subdirectory with the same name as + // wallet name + var new_wallet_filename = settings.wallet_path + "/" + + settings.account_name + "/" + + settings.account_name; + + // moving wallet files to the new destination, if user changed it + if (new_wallet_filename !== settings.wallet_filename) { + // using previously saved wallet; + settings.wallet.store(new_wallet_filename); + //walletManager.moveWallet(settingsObject.wallet_filename, new_wallet_filename); + } + + // saving wallet_filename; + settings['wallet_filename'] = new_wallet_filename; + } + @@ -255,6 +284,9 @@ Rectangle { releasedColor: "#FF6C3C" pressedColor: "#FF4304" visible: parent.paths[currentPath][currentPage] === finishPage - onClicked: wizard.useMoneroClicked() + onClicked: { + wizard.applySettings(); + wizard.useMoneroClicked() + } } } diff --git a/wizard/WizardPassword.qml b/wizard/WizardPassword.qml index aca45d4d..6b14dae9 100644 --- a/wizard/WizardPassword.qml +++ b/wizard/WizardPassword.qml @@ -45,6 +45,7 @@ Item { function onPageClosed(settingsObject) { settingsObject.wallet.setPassword(passwordItem.password) + return true } function handlePassword() { diff --git a/wizard/WizardRecoveryWallet.qml b/wizard/WizardRecoveryWallet.qml index e7fd6c0d..19530157 100644 --- a/wizard/WizardRecoveryWallet.qml +++ b/wizard/WizardRecoveryWallet.qml @@ -29,6 +29,7 @@ import QtQuick 2.2 import moneroComponents 1.0 import QtQuick.Dialogs 1.2 +import Bitmonero.Wallet 1.0 Item { opacity: 0 @@ -42,12 +43,25 @@ Item { function onPageClosed(settingsObject) { settingsObject['account_name'] = uiItem.accountNameText - settingsObject['words'] = uiItem.wordsTexttext + settingsObject['words'] = cleanWordsInput(uiItem.wordsTextItem.memoText) settingsObject['wallet_path'] = uiItem.walletPath + return recoveryWallet(settingsObject) } - function recoveryWallet() { + function recoveryWallet(settingsObject) { + var testnet = true; + var wallet = walletManager.recoveryWallet(oshelper.temporaryFilename(), settingsObject.words, testnet); + var success = wallet.status === Wallet.Status_Ok; + if (success) { + settingsObject['wallet'] = wallet; + } else { + walletManager.closeWallet(wallet); + } + return success; + } + function cleanWordsInput(text) { + return text.trim().replace(/(\r\n|\n|\r)/gm, " "); } WizardManageWalletUI { @@ -60,8 +74,8 @@ Item { wordsTextItem.memoTextReadOnly: false wordsTextItem.memoText: "" wordsTextItem.onMemoTextChanged: { - var wordsArray = wordsTextItem.memoText.trim().split(" ") - //wizard.nextButton.enabled = wordsArray.length === 25 + var wordsArray = cleanWordsInput(wordsTextItem.memoText).split(" "); + wizard.nextButton.enabled = wordsArray.length === 25 } } } diff --git a/wizard/WizardWelcome.qml b/wizard/WizardWelcome.qml index bdd88b70..8917d212 100644 --- a/wizard/WizardWelcome.qml +++ b/wizard/WizardWelcome.qml @@ -41,6 +41,7 @@ Item { settingsObject['language'] = lang.display_name; settingsObject['wallet_language'] = lang.wallet_name; settingsObject['locale'] = lang.locale; + return true } Column { From 2151f1395c28027f867d8e640b0c0be4cd4e0a23 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 15 Jun 2016 13:25:45 +0300 Subject: [PATCH 26/87] Persistent storage for common settings. closes #10 --- main.cpp | 5 +++++ main.qml | 2 ++ wizard/WizardDonation.qml | 12 ++++++++---- wizard/WizardMain.qml | 26 ++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/main.cpp b/main.cpp index a4a79947..7331a4e4 100644 --- a/main.cpp +++ b/main.cpp @@ -43,6 +43,11 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); + + app.setApplicationName("monero-core"); + app.setOrganizationDomain("getmonero.org"); + app.setOrganizationName("The Monero Project"); + filter *eventFilter = new filter; app.installEventFilter(eventFilter); diff --git a/main.qml b/main.qml index a36a3755..0eb87b2e 100644 --- a/main.qml +++ b/main.qml @@ -30,6 +30,8 @@ import QtQuick 2.2 import QtQuick.Window 2.0 import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 + + import "components" import "wizard" diff --git a/wizard/WizardDonation.qml b/wizard/WizardDonation.qml index e0b73df8..80ebd78b 100644 --- a/wizard/WizardDonation.qml +++ b/wizard/WizardDonation.qml @@ -38,13 +38,17 @@ Item { onOpacityChanged: visible = opacity !== 0 + function onPageOpened(settingsObject) { + enableAutoDonationCheckBox.checked = settingsObject.auto_donations_enabled + autoDonationAmountText.text = settingsObject.auto_donations_amount + allowBackgroundMiningCheckBox.checked = settingsObject.allow_background_mining + + } + function onPageClosed(settingsObject) { settingsObject['auto_donations_enabled'] = enableAutoDonationCheckBox.checked; - settingsObject['auto_donations_amount'] = autoDonationAmountText.text; + settingsObject['auto_donations_amount'] = parseInt(autoDonationAmountText.text); settingsObject['allow_background_mining'] = allowBackgroundMiningCheckBox.checked; - - - return true; } diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index da3a9824..940243cb 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -27,6 +27,8 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.2 +import Qt.labs.settings 1.0 + import "../components" Rectangle { @@ -142,10 +144,34 @@ Rectangle { // saving wallet_filename; settings['wallet_filename'] = new_wallet_filename; + + // persist settings + persistentSettings.language = settings.language + persistentSettings.account_name = settings.account_name + persistentSettings.wallet_path = settings.wallet_path + persistentSettings.allow_background_mining = settings.allow_background_mining + persistentSettings.auto_donations_enabled = settings.auto_donations_enabled + persistentSettings.auto_donations_amount = settings.auto_donations_amount + } + + // reading settings from persistent storage + Component.onCompleted: { + settings['allow_background_mining'] = persistentSettings.allow_background_mining + settings['auto_donations_enabled'] = persistentSettings.auto_donations_enabled + settings['auto_donations_amount'] = persistentSettings.auto_donations_amount } + Settings { + id: persistentSettings + property string language + property string account_name + property string wallet_path + property bool auto_donations_enabled : true + property int auto_donations_amount : 50 + property bool allow_background_mining : true + } Rectangle { id: nextButton From 3ddd9bed72da0e039f44b64a4cc9fff679dd40ed Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 15 Jun 2016 16:34:55 +0300 Subject: [PATCH 27/87] main application: initialize wallet, display balance --- BasicPanel.qml | 3 ++ LeftPanel.qml | 14 +++++++--- main.qml | 58 +++++++++++++++++++++++++++++++++++++-- wizard/WizardMain.qml | 37 +++++++++++++------------ wizard/WizardPassword.qml | 4 ++- 5 files changed, 91 insertions(+), 25 deletions(-) diff --git a/BasicPanel.qml b/BasicPanel.qml index 20a07d64..5698316f 100644 --- a/BasicPanel.qml +++ b/BasicPanel.qml @@ -35,6 +35,8 @@ Rectangle { color: "#F0EEEE" border.width: 1 border.color: "#DBDBDB" + property alias balanceText : balanceText.text; + property alias unlockedBalanceText : availableBalanceText.text; Rectangle { id: header @@ -63,6 +65,7 @@ Rectangle { columns: 3 Text { + width: 116 height: 20 font.family: "Arial" diff --git a/LeftPanel.qml b/LeftPanel.qml index 6bd400a8..1eddf019 100644 --- a/LeftPanel.qml +++ b/LeftPanel.qml @@ -31,6 +31,10 @@ import "components" Rectangle { id: panel + + property alias unlockedBalanceText: unlockedBalanceText.text + property alias balanceText: balanceText.text + signal dashboardClicked() signal historyClicked() signal transferClicked() @@ -90,7 +94,7 @@ Rectangle { spacing: 6 Label { - text: qsTr("Locked balance") + text: qsTr("Balance") anchors.left: parent.left anchors.leftMargin: 50 tipText: qsTr("Test tip 1<br/><br/>line 2") @@ -109,11 +113,12 @@ Rectangle { } Text { + id: balanceText anchors.verticalCenter: parent.verticalCenter font.family: "Arial" font.pixelSize: 26 color: "#000000" - text: "78.9239845" + text: "78.9245" } } @@ -124,19 +129,20 @@ Rectangle { } Label { - text: qsTr("Unlocked") + text: qsTr("Unlocked balance") anchors.left: parent.left anchors.leftMargin: 50 tipText: qsTr("Test tip 2<br/><br/>line 2") } Text { + id: unlockedBalanceText anchors.left: parent.left anchors.leftMargin: 50 font.family: "Arial" font.pixelSize: 18 color: "#000000" - text: "2324.9239845" + text: "2324.9245" } } diff --git a/main.qml b/main.qml index 0eb87b2e..3b79d1ec 100644 --- a/main.qml +++ b/main.qml @@ -30,7 +30,8 @@ import QtQuick 2.2 import QtQuick.Window 2.0 import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 - +import Qt.labs.settings 1.0 +import Bitmonero.Wallet 1.0 import "components" import "wizard" @@ -43,12 +44,16 @@ ApplicationWindow { property bool ctrlPressed: false property bool rightPanelExpanded: true property bool osx: false + property alias persistentSettings : persistentSettings + property var wallet; function altKeyReleased() { ctrlPressed = false; } + function showPageRequest(page) { middlePanel.state = page leftPanel.selectItem(page) } + function sequencePressed(obj, seq) { if(seq === undefined) return @@ -112,6 +117,37 @@ ApplicationWindow { } + + function initialize() { + + if (typeof wizard.settings['wallet'] !== 'undefined') { + wallet = wizard.settings['wallet']; + } else { + var wallet_path = persistentSettings.wallet_path + "/" + persistentSettings.account_name + "/" + + persistentSettings.account_name; + console.log("opening wallet at: ", wallet_path); + // TODO: wallet password dialog + wallet = walletManager.openWallet(wallet_path, "", persistentSettings.testnet); + if (wallet.status !== Wallet.Status_Ok) { + console.log("Error opening wallet: ", wallet.errorString); + return; + } + console.log("Wallet opened successfully: ", wallet.errorString); + } + + if (!wallet.init(persistentSettings.daemon_address, 0)) { + console.log("Error initialize wallet: ", wallet.errorString); + return + } + // TODO: refresh asynchronously without blocking UI, implement signal(s) + wallet.refresh(); + + console.log("wallet balance: ", wallet.balance) + leftPanel.unlockedBalanceText = walletManager.displayAmount(wallet.unlockedBalance); + leftPanel.balanceText = walletManager.displayAmount(wallet.balance); + } + + function walletsFound() { var wallets = walletManager.findWallets(moneroAccountsDir); if (wallets.length === 0) { @@ -133,6 +169,21 @@ ApplicationWindow { y = (Screen.height - height) / 2 // rootItem.state = walletsFound() ? "normal" : "wizard"; + if (rootItem.state === "normal") { + initialize(persistentSettings) + } + } + + Settings { + id: persistentSettings + property string language + property string account_name + property string wallet_path + property bool auto_donations_enabled : true + property int auto_donations_amount : 50 + property bool allow_background_mining : true + property bool testnet: true + property string daemon_address: "localhost:38081" } Item { @@ -344,7 +395,10 @@ ApplicationWindow { WizardMain { id: wizard anchors.fill: parent - onUseMoneroClicked: rootItem.state = "normal" + onUseMoneroClicked: { + rootItem.state = "normal" // TODO: listen for this state change in appWindow; + appWindow.initialize(); + } } property int maxWidth: leftPanel.width + 655 + rightPanel.width diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index 940243cb..3c4103ce 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -146,32 +146,33 @@ Rectangle { settings['wallet_filename'] = new_wallet_filename; // persist settings - persistentSettings.language = settings.language - persistentSettings.account_name = settings.account_name - persistentSettings.wallet_path = settings.wallet_path - persistentSettings.allow_background_mining = settings.allow_background_mining - persistentSettings.auto_donations_enabled = settings.auto_donations_enabled - persistentSettings.auto_donations_amount = settings.auto_donations_amount + appWindow.persistentSettings.language = settings.language + appWindow.persistentSettings.account_name = settings.account_name + appWindow.persistentSettings.wallet_path = settings.wallet_path + appWindow.persistentSettings.allow_background_mining = settings.allow_background_mining + appWindow.persistentSettings.auto_donations_enabled = settings.auto_donations_enabled + appWindow.persistentSettings.auto_donations_amount = settings.auto_donations_amount } // reading settings from persistent storage Component.onCompleted: { - settings['allow_background_mining'] = persistentSettings.allow_background_mining - settings['auto_donations_enabled'] = persistentSettings.auto_donations_enabled - settings['auto_donations_amount'] = persistentSettings.auto_donations_amount + console.log("rootItem: ", appWindow); + settings['allow_background_mining'] = appWindow.persistentSettings.allow_background_mining + settings['auto_donations_enabled'] = appWindow.persistentSettings.auto_donations_enabled + settings['auto_donations_amount'] = appWindow.persistentSettings.auto_donations_amount } - Settings { - id: persistentSettings +// Settings { +// id: persistentSettings - property string language - property string account_name - property string wallet_path - property bool auto_donations_enabled : true - property int auto_donations_amount : 50 - property bool allow_background_mining : true - } +// property string language +// property string account_name +// property string wallet_path +// property bool auto_donations_enabled : true +// property int auto_donations_amount : 50 +// property bool allow_background_mining : true +// } Rectangle { id: nextButton diff --git a/wizard/WizardPassword.qml b/wizard/WizardPassword.qml index 6b14dae9..4825c02d 100644 --- a/wizard/WizardPassword.qml +++ b/wizard/WizardPassword.qml @@ -44,7 +44,9 @@ Item { onOpacityChanged: visible = opacity !== 0 function onPageClosed(settingsObject) { - settingsObject.wallet.setPassword(passwordItem.password) + // TODO: set password on the final page + // settingsObject.wallet.setPassword(passwordItem.password) + settingsObject['wallet_password'] = passwordItem.password return true } From eaf59243b2cbe3d7ea6de1d8dcd18493df9f365d Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Thu, 16 Jun 2016 17:13:46 +0300 Subject: [PATCH 28/87] basic "send money" functionality implemented in GUI --- LeftPanel.qml | 2 ++ MiddlePanel.qml | 14 ++++++++++++++ components/LineEdit.qml | 3 +++ main.cpp | 3 +++ main.qml | 25 +++++++++++++++++++++++++ pages/Transfer.qml | 27 +++++++++++++++++++++------ src/libwalletqt/PendingTransaction.h | 2 ++ src/libwalletqt/WalletManager.cpp | 9 +++++++++ src/libwalletqt/WalletManager.h | 3 +++ 9 files changed, 82 insertions(+), 6 deletions(-) diff --git a/LeftPanel.qml b/LeftPanel.qml index 1eddf019..95b5aa6f 100644 --- a/LeftPanel.qml +++ b/LeftPanel.qml @@ -56,6 +56,7 @@ Rectangle { width: 260 color: "#FFFFFF" + // Item with monero logo Item { id: logoItem anchors.left: parent.left @@ -85,6 +86,7 @@ Rectangle { } } + Column { id: column1 anchors.left: parent.left diff --git a/MiddlePanel.qml b/MiddlePanel.qml index 62072af9..28d6f137 100644 --- a/MiddlePanel.qml +++ b/MiddlePanel.qml @@ -30,6 +30,7 @@ import QtQuick 2.2 Rectangle { color: "#F0EEEE" + signal paymentClicked(string address, string paymentId, double amount, double fee, int privacyLevel) states: [ State { @@ -72,6 +73,19 @@ Rectangle { anchors.right: parent.right anchors.top: styledRow.bottom anchors.bottom: parent.bottom + onLoaded: { + console.log("Loaded " + item); + } + + } + + Connections { + ignoreUnknownSignals: false + target: loader.item + onPaymentClicked : { + console.log("MiddlePanel: paymentClicked") + paymentClicked(address, paymentId, amount, fee, privacyLevel) + } } Rectangle { diff --git a/components/LineEdit.qml b/components/LineEdit.qml index 6994b75f..37c2390d 100644 --- a/components/LineEdit.qml +++ b/components/LineEdit.qml @@ -31,7 +31,9 @@ import QtQuick 2.0 Item { property alias placeholderText: input.placeholderText property alias text: input.text + property alias validator: input.validator property int fontSize: 18 + height: 37 Rectangle { @@ -54,5 +56,6 @@ Item { anchors.leftMargin: 4 anchors.rightMargin: 4 font.pixelSize: parent.fontSize + } } diff --git a/main.cpp b/main.cpp index 7331a4e4..70390a80 100644 --- a/main.cpp +++ b/main.cpp @@ -36,6 +36,7 @@ #include "oshelper.h" #include "WalletManager.h" #include "Wallet.h" +#include "PendingTransaction.h" @@ -53,6 +54,8 @@ int main(int argc, char *argv[]) qmlRegisterType<clipboardAdapter>("moneroComponents", 1, 0, "Clipboard"); qmlRegisterUncreatableType<Wallet>("Bitmonero.Wallet", 1, 0, "Wallet", "Wallet can't be instantiated directly"); + qmlRegisterUncreatableType<PendingTransaction>("Bitmonero.PendingTransaction", 1, 0, "PendingTransaction", + "PendingTransaction can't be instantiated directly"); QQmlApplicationEngine engine; diff --git a/main.qml b/main.qml index 3b79d1ec..d6109339 100644 --- a/main.qml +++ b/main.qml @@ -32,6 +32,7 @@ import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 import Qt.labs.settings 1.0 import Bitmonero.Wallet 1.0 +import Bitmonero.PendingTransaction 1.0 import "components" import "wizard" @@ -120,6 +121,8 @@ ApplicationWindow { function initialize() { + middlePanel.paymentClicked.connect(handlePayment); + if (typeof wizard.settings['wallet'] !== 'undefined') { wallet = wizard.settings['wallet']; } else { @@ -157,6 +160,27 @@ ApplicationWindow { return wallets.length > 0; } + function handlePayment(address, paymentId, amount, fee, privacyLevel) { + console.log("Process payment here: ", address, paymentId, amount, fee, privacyLevel) + // TODO: handle payment id + // TODO: handle fee; + // TODO: handle mixins + var amountxmr = walletManager.amountFromString(amount); + + console.log("integer amount: ", amountxmr); + var pendingTransaction = wallet.createTransaction(address, amountxmr); + if (pendingTransaction.status !== PendingTransaction.Status_Ok) { + console.error("Can't create transaction: ", pendingTransaction.errorString); + } else { + console.log("Transaction created, amount: " + walletManager.displayAmount(pendingTransaction.amount) + + ", fee: " + walletManager.displayAmount(pendingTransaction.fee)); + if (!pendingTransaction.commit()) { + console.log("Error committing transaction: " + pendingTransaction.errorString); + } + } + wallet.disposeTransaction(pendingTransaction); + } + visible: true width: rightPanelExpanded ? 1269 : 1269 - 300 height: 800 @@ -423,6 +447,7 @@ ApplicationWindow { } property var previousPosition + onPressed: { previousPosition = globalCursor.getPosition() } diff --git a/pages/Transfer.qml b/pages/Transfer.qml index 2535b8fe..df0a5b20 100644 --- a/pages/Transfer.qml +++ b/pages/Transfer.qml @@ -30,8 +30,11 @@ import QtQuick 2.0 import "../components" Rectangle { + signal paymentClicked(string address, string paymentId, double amount, double fee, int privacyLevel) + color: "#F0EEEE" + Label { id: amountLabel anchors.left: parent.left @@ -67,8 +70,9 @@ Rectangle { source: "../images/moneroIcon.png" } } - + // Amount input LineEdit { + id: amountLine placeholderText: qsTr("Amount...") width: parent.width - 37 - 17 } @@ -133,7 +137,7 @@ Rectangle { onLinkActivated: appWindow.showPageRequest("AddressBook") } - + // recipient address input LineEdit { id: addressLine anchors.left: parent.left @@ -142,10 +146,11 @@ Rectangle { anchors.leftMargin: 17 anchors.rightMargin: 17 anchors.topMargin: 5 + // validator: RegExpValidator { regExp: /[0-9A-Fa-f]{95}/g } } Label { - id: paymentLabel + id: paymentIdLabel anchors.left: parent.left anchors.right: parent.right anchors.top: addressLine.bottom @@ -156,21 +161,23 @@ Rectangle { text: qsTr("Payment ID <font size='2'>( Optional )</font>") } + // payment id input LineEdit { - id: paymentLine + id: paymentIdLine anchors.left: parent.left anchors.right: parent.right - anchors.top: paymentLabel.bottom + anchors.top: paymentIdLabel.bottom anchors.leftMargin: 17 anchors.rightMargin: 17 anchors.topMargin: 5 + // validator: DoubleValidator { top: 0.0 } } Label { id: descriptionLabel anchors.left: parent.left anchors.right: parent.right - anchors.top: paymentLine.bottom + anchors.top: paymentIdLine.bottom anchors.leftMargin: 17 anchors.rightMargin: 17 anchors.topMargin: 17 @@ -200,5 +207,13 @@ Rectangle { shadowPressedColor: "#B32D00" releasedColor: "#FF6C3C" pressedColor: "#FF4304" + onClicked: { + // do more smart validation + + if (addressLine.text.length > 0 && amountLine.text.length > 0) { + console.log("paymentClicked") + paymentClicked(addressLine.text, paymentIdLine.text, amountLine.text, 0.0002, 1) + } + } } } diff --git a/src/libwalletqt/PendingTransaction.h b/src/libwalletqt/PendingTransaction.h index 29fa7cb4..d8c4ec1e 100644 --- a/src/libwalletqt/PendingTransaction.h +++ b/src/libwalletqt/PendingTransaction.h @@ -24,6 +24,8 @@ public: Status_Error = Bitmonero::PendingTransaction::Status_Error }; + Q_ENUM(Status) + Status status() const; QString errorString() const; Q_INVOKABLE bool commit(); diff --git a/src/libwalletqt/WalletManager.cpp b/src/libwalletqt/WalletManager.cpp index 6ad81e2a..a7742bca 100644 --- a/src/libwalletqt/WalletManager.cpp +++ b/src/libwalletqt/WalletManager.cpp @@ -92,6 +92,15 @@ QString WalletManager::displayAmount(quint64 amount) return QString::fromStdString(Bitmonero::Wallet::displayAmount(amount)); } +quint64 WalletManager::amountFromString(const QString &amount) +{ + return Bitmonero::Wallet::amountFromString(amount.toStdString()); +} + +quint64 WalletManager::amountFromDouble(double amount) +{ + return Bitmonero::Wallet::amountFromDouble(amount); +} WalletManager::WalletManager(QObject *parent) : QObject(parent) { diff --git a/src/libwalletqt/WalletManager.h b/src/libwalletqt/WalletManager.h index 30e6b02a..29df9048 100644 --- a/src/libwalletqt/WalletManager.h +++ b/src/libwalletqt/WalletManager.h @@ -45,6 +45,9 @@ public: //! since we can't call static method from QML, move it to this class Q_INVOKABLE QString displayAmount(quint64 amount); + Q_INVOKABLE quint64 amountFromString(const QString &amount); + Q_INVOKABLE quint64 amountFromDouble(double amount); + signals: public slots: From 8ac86a8042f23e524f1f5245ada9ac7a1c2fc191 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Fri, 17 Jun 2016 16:35:07 +0300 Subject: [PATCH 29/87] Balance on UI updated by the signal --- main.qml | 12 ++++++++++++ src/libwalletqt/Wallet.cpp | 6 +++++- src/libwalletqt/Wallet.h | 3 +++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/main.qml b/main.qml index d6109339..e193ae29 100644 --- a/main.qml +++ b/main.qml @@ -142,10 +142,19 @@ ApplicationWindow { console.log("Error initialize wallet: ", wallet.errorString); return } + + // subscribing for wallet updates + wallet.updated.connect(onWalletUpdate); + // TODO: refresh asynchronously without blocking UI, implement signal(s) wallet.refresh(); console.log("wallet balance: ", wallet.balance) + + } + + function onWalletUpdate() { + console.log("wallet updated") leftPanel.unlockedBalanceText = walletManager.displayAmount(wallet.unlockedBalance); leftPanel.balanceText = walletManager.displayAmount(wallet.balance); } @@ -176,8 +185,11 @@ ApplicationWindow { + ", fee: " + walletManager.displayAmount(pendingTransaction.fee)); if (!pendingTransaction.commit()) { console.log("Error committing transaction: " + pendingTransaction.errorString); + } else { + wallet.refresh(); } } + wallet.disposeTransaction(pendingTransaction); } diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 77901b0c..901075b6 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -7,6 +7,7 @@ #include <QDir> #include <QDebug> #include <QUrl> +#include <QTimer> namespace { @@ -81,7 +82,10 @@ quint64 Wallet::unlockedBalance() const bool Wallet::refresh() { - return m_walletImpl->refresh(); + bool result = m_walletImpl->refresh(); + if (result) + emit updated(); + return result; } PendingTransaction *Wallet::createTransaction(const QString &dst_addr, quint64 amount) diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index 7d391429..f8263040 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -85,6 +85,9 @@ public: TransactionHistory * history(); // TODO: setListenter() when it implemented in API +signals: + void updated(); + private: Wallet(Bitmonero::Wallet *w, QObject * parent = 0); From e3985da4e1c95e21716fbee4824ba9ca471ef220 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Mon, 20 Jun 2016 15:58:13 +0300 Subject: [PATCH 30/87] Transfer page: priority dropdown hidded --- pages/Transfer.qml | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/pages/Transfer.qml b/pages/Transfer.qml index df0a5b20..f215ab27 100644 --- a/pages/Transfer.qml +++ b/pages/Transfer.qml @@ -45,7 +45,7 @@ Rectangle { text: qsTr("Amount") fontSize: 14 } - + /* Label { id: transactionPriority anchors.top: parent.top @@ -54,8 +54,11 @@ Rectangle { x: (parent.width - 17) / 2 + 17 text: qsTr("Transaction prority") } + */ + Row { + id: amountRow anchors.top: amountLabel.bottom anchors.topMargin: 5 anchors.left: parent.left @@ -84,7 +87,7 @@ Rectangle { ListElement { column1: "MEDIUM"; column2: "( fee: 0.0004 )" } ListElement { column1: "HIGH"; column2: "( fee: 0.0008 )" } } - + /* StandardDropdown { id: priorityDropdown anchors.top: transactionPriority.bottom @@ -99,12 +102,14 @@ Rectangle { dataModel: priorityModel z: 1 } + */ + Label { id: privacyLabel anchors.left: parent.left anchors.right: parent.right - anchors.top: priorityDropdown.bottom + anchors.top: amountRow.bottom anchors.leftMargin: 17 anchors.rightMargin: 17 anchors.topMargin: 30 @@ -122,6 +127,19 @@ Rectangle { anchors.topMargin: 5 } + + Label { + id: costLabel + anchors.right: parent.right + anchors.top: amountRow.bottom + anchors.leftMargin: 17 + anchors.rightMargin: 17 + anchors.topMargin: 30 + fontSize: 14 + text: qsTr("Cost") + } + + Label { id: addressLabel anchors.left: parent.left From 37c1c0bb7904c6b83f8a2e37049ece5af499cce1 Mon Sep 17 00:00:00 2001 From: Riccardo Spagni <ric@spagni.net> Date: Mon, 20 Jun 2016 21:08:09 +0200 Subject: [PATCH 31/87] disable right panel by default, don't perform Twitter https call if panel is disabled --- main.qml | 2 +- tabs/TweetsModel.qml | 41 ++++++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/main.qml b/main.qml index e193ae29..0ec6dafc 100644 --- a/main.qml +++ b/main.qml @@ -43,7 +43,7 @@ ApplicationWindow { property var currentItem property bool whatIsEnable: false property bool ctrlPressed: false - property bool rightPanelExpanded: true + property bool rightPanelExpanded: false property bool osx: false property alias persistentSettings : persistentSettings property var wallet; diff --git a/tabs/TweetsModel.qml b/tabs/TweetsModel.qml index 0e9fe004..a6b40aa6 100644 --- a/tabs/TweetsModel.qml +++ b/tabs/TweetsModel.qml @@ -60,30 +60,33 @@ Item { if (from == "" && phrase == "") return; + if (appWindow.rightPanelExpanded) { + //! [requesting] - var req = new XMLHttpRequest; - req.open("GET", "https://api.twitter.com/1.1/search/tweets.json?from=" + from + - "&count=" + tweetsMaxCount + "&q=" + encodePhrase(phrase)); - req.setRequestHeader("Authorization", "Bearer " + bearerToken); - req.onreadystatechange = function() { - status = req.readyState; - if (status === XMLHttpRequest.DONE) { - var objectArray = JSON.parse(req.responseText); - if (objectArray.errors !== undefined) - console.log("Error fetching tweets: " + objectArray.errors[0].message) - else { - for (var key in objectArray.statuses) { - var jsonObject = objectArray.statuses[key]; - tweets.append(jsonObject); + var req = new XMLHttpRequest; + req.open("GET", "https://api.twitter.com/1.1/search/tweets.json?from=" + from + + "&count=" + tweetsMaxCount + "&q=" + encodePhrase(phrase)); + req.setRequestHeader("Authorization", "Bearer " + bearerToken); + req.onreadystatechange = function() { + status = req.readyState; + if (status === XMLHttpRequest.DONE) { + var objectArray = JSON.parse(req.responseText); + if (objectArray.errors !== undefined) + console.log("Error fetching tweets: " + objectArray.errors[0].message) + else { + for (var key in objectArray.statuses) { + var jsonObject = objectArray.statuses[key]; + tweets.append(jsonObject); + } } + if (wasLoading == true) + wrapper.isLoaded() } - if (wasLoading == true) - wrapper.isLoaded() + wasLoading = (status === XMLHttpRequest.LOADING); } - wasLoading = (status === XMLHttpRequest.LOADING); - } - req.send(); + req.send(); //! [requesting] + } } From 2696e49a54c5ef028f7e4e74ffe3b18e205cd28f Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Mon, 20 Jun 2016 23:36:56 +0300 Subject: [PATCH 32/87] mixin count for Wallet::createTransaction --- MiddlePanel.qml | 4 ++-- main.qml | 6 +++--- pages/Transfer.qml | 17 +++++++++++++++-- src/libwalletqt/Wallet.cpp | 4 ++-- src/libwalletqt/Wallet.h | 2 +- 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/MiddlePanel.qml b/MiddlePanel.qml index 28d6f137..edb4963d 100644 --- a/MiddlePanel.qml +++ b/MiddlePanel.qml @@ -30,7 +30,7 @@ import QtQuick 2.2 Rectangle { color: "#F0EEEE" - signal paymentClicked(string address, string paymentId, double amount, double fee, int privacyLevel) + signal paymentClicked(string address, string paymentId, double amount, int mixinCount) states: [ State { @@ -84,7 +84,7 @@ Rectangle { target: loader.item onPaymentClicked : { console.log("MiddlePanel: paymentClicked") - paymentClicked(address, paymentId, amount, fee, privacyLevel) + paymentClicked(address, paymentId, amount, mixinCount) } } diff --git a/main.qml b/main.qml index e193ae29..e6dcef64 100644 --- a/main.qml +++ b/main.qml @@ -169,15 +169,15 @@ ApplicationWindow { return wallets.length > 0; } - function handlePayment(address, paymentId, amount, fee, privacyLevel) { - console.log("Process payment here: ", address, paymentId, amount, fee, privacyLevel) + function handlePayment(address, paymentId, amount, mixinCount) { + console.log("Process payment here: ", address, paymentId, amount, mixinCount) // TODO: handle payment id // TODO: handle fee; // TODO: handle mixins var amountxmr = walletManager.amountFromString(amount); console.log("integer amount: ", amountxmr); - var pendingTransaction = wallet.createTransaction(address, amountxmr); + var pendingTransaction = wallet.createTransaction(address, amountxmr, mixinCount); if (pendingTransaction.status !== PendingTransaction.Status_Ok) { console.error("Can't create transaction: ", pendingTransaction.errorString); } else { diff --git a/pages/Transfer.qml b/pages/Transfer.qml index f215ab27..e3f96997 100644 --- a/pages/Transfer.qml +++ b/pages/Transfer.qml @@ -30,10 +30,19 @@ import QtQuick 2.0 import "../components" Rectangle { - signal paymentClicked(string address, string paymentId, double amount, double fee, int privacyLevel) + signal paymentClicked(string address, string paymentId, double amount, int mixinCount) color: "#F0EEEE" + function scaleValueToMixinCount(scaleValue) { + var scaleToMixinCount = [2,3,4,5,5,5,6,7,8,9,10,15,20,25]; + if (scaleValue < scaleToMixinCount.length) { + return scaleToMixinCount[scaleValue]; + } else { + return 0; + } + } + Label { id: amountLabel @@ -125,6 +134,10 @@ Rectangle { anchors.leftMargin: 17 anchors.rightMargin: 17 anchors.topMargin: 5 + onFillLevelChanged: { + print ("PrivacyLevel changed:" + fillLevel) + print ("mixin count:" + scaleValueToMixinCount(fillLevel)) + } } @@ -230,7 +243,7 @@ Rectangle { if (addressLine.text.length > 0 && amountLine.text.length > 0) { console.log("paymentClicked") - paymentClicked(addressLine.text, paymentIdLine.text, amountLine.text, 0.0002, 1) + paymentClicked(addressLine.text, paymentIdLine.text, amountLine.text, scaleValueToMixinCount(privacyLevelItem.fillLevel)) } } } diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 901075b6..4e6b6787 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -88,10 +88,10 @@ bool Wallet::refresh() return result; } -PendingTransaction *Wallet::createTransaction(const QString &dst_addr, quint64 amount) +PendingTransaction *Wallet::createTransaction(const QString &dst_addr, quint64 amount, quint32 mixin_count) { Bitmonero::PendingTransaction * ptImpl = m_walletImpl->createTransaction( - dst_addr.toStdString(), amount); + dst_addr.toStdString(), amount, mixin_count); PendingTransaction * result = new PendingTransaction(ptImpl, this); return result; } diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index f8263040..4991476a 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -76,7 +76,7 @@ public: //! creates transaction Q_INVOKABLE PendingTransaction * createTransaction(const QString &dst_addr, - quint64 amount); + quint64 amount, quint32 mixin_count); //! deletes transaction and frees memory Q_INVOKABLE void disposeTransaction(PendingTransaction * t); From 88d9be953babda68cb5325258569578c11fa4438 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Tue, 21 Jun 2016 11:58:06 +0300 Subject: [PATCH 33/87] Lazy loading for the tweets --- RightPanel.qml | 13 +++++++++++- main.qml | 6 ++++++ tabs/TweetsModel.qml | 48 +++++++++++++++++++------------------------- tabs/Twitter.qml | 8 ++++++++ 4 files changed, 47 insertions(+), 28 deletions(-) diff --git a/RightPanel.qml b/RightPanel.qml index b29cb28a..c5878146 100644 --- a/RightPanel.qml +++ b/RightPanel.qml @@ -36,6 +36,11 @@ Rectangle { width: 330 color: "#FFFFFF" + function updateTweets() { + tabView.twitter.item.updateTweets() + } + + TabView { id: tabView anchors.left: parent.left @@ -45,12 +50,18 @@ Rectangle { anchors.leftMargin: 14 anchors.rightMargin: 14 anchors.topMargin: 40 + property alias twitter: twitter - Tab { title: qsTr("Twitter"); source: "tabs/Twitter.qml" } + + + + Tab { id: twitter; title: qsTr("Twitter"); source: "tabs/Twitter.qml" } Tab { title: "News" } Tab { title: "Help" } Tab { title: "About" } + + style: TabViewStyle { frameOverlap: 0 tabOverlap: 0 diff --git a/main.qml b/main.qml index 7101d096..6f90bcf8 100644 --- a/main.qml +++ b/main.qml @@ -210,6 +210,12 @@ ApplicationWindow { } } + onRightPanelExpandedChanged: { + if (rightPanelExpanded) { + rightPanel.updateTweets() + } + } + Settings { id: persistentSettings property string language diff --git a/tabs/TweetsModel.qml b/tabs/TweetsModel.qml index a6b40aa6..55a7c74d 100644 --- a/tabs/TweetsModel.qml +++ b/tabs/TweetsModel.qml @@ -56,47 +56,41 @@ Item { function reload() { tweets.clear() - if (from == "" && phrase == "") return; - - if (appWindow.rightPanelExpanded) { - -//! [requesting] - var req = new XMLHttpRequest; - req.open("GET", "https://api.twitter.com/1.1/search/tweets.json?from=" + from + - "&count=" + tweetsMaxCount + "&q=" + encodePhrase(phrase)); - req.setRequestHeader("Authorization", "Bearer " + bearerToken); - req.onreadystatechange = function() { - status = req.readyState; - if (status === XMLHttpRequest.DONE) { - var objectArray = JSON.parse(req.responseText); - if (objectArray.errors !== undefined) - console.log("Error fetching tweets: " + objectArray.errors[0].message) - else { - for (var key in objectArray.statuses) { - var jsonObject = objectArray.statuses[key]; - tweets.append(jsonObject); - } + //! [requesting] + var req = new XMLHttpRequest; + req.open("GET", "https://api.twitter.com/1.1/search/tweets.json?from=" + from + + "&count=" + tweetsMaxCount + "&q=" + encodePhrase(phrase)); + req.setRequestHeader("Authorization", "Bearer " + bearerToken); + req.onreadystatechange = function() { + status = req.readyState; + if (status === XMLHttpRequest.DONE) { + var objectArray = JSON.parse(req.responseText); + if (objectArray.errors !== undefined) + console.log("Error fetching tweets: " + objectArray.errors[0].message) + else { + for (var key in objectArray.statuses) { + var jsonObject = objectArray.statuses[key]; + tweets.append(jsonObject); } - if (wasLoading == true) - wrapper.isLoaded() } - wasLoading = (status === XMLHttpRequest.LOADING); + if (wasLoading == true) + wrapper.isLoaded() } - req.send(); -//! [requesting] + wasLoading = (status === XMLHttpRequest.LOADING); } + req.send(); + //! [requesting] } - Component.onCompleted: { if (consumerKey === "" || consumerSecret == "") { console.log("setting demo token") bearerToken = encodeURIComponent(Helper.demoToken()) tweetsModel.phrase = "" tweetsModel.from = "@monerocurrency" - reload() + // reload() return; } diff --git a/tabs/Twitter.qml b/tabs/Twitter.qml index 553e7da6..bd597287 100644 --- a/tabs/Twitter.qml +++ b/tabs/Twitter.qml @@ -34,6 +34,8 @@ import "../components" Item { id: tab + + ListModel { id: testModel ListElement { head: "Monero || #xmr"; foot: "<b>@btcplanet</b> Duis turpis arcu, varius nec rutrum in, adipiscing at enim. Donec quis consequat ipsum," } @@ -56,10 +58,16 @@ Item { property var idx property var ids + function updateTweets() { + tweetsModel.reload() + } + + Component.onCompleted: { ids = new Array() } + function idInModel(id) { for (var j = 0; j < ids.length; j++) if (ids[j] === id) From 17f38a930e33c25392dd565f484009e5eddba56a Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Sun, 26 Jun 2016 18:04:45 +0300 Subject: [PATCH 34/87] Added "Receive" page. Hide all pages except "Transfer" and "Receive". --- LeftPanel.qml | 50 ++++++++- MiddlePanel.qml | 5 + components/IconButton.qml | 72 +++++++++++++ components/Input.qml | 1 + components/LineEdit.qml | 3 +- get_libwallet_api.sh | 2 + main.qml | 4 +- pages/Receive.qml | 184 ++++++++++++++++++++++++++++++++ qml.qrc | 2 + src/libwalletqt/Wallet.cpp | 25 ++++- src/libwalletqt/Wallet.h | 16 ++- wizard/WizardCreateWallet.qml | 4 +- wizard/WizardRecoveryWallet.qml | 2 +- 13 files changed, 359 insertions(+), 11 deletions(-) create mode 100644 components/IconButton.qml create mode 100644 pages/Receive.qml diff --git a/LeftPanel.qml b/LeftPanel.qml index 95b5aa6f..0c1ccd12 100644 --- a/LeftPanel.qml +++ b/LeftPanel.qml @@ -34,10 +34,12 @@ Rectangle { property alias unlockedBalanceText: unlockedBalanceText.text property alias balanceText: balanceText.text + property alias networkStatus : networkStatus signal dashboardClicked() signal historyClicked() signal transferClicked() + signal receiveClicked() signal settingsClicked() signal addressBookClicked() signal miningClicked() @@ -47,9 +49,11 @@ Rectangle { if(pos === "Dashboard") menuColumn.previousButton = dashboardButton else if(pos === "History") menuColumn.previousButton = historyButton else if(pos === "Transfer") menuColumn.previousButton = transferButton + else if(pos === "Receive") menuColumn.previousButton = receiveButton else if(pos === "AddressBook") menuColumn.previousButton = addressBookButton else if(pos === "Mining") menuColumn.previousButton = miningButton else if(pos === "Settings") menuColumn.previousButton = settingsButton + menuColumn.previousButton.checked = true } @@ -120,7 +124,7 @@ Rectangle { font.family: "Arial" font.pixelSize: 26 color: "#000000" - text: "78.9245" + text: "N/A" } } @@ -144,7 +148,7 @@ Rectangle { font.family: "Arial" font.pixelSize: 18 color: "#000000" - text: "2324.9245" + text: "N/A" } } @@ -179,7 +183,11 @@ Rectangle { anchors.right: parent.right anchors.top: parent.top - property var previousButton: dashboardButton + property var previousButton: transferButton + + // ------------- Dashboard tab --------------- + + /* MenuButton { id: dashboardButton anchors.left: parent.left @@ -195,6 +203,7 @@ Rectangle { } } + Rectangle { anchors.left: parent.left anchors.right: parent.right @@ -202,7 +211,10 @@ Rectangle { color: dashboardButton.checked || transferButton.checked ? "#1C1C1C" : "#505050" height: 1 } + */ + + // ------------- Transfer tab --------------- MenuButton { id: transferButton anchors.left: parent.left @@ -221,10 +233,35 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 16 - color: transferButton.checked || historyButton.checked ? "#1C1C1C" : "#505050" + color: transferButton.checked || receiveButton.checked ? "#1C1C1C" : "#505050" height: 1 } + // ------------- Receive tab --------------- + MenuButton { + id: receiveButton + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Receive") + symbol: qsTr("R") + dotColor: "#AAFFBB" + onClicked: { + parent.previousButton.checked = false + parent.previousButton = receiveButton + panel.receiveClicked() + } + } + /* + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 16 + color: transferButton.checked || historyButton.checked ? "#1C1C1C" : "#505050" + height: 1 + }*/ + + // ------------- History tab --------------- + /* MenuButton { id: historyButton anchors.left: parent.left @@ -246,6 +283,7 @@ Rectangle { color: historyButton.checked || addressBookButton.checked ? "#1C1C1C" : "#505050" height: 1 } + // ------------- AddressBook tab --------------- MenuButton { id: addressBookButton @@ -269,6 +307,7 @@ Rectangle { height: 1 } + // ------------- Mining tab --------------- MenuButton { id: miningButton anchors.left: parent.left @@ -291,6 +330,7 @@ Rectangle { height: 1 } + // ------------- Settings tab --------------- MenuButton { id: settingsButton anchors.left: parent.left @@ -304,9 +344,11 @@ Rectangle { panel.settingsClicked() } } + */ } NetworkStatusItem { + id: networkStatus anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom diff --git a/MiddlePanel.qml b/MiddlePanel.qml index edb4963d..4d65636c 100644 --- a/MiddlePanel.qml +++ b/MiddlePanel.qml @@ -31,6 +31,7 @@ import QtQuick 2.2 Rectangle { color: "#F0EEEE" signal paymentClicked(string address, string paymentId, double amount, int mixinCount) + signal generatePaymentIdInvoked() states: [ State { @@ -42,6 +43,9 @@ Rectangle { }, 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" } @@ -79,6 +83,7 @@ Rectangle { } + /* connect "payment" click */ Connections { ignoreUnknownSignals: false target: loader.item diff --git a/components/IconButton.qml b/components/IconButton.qml new file mode 100644 index 00000000..042439f1 --- /dev/null +++ b/components/IconButton.qml @@ -0,0 +1,72 @@ +// Copyright (c) 2014-2015, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +import QtQuick 2.0 + +Item { + property alias imageSource : buttonImage.source + + signal clicked(var mouse) + + + id: button + width: parent.height + height: parent.height + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + + Image { + id: buttonImage + source: "" + x : (parent.width - width) / 2 + y : (parent.height - height) /2 + z: 100 + } + + MouseArea { + id: buttonArea + anchors.fill: parent + + + onPressed: { + buttonImage.x = buttonImage.x + 2 + buttonImage.y = buttonImage.y + 2 + } + onReleased: { + buttonImage.x = buttonImage.x - 2 + buttonImage.y = buttonImage.y - 2 + } + + onClicked: { + parent.clicked(mouse) + } + } + +} diff --git a/components/Input.qml b/components/Input.qml index c10994d0..78bec8ea 100644 --- a/components/Input.qml +++ b/components/Input.qml @@ -32,6 +32,7 @@ import QtQuick 2.2 TextField { font.family: "Arial" + horizontalAlignment: TextInput.AlignLeft style: TextFieldStyle { textColor: "#3F3F3F" diff --git a/components/LineEdit.qml b/components/LineEdit.qml index 37c2390d..81786881 100644 --- a/components/LineEdit.qml +++ b/components/LineEdit.qml @@ -32,8 +32,10 @@ Item { property alias placeholderText: input.placeholderText property alias text: input.text property alias validator: input.validator + property alias readOnly : input.readOnly property int fontSize: 18 + height: 37 Rectangle { @@ -56,6 +58,5 @@ Item { anchors.leftMargin: 4 anchors.rightMargin: 4 font.pixelSize: parent.fontSize - } } diff --git a/get_libwallet_api.sh b/get_libwallet_api.sh index c9f67ff8..9f8750d0 100755 --- a/get_libwallet_api.sh +++ b/get_libwallet_api.sh @@ -2,6 +2,7 @@ BITMONERO_URL=https://github.com/mbg033/bitmonero +BITMONERO_BRANCH=fee-mul CPU_CORE_COUNT=$(grep -c ^processor /proc/cpuinfo) pushd $(pwd) ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" @@ -13,6 +14,7 @@ BITMONERO_DIR=$ROOT_DIR/bitmonero if [ ! -d $BITMONERO_DIR ]; then git clone --depth=1 $BITMONERO_URL $BITMONERO_DIR + git checkout $BITMONERO_BRANCH else cd $BITMONERO_DIR; git pull; diff --git a/main.qml b/main.qml index 6f90bcf8..c2292798 100644 --- a/main.qml +++ b/main.qml @@ -226,6 +226,7 @@ ApplicationWindow { property bool allow_background_mining : true property bool testnet: true property string daemon_address: "localhost:38081" + property string payment_id } Item { @@ -274,6 +275,7 @@ ApplicationWindow { onDashboardClicked: middlePanel.state = "Dashboard" onHistoryClicked: middlePanel.state = "History" onTransferClicked: middlePanel.state = "Transfer" + onReceiveClicked: middlePanel.state = "Receive" onAddressBookClicked: middlePanel.state = "AddressBook" onMiningClicked: middlePanel.state = "Minning" onSettingsClicked: middlePanel.state = "Settings" @@ -294,7 +296,7 @@ ApplicationWindow { anchors.left: leftPanel.right anchors.right: rightPanel.left height: parent.height - state: "Dashboard" + state: "Transfer" } TipItem { diff --git a/pages/Receive.qml b/pages/Receive.qml new file mode 100644 index 00000000..623c629d --- /dev/null +++ b/pages/Receive.qml @@ -0,0 +1,184 @@ +// Copyright (c) 2014-2015, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import QtQuick 2.0 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.1 + +import "../components" +import moneroComponents 1.0 + +Rectangle { + + color: "#F0EEEE" + property alias addressText : addressLine.text + property alias paymentIdText : paymentIdLine.text + property alias integratedAddressText : integratedAddressLine.text + + function updatePaymentId() { + var payment_id = appWindow.persistentSettings.payment_id + if (payment_id.length === 0) { + payment_id = appWindow.wallet.generatePaymentId() + appWindow.persistentSettings.payment_id = payment_id + appWindow.wallet.payment_id = payment_id + } + paymentIdLine.text = payment_id + addressLine.text = appWindow.wallet.address + integratedAddressLine.text = appWindow.wallet.integratedAddress(payment_id) + } + + Clipboard { id: clipboard } + + + /* main layout */ + ColumnLayout { + id: mainLayout + anchors.margins: 40 + 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 + + + RowLayout { + id: addressRow + + Label { + id: addressLabel + fontSize: 14 + text: qsTr("Address") + width: mainLayout.labelWidth + } + + LineEdit { + id: addressLine + fontSize: mainLayout.lineEditFontSize + placeholderText: "ReadOnly wallet address displayed here"; + readOnly: true + width: mainLayout.editWidth + Layout.fillWidth: true + IconButton { + imageSource: "../images/copyToClipboard.png" + onClicked: { + if (addressLine.text.length > 0) { + clipboard.setText(addressLine.text) + } + } + } + } + } + + RowLayout { + id: integratedAddressRow + Label { + id: integratedAddressLabel + fontSize: 14 + text: qsTr("Integrated address") + width: mainLayout.labelWidth + } + + + LineEdit { + + id: integratedAddressLine + fontSize: mainLayout.lineEditFontSize + placeholderText: "ReadOnly wallet integrated address displayed here"; + readOnly: true + width: mainLayout.editWidth + Layout.fillWidth: true + IconButton { + imageSource: "../images/copyToClipboard.png" + onClicked: { + if (integratedAddressLine.text.length > 0) { + clipboard.setText(integratedAddressLine.text) + } + } + } + + } + } + + RowLayout { + id: paymentIdRow + Label { + id: paymentIdLabel + fontSize: 14 + text: qsTr("Payment ID") + width: mainLayout.labelWidth + } + + + LineEdit { + id: paymentIdLine + fontSize: mainLayout.lineEditFontSize + placeholderText: "PaymentID here"; + readOnly: false + + width: mainLayout.editWidth + Layout.fillWidth: true + + IconButton { + imageSource: "../images/copyToClipboard.png" + onClicked: { + if (paymentIdLine.text.length > 0) { + clipboard.setText(paymentIdLine.text) + } + } + } + } + + StandardButton { + id: generatePaymentId + width: 80 + fontSize: 14 + shadowReleasedColor: "#FF4304" + shadowPressedColor: "#B32D00" + releasedColor: "#FF6C3C" + pressedColor: "#FF4304" + text: qsTr("Generate") + anchors.right: parent.right + onClicked: { + appWindow.persistentSettings.payment_id = appWindow.wallet.generatePaymentId(); + updatePaymentId() + } + } + } + + } + + Component.onCompleted: { + console.log("Receive page loaded"); + updatePaymentId() + } + +} diff --git a/qml.qrc b/qml.qrc index bfa55389..36861fe4 100644 --- a/qml.qrc +++ b/qml.qrc @@ -111,5 +111,7 @@ <file>wizard/WizardRecoveryWallet.qml</file> <file>wizard/WizardMemoTextInput.qml</file> <file>wizard/utils.js</file> + <file>pages/Receive.qml</file> + <file>components/IconButton.qml</file> </qresource> </RCC> diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 4e6b6787..da9cba01 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -88,10 +88,11 @@ bool Wallet::refresh() return result; } -PendingTransaction *Wallet::createTransaction(const QString &dst_addr, quint64 amount, quint32 mixin_count) +PendingTransaction *Wallet::createTransaction(const QString &dst_addr, const QString &payment_id, + quint64 amount, quint32 mixin_count) { Bitmonero::PendingTransaction * ptImpl = m_walletImpl->createTransaction( - dst_addr.toStdString(), amount, mixin_count); + dst_addr.toStdString(), payment_id.toStdString(), amount, mixin_count); PendingTransaction * result = new PendingTransaction(ptImpl, this); return result; } @@ -112,6 +113,26 @@ TransactionHistory *Wallet::history() } +QString Wallet::generatePaymentId() const +{ + return QString::fromStdString(Bitmonero::Wallet::genPaymentId()); +} + +QString Wallet::integratedAddress(const QString &paymentId) const +{ + return QString::fromStdString(m_walletImpl->integratedAddress(paymentId.toStdString())); +} + +QString Wallet::paymentId() const +{ + return m_paymentId; +} + +void Wallet::setPaymentId(const QString &paymentId) +{ + m_paymentId = paymentId; +} + Wallet::Wallet(Bitmonero::Wallet *w, QObject *parent) : QObject(parent), m_walletImpl(w), m_history(nullptr) diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index 4991476a..675ff52e 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -23,6 +23,7 @@ class Wallet : public QObject Q_PROPERTY(quint64 balance READ balance) Q_PROPERTY(quint64 unlockedBalance READ unlockedBalance) Q_PROPERTY(TransactionHistory * history READ history) + Q_PROPERTY(QString paymentId READ paymentId WRITE setPaymentId) public: enum Status { @@ -75,7 +76,7 @@ public: Q_INVOKABLE bool refresh(); //! creates transaction - Q_INVOKABLE PendingTransaction * createTransaction(const QString &dst_addr, + Q_INVOKABLE PendingTransaction * createTransaction(const QString &dst_addr, const QString &payment_id, quint64 amount, quint32 mixin_count); //! deletes transaction and frees memory @@ -84,6 +85,18 @@ public: //! returns transaction history TransactionHistory * history(); + //! generate payment id + Q_INVOKABLE QString generatePaymentId() const; + + //! integrated address + Q_INVOKABLE QString integratedAddress(const QString &paymentId) const; + + + //! saved payment id + QString paymentId() const; + + void setPaymentId(const QString &paymentId); + // TODO: setListenter() when it implemented in API signals: void updated(); @@ -99,6 +112,7 @@ private: Bitmonero::Wallet * m_walletImpl; // history lifetime managed by wallet; TransactionHistory * m_history; + QString m_paymentId; }; #endif // WALLET_H diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml index 0aad0052..d39d52d2 100644 --- a/wizard/WizardCreateWallet.qml +++ b/wizard/WizardCreateWallet.qml @@ -60,7 +60,9 @@ Item { var wallet_filename = oshelper.temporaryFilename(); if (typeof settingsObject.wallet === 'undefined') { //var wallet = walletManager.createWallet(wallet_filename, "", settingsObject.language) - var wallet = walletManager.createWallet(wallet_filename, "", settingsObject.wallet_language) + var testnet = appWindow.persistentSettings.testnet; + var wallet = walletManager.createWallet(wallet_filename, "", settingsObject.wallet_language, + testnet) 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 diff --git a/wizard/WizardRecoveryWallet.qml b/wizard/WizardRecoveryWallet.qml index 19530157..aded7661 100644 --- a/wizard/WizardRecoveryWallet.qml +++ b/wizard/WizardRecoveryWallet.qml @@ -49,7 +49,7 @@ Item { } function recoveryWallet(settingsObject) { - var testnet = true; + var testnet = appWindow.persistentSettings.testnet; var wallet = walletManager.recoveryWallet(oshelper.temporaryFilename(), settingsObject.words, testnet); var success = wallet.status === Wallet.Status_Ok; if (success) { From 409c5701e2004023db58af7575959de4b8256001 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Mon, 27 Jun 2016 15:45:48 +0300 Subject: [PATCH 35/87] Priority aka fee multiplier integrated --- MiddlePanel.qml | 4 ++-- main.qml | 15 +++++++++------ pages/Transfer.qml | 24 ++++++++++++++---------- src/libwalletqt/PendingTransaction.h | 9 ++++++++- src/libwalletqt/Wallet.cpp | 6 ++++-- src/libwalletqt/Wallet.h | 10 ++++++---- 6 files changed, 43 insertions(+), 25 deletions(-) diff --git a/MiddlePanel.qml b/MiddlePanel.qml index 4d65636c..cb1c74d6 100644 --- a/MiddlePanel.qml +++ b/MiddlePanel.qml @@ -30,7 +30,7 @@ import QtQuick 2.2 Rectangle { color: "#F0EEEE" - signal paymentClicked(string address, string paymentId, double amount, int mixinCount) + signal paymentClicked(string address, string paymentId, double amount, int mixinCount, int priority) signal generatePaymentIdInvoked() states: [ @@ -89,7 +89,7 @@ Rectangle { target: loader.item onPaymentClicked : { console.log("MiddlePanel: paymentClicked") - paymentClicked(address, paymentId, amount, mixinCount) + paymentClicked(address, paymentId, amount, mixinCount, priority) } } diff --git a/main.qml b/main.qml index c2292798..a4a8b3ff 100644 --- a/main.qml +++ b/main.qml @@ -169,15 +169,18 @@ ApplicationWindow { return wallets.length > 0; } - function handlePayment(address, paymentId, amount, mixinCount) { - console.log("Process payment here: ", address, paymentId, amount, mixinCount) - // TODO: handle payment id - // TODO: handle fee; - // TODO: handle mixins + function handlePayment(address, paymentId, amount, mixinCount, priority) { + console.log("Creating transaction: ") + console.log("\taddress: ", address, + ", payment_id: ", paymentId, + ", amount: ", amount, + ", mixins: ", mixinCount, + ", priority: ", priority); + var amountxmr = walletManager.amountFromString(amount); console.log("integer amount: ", amountxmr); - var pendingTransaction = wallet.createTransaction(address, amountxmr, mixinCount); + var pendingTransaction = wallet.createTransaction(address, paymentId, amountxmr, mixinCount, priority); if (pendingTransaction.status !== PendingTransaction.Status_Ok) { console.error("Can't create transaction: ", pendingTransaction.errorString); } else { diff --git a/pages/Transfer.qml b/pages/Transfer.qml index e3f96997..5e683f73 100644 --- a/pages/Transfer.qml +++ b/pages/Transfer.qml @@ -27,10 +27,13 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 +import Bitmonero.PendingTransaction 1.0 import "../components" + Rectangle { - signal paymentClicked(string address, string paymentId, double amount, int mixinCount) + signal paymentClicked(string address, string paymentId, double amount, int mixinCount, + int priority) color: "#F0EEEE" @@ -54,7 +57,7 @@ Rectangle { text: qsTr("Amount") fontSize: 14 } - /* + Label { id: transactionPriority anchors.top: parent.top @@ -63,8 +66,6 @@ Rectangle { x: (parent.width - 17) / 2 + 17 text: qsTr("Transaction prority") } - */ - Row { id: amountRow @@ -92,11 +93,11 @@ Rectangle { ListModel { id: priorityModel - ListElement { column1: "LOW"; column2: "( fee: 0.0002 )" } - ListElement { column1: "MEDIUM"; column2: "( fee: 0.0004 )" } - ListElement { column1: "HIGH"; column2: "( fee: 0.0008 )" } + ListElement { column1: "LOW"; column2: ""; priority: PendingTransaction.Priority_Low } + ListElement { column1: "MEDIUM"; column2: ""; priority: PendingTransaction.Priority_Medium } + ListElement { column1: "HIGH"; column2: ""; priority: PendingTransaction.Priority_High } } - /* + StandardDropdown { id: priorityDropdown anchors.top: transactionPriority.bottom @@ -111,7 +112,7 @@ Rectangle { dataModel: priorityModel z: 1 } - */ + Label { @@ -243,7 +244,10 @@ Rectangle { if (addressLine.text.length > 0 && amountLine.text.length > 0) { console.log("paymentClicked") - paymentClicked(addressLine.text, paymentIdLine.text, amountLine.text, scaleValueToMixinCount(privacyLevelItem.fillLevel)) + var priority = priorityModel.get(priorityDropdown.currentIndex).priority + console.log("priority: " + priority) + paymentClicked(addressLine.text, paymentIdLine.text, amountLine.text, scaleValueToMixinCount(privacyLevelItem.fillLevel), + priority) } } } diff --git a/src/libwalletqt/PendingTransaction.h b/src/libwalletqt/PendingTransaction.h index d8c4ec1e..8f5fca1c 100644 --- a/src/libwalletqt/PendingTransaction.h +++ b/src/libwalletqt/PendingTransaction.h @@ -23,9 +23,16 @@ public: Status_Ok = Bitmonero::PendingTransaction::Status_Ok, Status_Error = Bitmonero::PendingTransaction::Status_Error }; - Q_ENUM(Status) + enum Priority { + Priority_Low = Bitmonero::PendingTransaction::Priority_Low, + Priority_Medium = Bitmonero::PendingTransaction::Priority_Medium, + Priority_High = Bitmonero::PendingTransaction::Priority_High + }; + Q_ENUM(Priority) + + Status status() const; QString errorString() const; Q_INVOKABLE bool commit(); diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index da9cba01..e6368ad2 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -89,10 +89,12 @@ bool Wallet::refresh() } PendingTransaction *Wallet::createTransaction(const QString &dst_addr, const QString &payment_id, - quint64 amount, quint32 mixin_count) + quint64 amount, quint32 mixin_count, + PendingTransaction::Priority priority) { Bitmonero::PendingTransaction * ptImpl = m_walletImpl->createTransaction( - dst_addr.toStdString(), payment_id.toStdString(), amount, mixin_count); + dst_addr.toStdString(), payment_id.toStdString(), amount, mixin_count, + static_cast<Bitmonero::PendingTransaction::Priority>(priority)); PendingTransaction * result = new PendingTransaction(ptImpl, this); return result; } diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index 675ff52e..a62c0f14 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -3,13 +3,15 @@ #include <QObject> -#include "wallet/wallet2_api.h" // we need to access Status enum here; +#include "wallet/wallet2_api.h" // we need to have an access to the Bitmonero::Wallet::Status enum here; +#include "PendingTransaction.h" // we need to have an access to the PendingTransaction::Priority enum here; + namespace Bitmonero { class Wallet; // forward declaration } -class PendingTransaction; + class TransactionHistory; class Wallet : public QObject @@ -77,8 +79,8 @@ public: //! creates transaction Q_INVOKABLE PendingTransaction * createTransaction(const QString &dst_addr, const QString &payment_id, - quint64 amount, quint32 mixin_count); - + quint64 amount, quint32 mixin_count, + PendingTransaction::Priority priority = PendingTransaction::Priority_Low); //! deletes transaction and frees memory Q_INVOKABLE void disposeTransaction(PendingTransaction * t); From 39cb75e58c2823e6a25e229596af4e276d77b2ae Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Tue, 28 Jun 2016 22:37:14 +0300 Subject: [PATCH 36/87] Send money: confirmation popups added --- main.cpp | 1 + main.qml | 79 ++++++++++++++++++++++---- src/libwalletqt/PendingTransaction.cpp | 1 + src/libwalletqt/Wallet.h | 2 +- 4 files changed, 71 insertions(+), 12 deletions(-) diff --git a/main.cpp b/main.cpp index 70390a80..7b2799d4 100644 --- a/main.cpp +++ b/main.cpp @@ -56,6 +56,7 @@ int main(int argc, char *argv[]) qmlRegisterUncreatableType<Wallet>("Bitmonero.Wallet", 1, 0, "Wallet", "Wallet can't be instantiated directly"); qmlRegisterUncreatableType<PendingTransaction>("Bitmonero.PendingTransaction", 1, 0, "PendingTransaction", "PendingTransaction can't be instantiated directly"); + qRegisterMetaType<PendingTransaction::Priority>(); QQmlApplicationEngine engine; diff --git a/main.qml b/main.qml index a4a8b3ff..721c69e4 100644 --- a/main.qml +++ b/main.qml @@ -30,6 +30,7 @@ import QtQuick 2.2 import QtQuick.Window 2.0 import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 +import QtQuick.Dialogs 1.2 import Qt.labs.settings 1.0 import Bitmonero.Wallet 1.0 import Bitmonero.PendingTransaction 1.0 @@ -47,6 +48,7 @@ ApplicationWindow { property bool osx: false property alias persistentSettings : persistentSettings property var wallet; + property var transaction; function altKeyReleased() { ctrlPressed = false; } @@ -133,6 +135,10 @@ ApplicationWindow { wallet = walletManager.openWallet(wallet_path, "", persistentSettings.testnet); if (wallet.status !== Wallet.Status_Ok) { console.log("Error opening wallet: ", wallet.errorString); + informationPopup.title = qsTr("Error"); + informationPopup.text = qsTr("Couldn't open wallet: ") + wallet.errorString; + informationPopup.icon = StandardIcon.Critical + informationPopup.open() return; } console.log("Wallet opened successfully: ", wallet.errorString); @@ -169,6 +175,8 @@ ApplicationWindow { return wallets.length > 0; } + + // called on "transfer" function handlePayment(address, paymentId, amount, mixinCount, priority) { console.log("Creating transaction: ") console.log("\taddress: ", address, @@ -180,22 +188,53 @@ ApplicationWindow { var amountxmr = walletManager.amountFromString(amount); console.log("integer amount: ", amountxmr); - var pendingTransaction = wallet.createTransaction(address, paymentId, amountxmr, mixinCount, priority); - if (pendingTransaction.status !== PendingTransaction.Status_Ok) { - console.error("Can't create transaction: ", pendingTransaction.errorString); + transaction = wallet.createTransaction(address, paymentId, amountxmr, mixinCount, priority); + if (transaction.status !== PendingTransaction.Status_Ok) { + console.error("Can't create transaction: ", transaction.errorString); + informationPopup.title = qsTr("Error"); + informationPopup.text = qsTr("Can't create transaction: ") + transaction.errorString + informationPopup.icon = StandardIcon.Critical + informationPopup.open(); + // deleting transaction object, we don't want memleaks + wallet.disposeTransaction(transaction); + } else { - console.log("Transaction created, amount: " + walletManager.displayAmount(pendingTransaction.amount) - + ", fee: " + walletManager.displayAmount(pendingTransaction.fee)); - if (!pendingTransaction.commit()) { - console.log("Error committing transaction: " + pendingTransaction.errorString); - } else { - wallet.refresh(); - } + console.log("Transaction created, amount: " + walletManager.displayAmount(transaction.amount) + + ", fee: " + walletManager.displayAmount(transaction.fee)); + + // here we show confirmation popup; + + transactionConfirmationPopup.title = qsTr("Confirmation") + transactionConfirmationPopup.text = qsTr("Please confirm transaction:\n\n") + + "\naddress: " + address + + "\npayment id: " + paymentId + + "\namount: " + walletManager.displayAmount(transaction.amount) + + "\nfee: " + walletManager.displayAmount(transaction.fee) + transactionConfirmationPopup.icon = StandardIcon.Question + transactionConfirmationPopup.open() + // committing transaction + } + } + + // called after user confirms transaction + function handleTransactionConfirmed() { + if (!transaction.commit()) { + console.log("Error committing transaction: " + transaction.errorString); + informationPopup.title = qsTr("Error"); + informationPopup.text = qsTr("Couldn't send the money: ") + transaction.errorString + informationPopup.icon = StandardIcon.Critical + } else { + informationPopup.title = qsTr("Information") + informationPopup.text = qsTr("Money sent successfully") + informationPopup.icon = StandardIcon.Information } - wallet.disposeTransaction(pendingTransaction); + informationPopup.open() + wallet.refresh() + wallet.disposeTransaction(transaction) } + visible: true width: rightPanelExpanded ? 1269 : 1269 - 300 height: 800 @@ -232,6 +271,24 @@ ApplicationWindow { property string payment_id } + // TODO: replace with customized popups + + // Information dialog + MessageDialog { + id: informationPopup + standardButtons: StandardButton.Ok + } + + // Confrirmation aka question dialog + MessageDialog { + id: transactionConfirmationPopup + standardButtons: StandardButton.Ok + StandardButton.Cancel + onAccepted: { + handleTransactionConfirmed() + } + } + + Item { id: rootItem anchors.fill: parent diff --git a/src/libwalletqt/PendingTransaction.cpp b/src/libwalletqt/PendingTransaction.cpp index a5dc458d..8c0d8c29 100644 --- a/src/libwalletqt/PendingTransaction.cpp +++ b/src/libwalletqt/PendingTransaction.cpp @@ -1,5 +1,6 @@ #include "PendingTransaction.h" + PendingTransaction::Status PendingTransaction::status() const { return static_cast<Status>(m_pimpl->status()); diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index a62c0f14..241b89d8 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -80,7 +80,7 @@ public: //! creates transaction Q_INVOKABLE PendingTransaction * createTransaction(const QString &dst_addr, const QString &payment_id, quint64 amount, quint32 mixin_count, - PendingTransaction::Priority priority = PendingTransaction::Priority_Low); + PendingTransaction::Priority priority); //! deletes transaction and frees memory Q_INVOKABLE void disposeTransaction(PendingTransaction * t); From a594e25b26aff323daaca21c580e5163cc2a2a1b Mon Sep 17 00:00:00 2001 From: dEBRUYNE-1 <dEBRUYNE-1@users.noreply.github.com> Date: Tue, 28 Jun 2016 22:14:30 +0200 Subject: [PATCH 37/87] Clean up text --- main.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main.qml b/main.qml index 721c69e4..e890a75b 100644 --- a/main.qml +++ b/main.qml @@ -206,10 +206,10 @@ ApplicationWindow { transactionConfirmationPopup.title = qsTr("Confirmation") transactionConfirmationPopup.text = qsTr("Please confirm transaction:\n\n") - + "\naddress: " + address - + "\npayment id: " + paymentId - + "\namount: " + walletManager.displayAmount(transaction.amount) - + "\nfee: " + walletManager.displayAmount(transaction.fee) + + "\nAddress: " + address + + "\nPayment ID: " + paymentId + + "\nAmount: " + walletManager.displayAmount(transaction.amount) + + "\nFee: " + walletManager.displayAmount(transaction.fee) transactionConfirmationPopup.icon = StandardIcon.Question transactionConfirmationPopup.open() // committing transaction From f846935f95abd892b3bcb708632d827a8fb29f7d Mon Sep 17 00:00:00 2001 From: dEBRUYNE-1 <dEBRUYNE-1@users.noreply.github.com> Date: Tue, 28 Jun 2016 22:21:02 +0200 Subject: [PATCH 38/87] Fix typo --- pages/Transfer.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/Transfer.qml b/pages/Transfer.qml index 5e683f73..aa79c18f 100644 --- a/pages/Transfer.qml +++ b/pages/Transfer.qml @@ -64,7 +64,7 @@ Rectangle { anchors.topMargin: 17 fontSize: 14 x: (parent.width - 17) / 2 + 17 - text: qsTr("Transaction prority") + text: qsTr("Transaction priority") } Row { From 0c093423f1da576d8b92363cc1e2f6dded8e907a Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Fri, 1 Jul 2016 15:02:19 +0300 Subject: [PATCH 39/87] Fixed for MSYS2 build --- get_libwallet_api.sh | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/get_libwallet_api.sh b/get_libwallet_api.sh index 9f8750d0..7410365a 100755 --- a/get_libwallet_api.sh +++ b/get_libwallet_api.sh @@ -1,7 +1,7 @@ #!/bin/bash -BITMONERO_URL=https://github.com/mbg033/bitmonero +BITMONERO_URL=https://github.com/mbg033/bitmonero.git BITMONERO_BRANCH=fee-mul CPU_CORE_COUNT=$(grep -c ^processor /proc/cpuinfo) pushd $(pwd) @@ -13,8 +13,7 @@ BITMONERO_DIR=$ROOT_DIR/bitmonero if [ ! -d $BITMONERO_DIR ]; then - git clone --depth=1 $BITMONERO_URL $BITMONERO_DIR - git checkout $BITMONERO_BRANCH + git clone --depth=1 $BITMONERO_URL $BITMONERO_DIR --branch $BITMONERO_BRANCH --single-branch else cd $BITMONERO_DIR; git pull; @@ -24,7 +23,21 @@ rm -fr $BITMONERO_DIR/build mkdir -p $BITMONERO_DIR/build/release pushd $BITMONERO_DIR/build/release -cmake -D CMAKE_BUILD_TYPE=Release -D STATIC=ON -D CMAKE_INSTALL_PREFIX="$BITMONERO_DIR" ../.. + +if [ "$(uname)" == "Darwin" ]; then + # Do something under Mac OS X platform + cmake -D CMAKE_BUILD_TYPE=Release -D STATIC=ON -D CMAKE_INSTALL_PREFIX="$BITMONERO_DIR" ../.. +elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then + # Do something under GNU/Linux platform + cmake -D CMAKE_BUILD_TYPE=Release -D STATIC=ON -D CMAKE_INSTALL_PREFIX="$BITMONERO_DIR" ../.. +elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then + # Do something under Windows NT platform + cmake -D CMAKE_BUILD_TYPE=Release -D STATIC=ON -D CMAKE_INSTALL_PREFIX="$BITMONERO_DIR" -G "MinGW Makefiles" ../.. + +elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]; then + # Do something under Windows NT platform +fi + pushd $BITMONERO_DIR/build/release/src/wallet make -j$CPU_CORE_COUNT From d880441f7e2631854803dd95458d11bef1a145a3 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Mon, 4 Jul 2016 18:17:26 +0300 Subject: [PATCH 40/87] MSYS2/Win64 build fixed --- get_libwallet_api.sh | 4 ++-- monero-core.pro | 31 ++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/get_libwallet_api.sh b/get_libwallet_api.sh index 7410365a..60f86d32 100755 --- a/get_libwallet_api.sh +++ b/get_libwallet_api.sh @@ -32,10 +32,10 @@ elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then cmake -D CMAKE_BUILD_TYPE=Release -D STATIC=ON -D CMAKE_INSTALL_PREFIX="$BITMONERO_DIR" ../.. elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then # Do something under Windows NT platform - cmake -D CMAKE_BUILD_TYPE=Release -D STATIC=ON -D CMAKE_INSTALL_PREFIX="$BITMONERO_DIR" -G "MinGW Makefiles" ../.. - + cmake -D CMAKE_BUILD_TYPE=Release -D STATIC=ON -D CMAKE_INSTALL_PREFIX="$BITMONERO_DIR" -G "MSYS Makefiles" ../.. elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]; then # Do something under Windows NT platform + cmake -D CMAKE_BUILD_TYPE=Release -D STATIC=ON -D CMAKE_INSTALL_PREFIX="$BITMONERO_DIR" -G "MSYS Makefiles" ../.. fi diff --git a/monero-core.pro b/monero-core.pro index 8ce4a16a..b345a3d7 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -42,12 +42,41 @@ SOURCES = *.qml \ LIBS += -L$$WALLET_ROOT/lib \ -lwallet_merged \ + -lwallet_merged2 + +win32 { + #QMAKE_LFLAGS += -static + LIBS+= \ + -Wl,-Bstatic \ + -lboost_serialization-mt \ + -lboost_thread-mt \ + -lboost_system-mt \ + -lboost_date_time-mt \ + -lboost_filesystem-mt \ + -lboost_regex-mt \ + -lboost_chrono-mt \ + -lboost_program_options-mt \ + -lssl \ + -lcrypto \ + -Wl,-Bdynamic \ + -lws2_32 \ + -lwsock32 \ + -lIphlpapi \ + -lgdi32 +} + +unix { + LIBS+= \ -lboost_serialization \ -lboost_thread \ -lboost_system \ -lboost_date_time \ -lboost_filesystem \ - -lboost_regex + -lboost_regex \ + -lboost_chrono \ + -lboost_program_options + +} From da43e9a93a8cac57a8c993ba823dddddefa4af3f Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Mon, 4 Jul 2016 18:25:03 +0300 Subject: [PATCH 41/87] "Compiling" section stub added to documentation --- README.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b10c94cf..091fb303 100644 --- a/README.md +++ b/README.md @@ -61,4 +61,22 @@ Redistribution and use in source and binary forms, with or without modification, 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. -Parts of the project are originally copyright (c) 2012-2013 The Cryptonote developers \ No newline at end of file +Parts of the project are originally copyright (c) 2012-2013 The Cryptonote developers + +## Compiling Monero-core + +### Overview: + +Dependencies: TODO + +Process: TODO + + +### On Linux: +TODO + +### On OS X: +TODO + +### On Windows: +TODO From fca82f347d29429e3ad662897a38923e3258a643 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.comm> Date: Wed, 6 Jul 2016 16:24:14 +0300 Subject: [PATCH 42/87] Cross-plaftorm number of cpu cores --- get_libwallet_api.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/get_libwallet_api.sh b/get_libwallet_api.sh index 60f86d32..520bba17 100755 --- a/get_libwallet_api.sh +++ b/get_libwallet_api.sh @@ -3,7 +3,8 @@ BITMONERO_URL=https://github.com/mbg033/bitmonero.git BITMONERO_BRANCH=fee-mul -CPU_CORE_COUNT=$(grep -c ^processor /proc/cpuinfo) +# thanks to SO: http://stackoverflow.com/a/20283965/4118915 +CPU_CORE_COUNTS=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu) pushd $(pwd) ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" From 5b1ab69d70a29c4ddf66d5f107f621ed3340d066 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 6 Jul 2016 16:25:41 +0300 Subject: [PATCH 43/87] Mac OSX build steps added --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 091fb303..25caa911 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,11 @@ Process: TODO TODO ### On OS X: -TODO +1. install homebrew +2. install dependencies: +`brew install boost --c++11` +`brew install pkgconfig` + ### On Windows: TODO From c027922cb710ca78e400c30268f5ceaec10a7e49 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 13 Jul 2016 10:30:12 +0300 Subject: [PATCH 44/87] fixed multicore build; statically link boost, libcrypto and libssl for Linux; --- get_libwallet_api.sh | 4 ++-- monero-core.pro | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/get_libwallet_api.sh b/get_libwallet_api.sh index 520bba17..9e69235e 100755 --- a/get_libwallet_api.sh +++ b/get_libwallet_api.sh @@ -2,9 +2,9 @@ BITMONERO_URL=https://github.com/mbg033/bitmonero.git -BITMONERO_BRANCH=fee-mul +BITMONERO_BRANCH=devel # thanks to SO: http://stackoverflow.com/a/20283965/4118915 -CPU_CORE_COUNTS=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu) +CPU_CORE_COUNT=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu) pushd $(pwd) ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" diff --git a/monero-core.pro b/monero-core.pro index b345a3d7..84d4f35a 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -67,6 +67,7 @@ win32 { unix { LIBS+= \ + -Wl,-Bstatic \ -lboost_serialization \ -lboost_thread \ -lboost_system \ @@ -74,8 +75,11 @@ unix { -lboost_filesystem \ -lboost_regex \ -lboost_chrono \ - -lboost_program_options - + -lboost_program_options \ + -lssl \ + -lcrypto \ + -Wl,-Bdynamic \ + -ldl } From d9f031ec2a3b6dc256ea138a8aa8326e41130e4b Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 13 Jul 2016 15:24:40 +0300 Subject: [PATCH 45/87] Async API integration in progress --- main.cpp | 1 + main.qml | 43 +++++++++++++++++++++++++++++-------- src/libwalletqt/Wallet.cpp | 44 ++++++++++++++++++++++++++++++++++++++ src/libwalletqt/Wallet.h | 9 ++++++++ 4 files changed, 88 insertions(+), 9 deletions(-) diff --git a/main.cpp b/main.cpp index 7b2799d4..43ef8186 100644 --- a/main.cpp +++ b/main.cpp @@ -56,6 +56,7 @@ int main(int argc, char *argv[]) qmlRegisterUncreatableType<Wallet>("Bitmonero.Wallet", 1, 0, "Wallet", "Wallet can't be instantiated directly"); qmlRegisterUncreatableType<PendingTransaction>("Bitmonero.PendingTransaction", 1, 0, "PendingTransaction", "PendingTransaction can't be instantiated directly"); + qRegisterMetaType<PendingTransaction::Priority>(); diff --git a/main.qml b/main.qml index e890a75b..b96b5dea 100644 --- a/main.qml +++ b/main.qml @@ -35,6 +35,7 @@ import Qt.labs.settings 1.0 import Bitmonero.Wallet 1.0 import Bitmonero.PendingTransaction 1.0 + import "components" import "wizard" @@ -50,6 +51,7 @@ ApplicationWindow { property var wallet; property var transaction; + function altKeyReleased() { ctrlPressed = false; } function showPageRequest(page) { @@ -122,7 +124,7 @@ ApplicationWindow { function initialize() { - + console.log("initializing..") middlePanel.paymentClicked.connect(handlePayment); if (typeof wizard.settings['wallet'] !== 'undefined') { @@ -143,24 +145,34 @@ ApplicationWindow { } console.log("Wallet opened successfully: ", wallet.errorString); } + // display splash screen... + console.log("initializing with daemon address..") if (!wallet.init(persistentSettings.daemon_address, 0)) { console.log("Error initialize wallet: ", wallet.errorString); return } + console.log("Wallet initialized successfully") + // TODO: update network indicator // subscribing for wallet updates wallet.updated.connect(onWalletUpdate); - + wallet.refreshed.connect(onWalletRefresh); + console.log("refreshing wallet async") // TODO: refresh asynchronously without blocking UI, implement signal(s) - wallet.refresh(); - + wallet.refreshAsync(); console.log("wallet balance: ", wallet.balance) } function onWalletUpdate() { - console.log("wallet updated") + console.log(">>> wallet updated") + leftPanel.unlockedBalanceText = walletManager.displayAmount(wallet.unlockedBalance); + leftPanel.balanceText = walletManager.displayAmount(wallet.balance); + } + + function onWalletRefresh() { + console.log(">>> wallet refreshed") leftPanel.unlockedBalanceText = walletManager.displayAmount(wallet.unlockedBalance); leftPanel.balanceText = walletManager.displayAmount(wallet.balance); } @@ -206,10 +218,10 @@ ApplicationWindow { transactionConfirmationPopup.title = qsTr("Confirmation") transactionConfirmationPopup.text = qsTr("Please confirm transaction:\n\n") - + "\nAddress: " + address - + "\nPayment ID: " + paymentId - + "\nAmount: " + walletManager.displayAmount(transaction.amount) - + "\nFee: " + walletManager.displayAmount(transaction.fee) + + qsTr("\nAddress: ") + address + + qsTr("\nPayment ID: ") + paymentId + + qsTr("\nAmount: ") + walletManager.displayAmount(transaction.amount) + + qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee) transactionConfirmationPopup.icon = StandardIcon.Question transactionConfirmationPopup.open() // committing transaction @@ -288,6 +300,19 @@ ApplicationWindow { } } + Window { + id: walletInitializationSplash + modality: Qt.ApplicationModal + flags: Qt.SplashScreen + height: 100 + width: 250 + Text { + anchors.fill: parent + text: qsTr("Initializing Wallet..."); + } + + } + Item { id: rootItem diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index e6368ad2..3697984e 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -14,6 +14,45 @@ namespace { } +class WalletListenerImpl : public Bitmonero::WalletListener +{ +public: + WalletListenerImpl(Wallet * w) + : m_wallet(w) + { + + } + + virtual void moneySpent(const std::string &txId, uint64_t amount) + { + // TODO + Q_UNUSED(txId) + Q_UNUSED(amount) + } + + virtual void moneyReceived(const std::string &txId, uint64_t amount) + { + // TODO + Q_UNUSED(txId) + Q_UNUSED(amount) + } + + virtual void updated() + { + emit m_wallet->updated(); + } + + // called when wallet refreshed by background thread or explicitly + virtual void refreshed() + { + emit m_wallet->refreshed(); + } + +private: + Wallet * m_wallet; +}; + + QString Wallet::getSeed() const { @@ -88,6 +127,11 @@ bool Wallet::refresh() return result; } +void Wallet::refreshAsync() +{ + m_walletImpl->refreshAsync(); +} + PendingTransaction *Wallet::createTransaction(const QString &dst_addr, const QString &payment_id, quint64 amount, quint32 mixin_count, PendingTransaction::Priority priority) diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index 241b89d8..4d6a1ea0 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -77,6 +77,10 @@ public: //! refreshes the wallet Q_INVOKABLE bool refresh(); + + //! refreshes the wallet asynchronously + Q_INVOKABLE void refreshAsync(); + //! creates transaction Q_INVOKABLE PendingTransaction * createTransaction(const QString &dst_addr, const QString &payment_id, quint64 amount, quint32 mixin_count, @@ -103,6 +107,10 @@ public: signals: void updated(); + // emitted when refresh process finished (could take a long time) + // signalling only after we + void refreshed(); + private: Wallet(Bitmonero::Wallet *w, QObject * parent = 0); @@ -110,6 +118,7 @@ private: private: friend class WalletManager; + friend class WalletListenerImpl; //! libwallet's Bitmonero::Wallet * m_walletImpl; // history lifetime managed by wallet; From 7df82af75d66a66b2c156f74d3a9fee45a5c178a Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 13 Jul 2016 16:01:56 +0300 Subject: [PATCH 46/87] New flags images, added IT,RU,ZH translation files --- lang/flags/bangladesh.png | Bin 1340 -> 9356 bytes lang/flags/brazil.png | Bin 2110 -> 12687 bytes lang/flags/china.png | Bin 1282 -> 9669 bytes lang/flags/german.png | Bin 731 -> 7150 bytes lang/flags/india.png | Bin 846 -> 10228 bytes lang/flags/italy.png | Bin 0 -> 7974 bytes lang/flags/palestine.png | Bin 1173 -> 7164 bytes lang/flags/rpa.png | Bin 2177 -> 11279 bytes lang/flags/russia.png | Bin 805 -> 8911 bytes lang/flags/uk.png | Bin 1995 -> 12940 bytes lang/flags/usa.png | Bin 1716 -> 11316 bytes lang/languages.xml | 3 +- monero-core.pro | 8 +- monero-core_de.ts | 273 +++++++++----- monero-core_en.ts | 273 +++++++++----- monero-core_it.ts | 755 ++++++++++++++++++++++++++++++++++++++ monero-core_ru.ts | 755 ++++++++++++++++++++++++++++++++++++++ monero-core_zh.ts | 755 ++++++++++++++++++++++++++++++++++++++ qml.qrc | 1 + wizard/WizardWelcome.qml | 2 +- 20 files changed, 2617 insertions(+), 208 deletions(-) create mode 100644 lang/flags/italy.png create mode 100644 monero-core_it.ts create mode 100644 monero-core_ru.ts create mode 100644 monero-core_zh.ts diff --git a/lang/flags/bangladesh.png b/lang/flags/bangladesh.png index 099b7eee38bf31b3ef01524ccc76322204cf63c8..6fc33574df0723f2adbbc8b5cae5227f2cec27ce 100644 GIT binary patch literal 9356 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 GLSTX{Y5e2> literal 1340 zcmV-C1;hG@P)<h;3K|Lk000e1NJLTq001%o001%w1^@s69zTe&00004b3#c}2nYxW zd<bNS00009a7bBm000XT000XT0n*)m`~Uy|9CSrkbW?9;ba!ELWdK2BZ(?O2Mrm?o zcW-iQb09-gHt4*vi~s-t7IZ~ebVG7wVRUJ4ZXi@?ZDjy3I4?0VFEKQ>m=cNr00fjt zL_t(&fz_H%Xd_h|$3K}QRW|4b+=)_<v;h&y#;vjos|d{!PafLcoAhFec=1%PuF!O0 zZ-U*ki1E_(7(IxWvaQHkVGn_nf-H0sSQgt{#={geZN|f!Y0_!(-kZrJbw4m<X7c8} z_nqJG{ocQcUH)vI2r0P7lzRZoxxY=I;ht~0=bJtEh9WWK^J(Cwdn_o@X59n2;y?(j zxJM&wMU0TorGc_r@OP+1$jAaKz!QXp3Slw{BczNFumW5RQ>cVF-~mvj>zY~w5i$$Z z7>xiw3vOA<x)10IDIv^$C2*C(a}oF&VV$%pv5t@mq8*Id3WHccyhN!Om5>VX@vt?? zS<bLoTtT?nKryoLTOovqV&j;6%OPiVnEv~$06Pggra|2__<hpgAQjWiI!iaIS^hs` z13JVK!kx6p*bW~wkC}gbOscK>lwij+Sf7bgH?`x=7JWi=Jag?$|Gin@2jE4WTo-qb zSblWGJNph39o@Qg$s9Tqn;qV2In+%9dqQcUDIkWh&I$d5{6e<}9!RPUcYbSAY<5Bk z@RK<dR(<-i!PA$NVhRY$G`t&rdoH69Vsn<mw?F^G<yHg=dPue5_QN*C#<5QFwcd+f zi=+`TTk297+u^GR{|0UgLAd^`!@-3ZPtwwM^BQ8DR)f<PSw_)Uq}uT1!}dr;oK)t~ z5qY)6%if7!h?K?MqrM?^RNPj-v@BxeeIn#03TxzB9p)cv`EF#S+VE-ZNR_MvT_Gh^ z>c!phits2lkIC3lFIWIhT2n!mGG{rFN2nlZyu^Zm=m4c|HEx&kbN!i~kb)|eM)Vjd zskR8o5@rn)!{dzYkU1P*q#8udk_wqqTIALLfe3(nOI{D<kn_CVN|&&!C}T$vf}bBD zC<esOjgW&2awSS30cLLJih*yY<!4{<CdNhGR9ocCM821UR4m8>!N}N?&rP<J76GVV zI$!s)ldwH0twYT~%&??Z`RR>#l=TYC_N21>O;6^QEY)5*cCL+neMVnMMV0ctI<t|m zk&Ua`=#PNq38|uRuexcB-No!Ad^4-ui>kose&n9&iS?NTd+G5-u)FUiv6Ipy4TKR+ z30Xs76*~!c-&JNF32RpqI_+}RJLyen_5Lx4gH((!<|aleX6<T%jVYxY*XU{6e#vWY z0x5gx7@vIjLgbOmP6~I@5CQOc??u10-#>tlP^>t%<G2OJ$XUa$|JF@|mG_hU`HI%d zS;ZG=`w96A*vDP?Qn6zi{Q7zvdm@~mx@mClT7vsC37wUA5F?Q#|II=BBOvxiO2Min z)}it(hiR+Rcc;ouiptkbgY94&Js{lv27Q8(EJ%B*OF>H7$i~_5ZA#=UCyKD$V1Niv z&qtQf==D`ZAfg7mjih_fX<1A3@yRh#MPdmL-S}BSyb)z+jt~p6LvRa)2naT3_sm<? z$#_VrZduA<lSh~yZ55biG=eq}Zgh))UkZion!Vx7G$N{1L*@gb!euwF8)(c}`!VeI yS{CrVdw}@5r@-kC&kF8ugR>u=o!XflhW`K-ltk%0phMFD0000<MNUMnLSTZ!v3Xbk diff --git a/lang/flags/brazil.png b/lang/flags/brazil.png index baa62b9d71f31de819c4b18fec91dae0e164cc06..1438aa0d64d848056fe26e3d642466ef398ecbef 100644 GIT binary patch literal 12687 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 JPDHLkV1kW4v-to3 literal 2110 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 diff --git a/lang/flags/china.png b/lang/flags/china.png index 5f3c6fc846589c8342bf9e84b4829830e0bd7163..dfe1fb66dc002c3ab14e027718d07d8fd4fa5442 100644 GIT binary patch literal 9669 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 Hu0mjfc(^rr literal 1282 zcmV+d1^xPoP)<h;3K|Lk000e1NJLTq001%o001%w1^@s69zTe&00004b3#c}2nYxW zd<bNS00009a7bBm000XT000XT0n*)m`~Uy|9CSrkbW?9;ba!ELWdK2BZ(?O2Mrm?o zcW-iQb09-gHt4*vi~s-t7IZ~ebVG7wVRUJ4ZXi@?ZDjy3I4?0VFEKQ>m=cNr00de| zL_t(&f!&%tY}-Z{h98o$AykS?!3f|KMr#L}x|G>tM41{-&CsGl2ggIV21(JWQ{)0g zyVXIaPUfBt$>c4yVNdSju7v@+MT$BGT+6l$II<~rI8tIL{vE04Cl7G2WF7DBz3=Y3 z@9wB<O<$)+=s*=PoTNMHW9RojfVz{mowVkB&y12$$P927xJReKvOEW#IVrWMv_fWp z8nBSI;sA~T6IcfJWFM9lqB|935}*|!Us2oN&$e6sEK5#3i7lkYXK8Z}(NmeNU^SpT zuQK~M$K>ZKTCpq3Bg7o4CM`3G5FKIi6<{K1!BLD)DO{Ozs<xpt7ubvsf!`2AI2P@z zQaS2(9pPC%i7Tiyr*id6jg!r;VbWb`QQ_4u7ASE1!j5~U3d|y$K`2ocaYZEZMx~o- zr<Y@B?%MzyKD9XC>4*pzVlE4aQ4va5%~B!&uFR=uh0tLVh}96uC0|jQ{w_zsP{~&m zfA&Z*VYQk_h$uNCKv*UV`W@i}E*z`*SRiE11i9abz|Ub7<tqvw{E%aOs;kFB`S*#% z;jdO?o_s~2d`Cr}*U*Y^U|Jlkgg$c{F=E>Ih0FlEaShXoF!gng@_cmfpYPbb{PB|W zoxt7=<l23$Ex<eMeEfw7gWBti-)lWXh>65*!s%v<i&r)ULq#3$&U3Wd;^p_3T<j+k z;L_N#v74ff2z1~z9;<k}v<lpksq|>I#c6=+w9eq4pDv?%v==<W)9GFzwKSy#xm;QA zm4TZ3!L7|e(i-rlw>ns{*nQBkLR#-tFr=Qlix_5YArI44s?glG*?n-yfoXBJ-Qv$L znw)I3DBMWy)j)Wyf}wKlzD9XorC<ccV16bLV%n441oE;%#wHc^pIE&9yW^GYCLF(L zfvsTu7wLK4z;43(-)g+~kr2`Ny_MA4l>sw{nB=K~!K2mi7%6Vu@MAULWYcDB%0^M( zWFtOibGQZQu8^VNbfd-LQ;U2>K`SP=CQuzJA#N}!vw%7nIh<MFPqZS;J|3gFZ*#t5 zM};CuF><6oG)Rrr5Zl|y&ooLm#s4yj(R00Mm@N5<f?807HB3upVuzw^O<$KDkiEi< zpqs%Vy9~zzv4~3#1h`D}B_Qep>+gyXRK)qws8d%FN0p<_wu*1>JEFWZLe^X%J-MS8 z5bHQ|1jHT1sA58Ahqyerc4VTCb0+Kxaj(HfjpsPi!n+_Y4W=!bsJS1!Le>~9t1RKU zqVtC+i+ycMdiL<mYrl{^;F~@*CJT%BmW-gFahaIgp#if*z!V6Jeis?eVA3SyXg5qq z9dQRSOkzwT=5W-0WSGR5#5kh3jg>3L>`i-8Q6qsjO|nC*I|X%linq)jq7xG>)G}LL z6LH^d%C;y4HQ)vk3$*N>-L=l!5L8FF{#k?-q^#eI*PK2@yr*KMEW>@psT}~OA*&EC sI^u}m|Kgb|aLxJaeerCa9?iS|0giG;PJue>S^xk507*qoM6N<$f`6!1lK=n! diff --git a/lang/flags/german.png b/lang/flags/german.png index 7756bf592a23d2bc31cd951f3ee6e12fdfa5af8b..320b24ef97237f3fdc51b55d10a72b2de7f291e5 100644 GIT binary patch literal 7150 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 delta 727 zcmV;|0x13NH`@hDiBL{Q4GJ0x0000DNk~Le0000o0000o2nGNE03JVxu>b%71am@3 zR0s$N2z&@+hyVZp32;bRa{vGf5&!@T5&_cPe*6Fc034IS8xwy<X>w(EZ*psMAVX6& z=)AIw0000MbVXQnLvm$dbZKvHAXI5>WdJZZFEKGMF*LTA5{du-0y9ZOK~!jg?V7)C z+b|G^KNA_+DFnK=%G9xbgCs+NjOi1!-a5vQ(aqU1%5R`YaHp)w)~)IraOvC*M+K@Z z>kmbVRFMz3!H|DI{m#cD?<lSChX$^IwKZ++gT4L)7;Cw;gZ&*G4csB3{y180$Ivrt z2Ot5`9wLWYYR8@&4eTaxpl&-RjL<DIpQm=BG-IFXl{uo&7M;;(rpX1D+;N_2nsKX< zZ_8bs$s!P6w``~rA#<Y3dgsh-1Y*0ab2Zb<yTrPhp(B4^(g;NMwe*w|Nd)4CTGHf5 z8iBCUQCVU%{)x)jM_vQmAREpSxd9$l1#bZg;9XET?)(B0g@k6QPJn1n6w;n9ohya( z*Gp&p;z(qy6>uI}g$K@6Xa&A_aU?brksMi$#3<xUcIiARmRl@V$^R=y4xv?e;GmEa zz6h&h6a{}!oV|H`1@H~{8dQ!u4*;v*Ki-4%BtJu{8NmfmlpA6J?89ksW{*va>dx-v z_<m-dHCG+USyoi`RJM*XM@lr3D?wgN4!|I}@myZji$()%=2Ya!hFXo-RQ+ba{Va0a zxToPg$*D5_uIc6o$PjHuwDlt!;;O@PTBd!QBL;uCrsep4Mp8t}$=<1}LoAa&<Q}u5 zA-U`HZFRT6r>?;~W9&1xeQqAovuDWKJx6qQ_F26boS}yg2Kk3Bm?n2pJNA}=(Xa39 zL(#xz;0x|2mO0|Uo)J@btRq!4aLMt9XQhKV#~+@3$5Y<@1y>1Yx+}4ZDgXcg07*qo JM6LruV1i{YKwkg= diff --git a/lang/flags/india.png b/lang/flags/india.png index bf27a1737beea297facfe93afc859f33b1603902..1e56cb3bb7be123a859676e5438f44a8122a25e2 100644 GIT binary patch literal 10228 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 literal 846 zcmV-U1F`&xP)<h;3K|Lk000e1NJLTq001%o001%w1^@s69zTe&00004b3#c}2nYxW zd<bNS00009a7bBm000XT000XT0n*)m`~Uy|9CSrkbW?9;ba!ELWdK2BZ(?O2Mrm?o zcW-iQb09-gHt4*vi~s-t7IZ~ebVG7wVRUJ4ZXi@?ZDjy3I4?0VFEKQ>m=cNr00O2- zL_t(&f!&%hY|}s#hCf@GLYEAP0fmjKsk$I_3IeGE3IhY_nyOP^Lh2e81}4@>Owb86 zjLpK(hye+SOdYERwHsOJl%@4*hIfgK6UX-1v3>ofNU`tzzwNtw@7dPm;}cS11K0t! zfpy>^um;>w|K9-Dz$I`2oB}_9-)RK55*n!i`#=k*YK}1mdcYT8q$|YMJg*L%0Ovpl zeG{m2J8G;GHFj*`8mR)uz%QVo6EK8^8vB@-7blL9Hu5|-;{?#8sbaOGo)E=I88`wy ztKV5sRxyvF#0@i20lp)XIWJmDLuJ`P%ZyZjpJ-0Ll&K?H0?h;&DFfettrdvUWed@? z@G%QA@`+;H2|sm2+Z>CGw8?i)gwbNbYUVdm1-hBYNk$jnKI1piCEF!dmomN!?ln>; zo6RmQnt0~1*T}o<wIpVyd1|D_YI3Jl(?GOSD&2nsl8T$kKJeCZT^HaF$x`t=83PY2 z*L62YP|y^FnvImFrn6%sHMZ$&+eo9pbk;4`b^ikQ@>Y_ND;sIqn9iEzs`b}&blX9N z!$vxQrgLK>ZA{a-wvk?}>0H`KL)mmLY@{o0I;XcLX}mRQeCf^Cmmu#aI{E6+rUziv zKimZ=7teE*qt7NVn(pi)V34C2T?VN6?M+eM=c6SNGtFKjL!h6%7H#^7W?(*PJOG?b z<>=ucT4(r;jQs}`lmkTTj74euA!<o0C_O~ue+1Pdukk#81!9P3n<L1G1H1svR;5UT zGepzEIlQbwoB&TL#+?}=S|&jUgq6Az;2HVOnV!-RXab_u><+L8ydvAB*-<g~qQs5U zd^kkD0Lo(1?5kLFt5XnhyC`E|7kJESa<hRNdl%n65k^Tf;1GCDfj)DZrtxWz>xXCm Y07LMPM?*$k-T(jq07*qoM6N<$g1n+^F8}}l diff --git a/lang/flags/italy.png b/lang/flags/italy.png new file mode 100644 index 0000000000000000000000000000000000000000..177716ad302eef13af440c4942410239201af5c4 GIT binary patch literal 7974 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 literal 0 HcmV?d00001 diff --git a/lang/flags/palestine.png b/lang/flags/palestine.png index 78f5b1d420cb9fb1b8e21957b4114e9a7cd39042..66b5939ed7cf06e3f949153061b7546205a47b22 100644 GIT binary patch literal 7164 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 literal 1173 zcmV;G1Zw+<P)<h;3K|Lk000e1NJLTq001%o001%w1^@s69zTe&00004b3#c}2nYxW zd<bNS00009a7bBm000XT000XT0n*)m`~Uy|9CSrkbW?9;ba!ELWdK2BZ(?O2Mrm?o zcW-iQb09-gHt4*vi~s-t7IZ~ebVG7wVRUJ4ZXi@?ZDjy3I4?0VFEKQ>m=cNr00Zqw zL_t(&fz6uFZxcrpfWLK|IDqYq5g^i_Vsoei5?~HoK!J_a15%}kRN~O8YR#o;)l&r* z!U0DJxCBl}97%-4j}sw>-l{nNK#0@>aA{U51SzUiyH10Ws-%b6O*ZS@WOux?&L^#8 zk7wV!x9`oodE?cHmJ(n9dF!*?rUP|g&T5+jOrYv$YdZ!o4%C1(iK}MaZ^WszlQQC| z$|&!5nU>sGFccWzWssrDfF58{u>tOD(i(SrhPw11-AbtU!dBj~7Y=`Bb45n?93-P9 z{JLC3ej-P8)z~i7W^+Ymb48wJ^AtN$?w`wTHo$$A{p`?YbH(*9OKTq)TV7;pwGP6a zFSmRO@l!{5rYZMqil?-ept9#6_tJg&jFzazqgyC+L=w%rfAE|bMrV5RX*REWgxXF( zN33R>@G_(Voa{|>@+6z*>r_s)VltdW=(*0OIf8K6y!)=|zf0Ws=RJ+Jk1Caup@3MP zn>;e^)!XPy`>ks2rec3^dL)mBH{6UZFY<WhFC|(@QUFY+M=C+?y1M%S_tJe^CD6F3 zz=lV95V00$zXH(cO0GUT_R0L)%&reAv<tx!Fkl-}1|G^t>AQ7}13!Kjp<Ys4w&TN) zmGJKR9e)4jC;qGd9gRwI7%dwDQ2*suUZ1<jhu>bcu96%^0x>@hw<>A%j|E<zA7=5v zMC)pW=Wv1`d;Ji!E7T%41lkj7c4$RT+@YpCtHl*+@uX)>Q$9pe^#F%%kFfuTZ&eRN z5>ePkPS>Y>9C>t~UB{2A5Z^=s1!u4N7oXEV^E@^qKzPKAQea%6<i<9{#G{}OL)@X{ zV!a-jX+=sqLdnI9ZAevC!lBzE9C>t~4m}%<N^(@4h1EPEvizUv<m%0#Uh`FNce@L# z1~6dfks9y<2vi|W7gAIPvt5nU%4aOEs8TQ}6CiW=a5l~36T8)^6`lfMIy1Y8m@9@? z?}bbUS1#zh*{6In5QYh?^bzQQ&I%<ODfN4%koX?ZnZT&CVeD+0D;M;gXv8RvWbXEe z&C7*MM`;I!lFb}&%Guz#jh`;0hQGSBx3)u#r~$+7#!Z?wQW|&9WSHvjHm%On@#q$q z8Zd~*{&3wRZ}uhmekjLOf4ALK1un;+To``FXSbdNnCkE5?wO3&gdRscg@-7r?E_+m zQ`N77HuU9brx*Mv0ncf1hb)PSFk;KPDG|U3*jOc+{_;}Hq&4og#b21i2iv`#lPzLQ zYn)*Mmf|v}C{;v8Efc*#rX{yP$kL*f<Ddy^z(F<^1sUwuoCYm<QYU&EBLkA-dr|_< n)BNID4?<!0i)S-LbolW<OnR;I>{}Z300000NkvXXu0mjf{bV2) diff --git a/lang/flags/rpa.png b/lang/flags/rpa.png index 61de692d71c85ab90c5dafda09ec5023c925921c..07c4655f2606cb977ecfaca7177b815e72179fec 100644 GIT binary patch literal 11279 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 FV1gg>tn~l@ literal 2177 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 DDDwRh diff --git a/lang/flags/russia.png b/lang/flags/russia.png index 905e6bab3fe98a19d78b37ba4d5bbf8d7202749b..1fc22e5011e0345efdddcb05f7a88d09f17cc560 100644 GIT binary patch literal 8911 zcmY*fbx<5lus=wE;1V=IaB{f2J6v!*Tn~3R+zEaJf`#C4xCeI$ZUGK=3&Da02+rfH z_s6T(UAtX7Tiw0W-Sg|(sfkfnRlvr0hXDWpu$2^LHD9FFf7ct-m%HnBs`iU`Z6l>3 z1ps_cz<e-Ad3mO`RMb=f0Q?vMfRIlBz}?GG$UXo7<pcl@%>V%5bO3<FHLFcS^yLMr z#YY8M!1I5c*IAPMGJ@u*q#}p5iH42E$K)YHtN{SfR4d6!Y5Oc6XWu7K4yA5L=*$ID z{r!bSC4-=s)31{qF<C-bGmNF_B~gx{Ix1nZ5Yyiaa5(n#Jf%@3vDTs|N-&Vyn4{^_ zN8$@E`RvI3kn5;ROM@iyLNo{&Vhe#k&$w#*+mEz^O3P0Ub3|~vWZCoHUtaF4pR5Fm zUy1F_?p#MC6#pL|WzHUVg&6uApLm&WR<)F^h?P04Zse@;opc{-d9`zx^%u%lCKxc! zqwOSp!ymi$KTSVSMM6X-{uI`)Zq88+6R2~nT}LG@S;5)!Le|HX=50dvz`67~Ugm?I zZT2p`kkh|4?~NgAYilnr;q0KCy=>7*K1mHi?#r3cA3uIXy#1h>^({BI+w<=7;P&s{ zq$!eaC~~d2s?-|3tFr<Y844}(aL6htPm}+@6Uqd!>%}2lO5w}RA&IARiN)`hLtWp# zee2xW+0n9mp={L>2iWu=X~Q)wK7M5**a5;xik0^D>sJyIk{Y8n&x1}(67~-Ni(exP z2~-k6m#KOtLcS-ft+<tqV?L4$e0ls?xJ2Vo*!1y88t7yuD3-XQXFXjXa(uS8qTc)M z|MlJo{8!?AyxbV<=jUhGy|FMz>O#4Pho7~ws0w0gm<R4kAPmMXF6#dCg?O3HhVM~T zvx)!X)dDV+c)-o@`OeS=il$(h`=-pN3v(npw4MD};m4rh-ycoy5LBY){coQideNu? z>^Hgs|2eKSRpmm~Gh^S-YGx}s7*Bx8MmIrBSsrr~`2&#Ggmb(UIQn2PSSaxBGE*Vp z{p0OcU)1yOJ&EUA7hPRl;t-lf2l7;khh!84YW}O}lm7nxKOU1}{}!p9	hA@@1lO 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 O0F>lZWvivl!u|(q%v^E+ literal 805 zcmV+=1KRwFP)<h;3K|Lk000e1NJLTq001%o001%w1^@s69zTe&00004b3#c}2nYxW zd<bNS00009a7bBm000XT000XT0n*)m`~Uy|9CSrkbW?9;ba!ELWdK2BZ(?O2Mrm?o zcW-iQb09-gHt4*vi~s-t7IZ~ebVG7wVRUJ4ZXi@?ZDjy3I4?0VFEKQ>m=cNr00MnU zL_t(&f$f?xZrd;vhCd7K9A2QPymXCwfTHP^E$ImwZ{1Sgz(-Jk4j$zb#7A(40!1fz z>Sz_cfC68j!+Q!GS&~Ibmc$?*Kp=)`@%?#^<a?w>yWNhKFu(;c(Pp%r>-QTV(H3c2 z>*vOd8VWJMjkfdBp2ci{P+M(Lb%prA9Qaaq-~yKV+}QSqo@IXn1i+T|MWD~z>KMl6 zhc+I$M%;g9Ge83#kdR$f>0H$#0dP-uBG9q!b?l=Y6JiiA+%~hR5w~hXX{eQjmO+-s zx~oy!Y>?$WcV#Q{NXT$RfY=fieOV+V0Ip79O+&6Im@|2yb&X82A@iBcYL*pZkj<#e z)u|2-$fo=_U$UVUFnkdpHa-cleUJFauIdtFG@aS^$h;3r8ZuA+NIl}?o;Om)K>X_G zuYUlSNPXZUm%w85{=;{WID6ZxIraGq_#P5gu8IJ$-S?3E#dR(`q`r2Y$%~MIG4XIC zB{{~K?cu{<c@Z)+JX$)k?3u(vih9@Cc(|J^?h`#LA?v=aXo0ndr0{XSb~GXe;?eKd z?*P7PbCCtG82#Z5JcCj<-4J8slEpQa=(I>Z0&aRG_c$oVEw4O!1D<*W<j8c3<+WE2 zB#1W(k4zI_+NDJ`nUcv7^RnL+aMy`B^|&MFUa=^R|CZNz0IU$(4k)WfrVJ|&izo^E zG9d}@iIVHC4ha!k3Tvlh6=FL1D_s$vh=82Qouz82J43F!x~wJ>9dlNtvrWyuLe}ms zyc6hHl@}b_!-oX<4~;p^+zIvBGc3KI-Pvt1$cr#H)IYI|5CKb?yynzU$UX-6$l;4; jslbTC7tems(!Bc*)(Ms2!I@1i00000NkvXXu0mjfihO1~ diff --git a/lang/flags/uk.png b/lang/flags/uk.png index cb68609c395e2e08910fae776ba36cf78e7798cd..cbd99556ef9ad5edc7064252ba5511cf42f294f6 100644 GIT binary patch literal 12940 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 C3^zgm literal 1995 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 diff --git a/lang/flags/usa.png b/lang/flags/usa.png index fd5013242f481294ed5c40491b7c3670790d441f..bd70935c4e1f7769840ed96e196a17199936c6c4 100644 GIT binary patch literal 11316 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 literal 1716 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 KMNUMnLSTYVzA1VD diff --git a/lang/languages.xml b/lang/languages.xml index 449d415c..8f5120a7 100644 --- a/lang/languages.xml +++ b/lang/languages.xml @@ -6,7 +6,8 @@ <language display_name="RPA" locale="TODO" wallet_name="English" flag="/lang/flags/rpa.png" qs="none"/> <language display_name="Palestine" locale="TODO" wallet_name="English" flag="/lang/flags/palestine.png" qs="none"/> <language display_name="India" locale="hi_IN" wallet_name="English" flag="/lang/flags/india.png" qs="none"/> - <language display_name="German" locale="de_DE" wallet_name="English" flag="/lang/flags/german.png" qs="none"/> + <language display_name="Italy" locale="it_IT" wallet_name="English" flag="/lang/flags/italy.png" qs="none"/> + <language display_name="German" locale="de_DE" wallet_name="English" flag="/lang/flags/german.png" qs="none"/> <language display_name="China" locale="zh_CN" wallet_name="English" flag="/lang/flags/china.png" qs="none"/> <language display_name="Brazil" locale="pt_BR" wallet_name="English" flag="/lang/flags/brazil.png" qs="none"/> <language display_name="Bangladesh" locale="TODO" wallet_name="English" flag="/lang/flags/bangladesh.png" qs="none"/> diff --git a/monero-core.pro b/monero-core.pro index 84d4f35a..f11cff8a 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -86,13 +86,17 @@ unix { # translations files; TRANSLATIONS = monero-core_en.ts \ # English (could be untranslated) - monero-core_de.ts # Deutsch + monero-core_de.ts \ # Deutsch + monero-core_zh.ts \ # Chineese + monero-core_ru.ts \ # Russian + monero-core_it.ts \ # Italy + # extra make targets for lupdate and lrelease invocation # use "make lupdate" to update *.ts files and "make lrelease" to generate *.qm files lupdate.commands = lupdate $$_PRO_FILE_ -lupdate.depends = $$SOURCES $$HEADERS +lupdate.depends = $$SOURCES $$HEADERS lrelease.commands = lrelease $$_PRO_FILE_ lrelease.depends = lupdate translate.commands = $(COPY) *.qm ${DESTDIR} diff --git a/monero-core_de.ts b/monero-core_de.ts index 0a99e2fb..4b16cc31 100644 --- a/monero-core_de.ts +++ b/monero-core_de.ts @@ -60,47 +60,47 @@ <context> <name>BasicPanel</name> <message> - <location filename="BasicPanel.qml" line="75"/> + <location filename="BasicPanel.qml" line="78"/> <source>Locked Balance:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="89"/> + <location filename="BasicPanel.qml" line="92"/> <source>78.9239845</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="113"/> + <location filename="BasicPanel.qml" line="116"/> <source>Availible Balance:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="127"/> + <location filename="BasicPanel.qml" line="130"/> <source>2324.9239845</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="152"/> + <location filename="BasicPanel.qml" line="155"/> <source>amount...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="160"/> + <location filename="BasicPanel.qml" line="163"/> <source>SEND</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="176"/> + <location filename="BasicPanel.qml" line="179"/> <source>destination...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="188"/> + <location filename="BasicPanel.qml" line="191"/> <source>Privacy level</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="209"/> + <location filename="BasicPanel.qml" line="212"/> <source>payment ID (optional)...</source> <translation type="unfinished"></translation> </message> @@ -251,83 +251,43 @@ <context> <name>LeftPanel</name> <message> - <location filename="LeftPanel.qml" line="93"/> - <source>Locked balance</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="96"/> + <location filename="LeftPanel.qml" line="106"/> <source>Test tip 1<br/><br/>line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="127"/> - <source>Unlocked</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="130"/> + <location filename="LeftPanel.qml" line="141"/> <source>Test tip 2<br/><br/>line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="179"/> - <source>Dashboard</source> + <location filename="LeftPanel.qml" line="103"/> + <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="180"/> - <source>D</source> + <location filename="LeftPanel.qml" line="138"/> + <source>Unlocked balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="202"/> + <location filename="LeftPanel.qml" line="222"/> <source>Transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="203"/> + <location filename="LeftPanel.qml" line="223"/> <source>T</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="224"/> - <source>History</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="225"/> - <source>H</source> + <location filename="LeftPanel.qml" line="245"/> + <source>Receive</source> <translation type="unfinished"></translation> </message> <message> <location filename="LeftPanel.qml" line="246"/> - <source>Address book</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="247"/> - <source>B</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="268"/> - <source>Mining</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="269"/> - <source>M</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="290"/> - <source>Settings</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="291"/> - <source>S</source> + <source>R</source> <translation type="unfinished"></translation> </message> </context> @@ -352,25 +312,48 @@ <context> <name>PrivacyLevelSmall</name> <message> - <location filename="components/PrivacyLevelSmall.qml" line="95"/> + <location filename="components/PrivacyLevelSmall.qml" line="102"/> <source>LOW</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/PrivacyLevelSmall.qml" line="106"/> + <location filename="components/PrivacyLevelSmall.qml" line="113"/> <source>MEDIUM</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/PrivacyLevelSmall.qml" line="117"/> + <location filename="components/PrivacyLevelSmall.qml" line="124"/> <source>HIGH</source> <translation type="unfinished"></translation> </message> </context> +<context> + <name>Receive</name> + <message> + <location filename="pages/Receive.qml" line="79"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Receive.qml" line="106"/> + <source>Integrated address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Receive.qml" line="136"/> + <source>Payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Receive.qml" line="168"/> + <source>Generate</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>RightPanel</name> <message> - <location filename="RightPanel.qml" line="49"/> + <location filename="RightPanel.qml" line="58"/> <source>Twitter</source> <translation type="unfinished"></translation> </message> @@ -409,42 +392,47 @@ <context> <name>Transfer</name> <message> - <location filename="pages/Transfer.qml" line="42"/> + <location filename="pages/Transfer.qml" line="57"/> <source>Amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="52"/> - <source>Transaction prority</source> + <location filename="pages/Transfer.qml" line="67"/> + <source>Transaction priority</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="72"/> + <location filename="pages/Transfer.qml" line="89"/> <source>Amount...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="108"/> + <location filename="pages/Transfer.qml" line="127"/> <source>Privacy Level</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="131"/> + <location filename="pages/Transfer.qml" line="153"/> + <source>Cost</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="167"/> <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> Address <font size='2'> ( Type in or select from </font> <a href='#'>Address</a><font size='2'> book )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="156"/> + <location filename="pages/Transfer.qml" line="193"/> <source>Payment ID <font size='2'>( Optional )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="178"/> + <location filename="pages/Transfer.qml" line="217"/> <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="198"/> + <location filename="pages/Transfer.qml" line="237"/> <source>SEND</source> <translation type="unfinished"></translation> </message> @@ -490,12 +478,12 @@ <context> <name>WizardCreateWallet</name> <message> - <location filename="wizard/WizardCreateWallet.qml" line="51"/> + <location filename="wizard/WizardCreateWallet.qml" line="81"/> <source>A new wallet has been created for you</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardCreateWallet.qml" line="52"/> + <location filename="wizard/WizardCreateWallet.qml" line="82"/> <source>This is the 25 word mnemonic for your wallet</source> <translation type="unfinished"></translation> </message> @@ -503,32 +491,32 @@ <context> <name>WizardDonation</name> <message> - <location filename="wizard/WizardDonation.qml" line="85"/> + <location filename="wizard/WizardDonation.qml" line="93"/> <source>Monero development is solely supported by donations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="105"/> + <location filename="wizard/WizardDonation.qml" line="113"/> <source>Enable auto-donations of?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="145"/> + <location filename="wizard/WizardDonation.qml" line="153"/> <source>% of my fee added to each transaction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="156"/> + <location filename="wizard/WizardDonation.qml" line="164"/> <source>For every transaction, a small transaction fee is charged. This option lets you add an additional amount, 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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="167"/> + <location filename="wizard/WizardDonation.qml" line="175"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="185"/> + <location filename="wizard/WizardDonation.qml" line="193"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -576,7 +564,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="99"/> + <location filename="wizard/WizardFinish.qml" line="102"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -584,7 +572,17 @@ <context> <name>WizardMain</name> <message> - <location filename="wizard/WizardMain.qml" line="244"/> + <location filename="wizard/WizardMain.qml" line="85"/> + <source>Now that your wallet has been created, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardMain.qml" line="87"/> + <source>Now that your wallet has been restored, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardMain.qml" line="308"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -592,17 +590,17 @@ <context> <name>WizardManageWalletUI</name> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="101"/> + <location filename="wizard/WizardManageWalletUI.qml" line="103"/> <source>This is the name of your wallet. You can change it to a different name if you’d like:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="123"/> + <location filename="wizard/WizardManageWalletUI.qml" line="125"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="173"/> + <location filename="wizard/WizardManageWalletUI.qml" line="175"/> <source>Your wallet is stored in</source> <translation type="unfinished"></translation> </message> @@ -618,22 +616,22 @@ <context> <name>WizardOptions</name> <message> - <location filename="wizard/WizardOptions.qml" line="61"/> - <source>I want</source> + <location filename="wizard/WizardOptions.qml" line="62"/> + <source>Welcome to Monero!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="72"/> + <location filename="wizard/WizardOptions.qml" line="74"/> <source>Please select one of the following options:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="108"/> + <location filename="wizard/WizardOptions.qml" line="110"/> <source>This is my first time, I want to<br/>create a new account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="139"/> + <location filename="wizard/WizardOptions.qml" line="141"/> <source>I want to recover my account<br/>from my 24 work seed</source> <translation type="unfinished"></translation> </message> @@ -641,12 +639,7 @@ <context> <name>WizardPassword</name> <message> - <location filename="wizard/WizardPassword.qml" line="94"/> - <source>Now that your wallet has been created, please set a password for the wallet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="wizard/WizardPassword.qml" line="105"/> + <location filename="wizard/WizardPassword.qml" line="121"/> <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> <oldsource>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> @@ -657,17 +650,17 @@ <context> <name>WizardRecoveryWallet</name> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="51"/> + <location filename="wizard/WizardRecoveryWallet.qml" line="69"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="52"/> + <location filename="wizard/WizardRecoveryWallet.qml" line="70"/> <source>We're ready to recover your account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="53"/> + <location filename="wizard/WizardRecoveryWallet.qml" line="71"/> <source>Please enter your 25 word private key</source> <translation type="unfinished"></translation> </message> @@ -675,14 +668,90 @@ <context> <name>WizardWelcome</name> <message> - <location filename="wizard/WizardWelcome.qml" line="61"/> + <location filename="wizard/WizardWelcome.qml" line="65"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardWelcome.qml" line="72"/> + <location filename="wizard/WizardWelcome.qml" line="76"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> </context> +<context> + <name>main</name> + <message> + <location filename="main.qml" line="140"/> + <location filename="main.qml" line="206"/> + <location filename="main.qml" line="235"/> + <source>Error</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="141"/> + <source>Couldn't open wallet: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="207"/> + <source>Can't create transaction: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="219"/> + <source>Confirmation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="220"/> + <source>Please confirm transaction: + +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="221"/> + <source> +Address: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="222"/> + <source> +Payment ID: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="223"/> + <source> +Amount: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="224"/> + <source> +Fee: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="236"/> + <source>Couldn't send the money: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="239"/> + <source>Information</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="240"/> + <source>Money sent successfully</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="311"/> + <source>Initializing Wallet...</source> + <translation type="unfinished"></translation> + </message> +</context> </TS> diff --git a/monero-core_en.ts b/monero-core_en.ts index e59eb72d..bae9d7a9 100644 --- a/monero-core_en.ts +++ b/monero-core_en.ts @@ -60,47 +60,47 @@ <context> <name>BasicPanel</name> <message> - <location filename="BasicPanel.qml" line="75"/> + <location filename="BasicPanel.qml" line="78"/> <source>Locked Balance:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="89"/> + <location filename="BasicPanel.qml" line="92"/> <source>78.9239845</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="113"/> + <location filename="BasicPanel.qml" line="116"/> <source>Availible Balance:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="127"/> + <location filename="BasicPanel.qml" line="130"/> <source>2324.9239845</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="152"/> + <location filename="BasicPanel.qml" line="155"/> <source>amount...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="160"/> + <location filename="BasicPanel.qml" line="163"/> <source>SEND</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="176"/> + <location filename="BasicPanel.qml" line="179"/> <source>destination...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="188"/> + <location filename="BasicPanel.qml" line="191"/> <source>Privacy level</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="209"/> + <location filename="BasicPanel.qml" line="212"/> <source>payment ID (optional)...</source> <translation type="unfinished"></translation> </message> @@ -251,83 +251,43 @@ <context> <name>LeftPanel</name> <message> - <location filename="LeftPanel.qml" line="93"/> - <source>Locked balance</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="96"/> + <location filename="LeftPanel.qml" line="106"/> <source>Test tip 1<br/><br/>line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="127"/> - <source>Unlocked</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="130"/> + <location filename="LeftPanel.qml" line="141"/> <source>Test tip 2<br/><br/>line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="179"/> - <source>Dashboard</source> + <location filename="LeftPanel.qml" line="103"/> + <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="180"/> - <source>D</source> + <location filename="LeftPanel.qml" line="138"/> + <source>Unlocked balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="202"/> + <location filename="LeftPanel.qml" line="222"/> <source>Transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="203"/> + <location filename="LeftPanel.qml" line="223"/> <source>T</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="224"/> - <source>History</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="225"/> - <source>H</source> + <location filename="LeftPanel.qml" line="245"/> + <source>Receive</source> <translation type="unfinished"></translation> </message> <message> <location filename="LeftPanel.qml" line="246"/> - <source>Address book</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="247"/> - <source>B</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="268"/> - <source>Mining</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="269"/> - <source>M</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="290"/> - <source>Settings</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="291"/> - <source>S</source> + <source>R</source> <translation type="unfinished"></translation> </message> </context> @@ -352,25 +312,48 @@ <context> <name>PrivacyLevelSmall</name> <message> - <location filename="components/PrivacyLevelSmall.qml" line="95"/> + <location filename="components/PrivacyLevelSmall.qml" line="102"/> <source>LOW</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/PrivacyLevelSmall.qml" line="106"/> + <location filename="components/PrivacyLevelSmall.qml" line="113"/> <source>MEDIUM</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/PrivacyLevelSmall.qml" line="117"/> + <location filename="components/PrivacyLevelSmall.qml" line="124"/> <source>HIGH</source> <translation type="unfinished"></translation> </message> </context> +<context> + <name>Receive</name> + <message> + <location filename="pages/Receive.qml" line="79"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Receive.qml" line="106"/> + <source>Integrated address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Receive.qml" line="136"/> + <source>Payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Receive.qml" line="168"/> + <source>Generate</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>RightPanel</name> <message> - <location filename="RightPanel.qml" line="49"/> + <location filename="RightPanel.qml" line="58"/> <source>Twitter</source> <translation type="unfinished"></translation> </message> @@ -409,42 +392,47 @@ <context> <name>Transfer</name> <message> - <location filename="pages/Transfer.qml" line="42"/> + <location filename="pages/Transfer.qml" line="57"/> <source>Amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="52"/> - <source>Transaction prority</source> + <location filename="pages/Transfer.qml" line="67"/> + <source>Transaction priority</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="72"/> + <location filename="pages/Transfer.qml" line="89"/> <source>Amount...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="108"/> + <location filename="pages/Transfer.qml" line="127"/> <source>Privacy Level</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="131"/> + <location filename="pages/Transfer.qml" line="153"/> + <source>Cost</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="167"/> <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> Address <font size='2'> ( Type in or select from </font> <a href='#'>Address</a><font size='2'> book )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="156"/> + <location filename="pages/Transfer.qml" line="193"/> <source>Payment ID <font size='2'>( Optional )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="178"/> + <location filename="pages/Transfer.qml" line="217"/> <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="198"/> + <location filename="pages/Transfer.qml" line="237"/> <source>SEND</source> <translation type="unfinished"></translation> </message> @@ -490,12 +478,12 @@ <context> <name>WizardCreateWallet</name> <message> - <location filename="wizard/WizardCreateWallet.qml" line="51"/> + <location filename="wizard/WizardCreateWallet.qml" line="81"/> <source>A new wallet has been created for you</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardCreateWallet.qml" line="52"/> + <location filename="wizard/WizardCreateWallet.qml" line="82"/> <source>This is the 25 word mnemonic for your wallet</source> <translation type="unfinished"></translation> </message> @@ -503,32 +491,32 @@ <context> <name>WizardDonation</name> <message> - <location filename="wizard/WizardDonation.qml" line="85"/> + <location filename="wizard/WizardDonation.qml" line="93"/> <source>Monero development is solely supported by donations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="105"/> + <location filename="wizard/WizardDonation.qml" line="113"/> <source>Enable auto-donations of?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="145"/> + <location filename="wizard/WizardDonation.qml" line="153"/> <source>% of my fee added to each transaction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="156"/> + <location filename="wizard/WizardDonation.qml" line="164"/> <source>For every transaction, a small transaction fee is charged. This option lets you add an additional amount, 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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="167"/> + <location filename="wizard/WizardDonation.qml" line="175"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="185"/> + <location filename="wizard/WizardDonation.qml" line="193"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -576,7 +564,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="99"/> + <location filename="wizard/WizardFinish.qml" line="102"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -584,7 +572,17 @@ <context> <name>WizardMain</name> <message> - <location filename="wizard/WizardMain.qml" line="244"/> + <location filename="wizard/WizardMain.qml" line="85"/> + <source>Now that your wallet has been created, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardMain.qml" line="87"/> + <source>Now that your wallet has been restored, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardMain.qml" line="308"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -592,17 +590,17 @@ <context> <name>WizardManageWalletUI</name> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="101"/> + <location filename="wizard/WizardManageWalletUI.qml" line="103"/> <source>This is the name of your wallet. You can change it to a different name if you’d like:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="123"/> + <location filename="wizard/WizardManageWalletUI.qml" line="125"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="173"/> + <location filename="wizard/WizardManageWalletUI.qml" line="175"/> <source>Your wallet is stored in</source> <translation type="unfinished"></translation> </message> @@ -618,22 +616,22 @@ <context> <name>WizardOptions</name> <message> - <location filename="wizard/WizardOptions.qml" line="61"/> - <source>I want</source> + <location filename="wizard/WizardOptions.qml" line="62"/> + <source>Welcome to Monero!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="72"/> + <location filename="wizard/WizardOptions.qml" line="74"/> <source>Please select one of the following options:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="108"/> + <location filename="wizard/WizardOptions.qml" line="110"/> <source>This is my first time, I want to<br/>create a new account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="139"/> + <location filename="wizard/WizardOptions.qml" line="141"/> <source>I want to recover my account<br/>from my 24 work seed</source> <translation type="unfinished"></translation> </message> @@ -641,12 +639,7 @@ <context> <name>WizardPassword</name> <message> - <location filename="wizard/WizardPassword.qml" line="94"/> - <source>Now that your wallet has been created, please set a password for the wallet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="wizard/WizardPassword.qml" line="105"/> + <location filename="wizard/WizardPassword.qml" line="121"/> <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> <oldsource>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> @@ -657,17 +650,17 @@ <context> <name>WizardRecoveryWallet</name> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="51"/> + <location filename="wizard/WizardRecoveryWallet.qml" line="69"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="52"/> + <location filename="wizard/WizardRecoveryWallet.qml" line="70"/> <source>We're ready to recover your account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="53"/> + <location filename="wizard/WizardRecoveryWallet.qml" line="71"/> <source>Please enter your 25 word private key</source> <translation type="unfinished"></translation> </message> @@ -675,14 +668,90 @@ <context> <name>WizardWelcome</name> <message> - <location filename="wizard/WizardWelcome.qml" line="61"/> + <location filename="wizard/WizardWelcome.qml" line="65"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardWelcome.qml" line="72"/> + <location filename="wizard/WizardWelcome.qml" line="76"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> </context> +<context> + <name>main</name> + <message> + <location filename="main.qml" line="140"/> + <location filename="main.qml" line="206"/> + <location filename="main.qml" line="235"/> + <source>Error</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="141"/> + <source>Couldn't open wallet: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="207"/> + <source>Can't create transaction: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="219"/> + <source>Confirmation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="220"/> + <source>Please confirm transaction: + +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="221"/> + <source> +Address: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="222"/> + <source> +Payment ID: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="223"/> + <source> +Amount: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="224"/> + <source> +Fee: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="236"/> + <source>Couldn't send the money: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="239"/> + <source>Information</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="240"/> + <source>Money sent successfully</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="311"/> + <source>Initializing Wallet...</source> + <translation type="unfinished"></translation> + </message> +</context> </TS> diff --git a/monero-core_it.ts b/monero-core_it.ts new file mode 100644 index 00000000..b6bec1a6 --- /dev/null +++ b/monero-core_it.ts @@ -0,0 +1,755 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="it_IT"> +<context> + <name>AddressBook</name> + <message> + <location filename="pages/AddressBook.qml" line="47"/> + <source>Add new entry</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="56"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="58"/> + <source><b>Tip tekst test</b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="77"/> + <source>Payment ID <font size='2'>(Optional)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="79"/> + <source><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 thevtransfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="98"/> + <source>Description <font size='2'>(Local database)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="100"/> + <source><b>Tip tekst test</b><br/><br/>test line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="125"/> + <source>ADD</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>AddressBookTable</name> + <message> + <location filename="components/AddressBookTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/AddressBookTable.qml" line="106"/> + <source>Payment ID:</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>BasicPanel</name> + <message> + <location filename="BasicPanel.qml" line="78"/> + <source>Locked Balance:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="92"/> + <source>78.9239845</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="116"/> + <source>Availible Balance:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="130"/> + <source>2324.9239845</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="155"/> + <source>amount...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="163"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="179"/> + <source>destination...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="191"/> + <source>Privacy level</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="212"/> + <source>payment ID (optional)...</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Dashboard</name> + <message> + <location filename="pages/Dashboard.qml" line="57"/> + <source>Quick transfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Dashboard.qml" line="89"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Dashboard.qml" line="102"/> + <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> lookng for security level and address book? go to <a href='#'>Transfer</a> tab</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>DashboardTable</name> + <message> + <location filename="components/DashboardTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/DashboardTable.qml" line="137"/> + <source>Date</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/DashboardTable.qml" line="172"/> + <source>Balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/DashboardTable.qml" line="193"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>History</name> + <message> + <location filename="pages/History.qml" line="47"/> + <source>Filter trasactions history</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="56"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="58"/> + <location filename="pages/History.qml" line="122"/> + <location filename="pages/History.qml" line="142"/> + <location filename="pages/History.qml" line="190"/> + <location filename="pages/History.qml" line="224"/> + <location filename="pages/History.qml" line="245"/> + <source><b>Tip tekst test</b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="77"/> + <source>Payment ID <font size='2'>(Optional)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="79"/> + <source><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 thevtransfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="98"/> + <source>Description <font size='2'>(Local database)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="100"/> + <source><b>Tip tekst test</b><br/><br/>test line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="120"/> + <source>Date from</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="140"/> + <location filename="pages/History.qml" line="243"/> + <source>To</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="160"/> + <source>FILTER</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="169"/> + <source>Advance filtering</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="188"/> + <source>Type of transation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="222"/> + <source>Amount from</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>HistoryTable</name> + <message> + <location filename="components/HistoryTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="129"/> + <source>Payment ID:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="167"/> + <source>Date</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="202"/> + <source>Balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="223"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>LeftPanel</name> + <message> + <location filename="LeftPanel.qml" line="103"/> + <source>Balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="106"/> + <source>Test tip 1<br/><br/>line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="138"/> + <source>Unlocked balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="141"/> + <source>Test tip 2<br/><br/>line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="222"/> + <source>Transfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="223"/> + <source>T</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="245"/> + <source>Receive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="246"/> + <source>R</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>NetworkStatusItem</name> + <message> + <location filename="components/NetworkStatusItem.qml" line="58"/> + <source>Network status</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/NetworkStatusItem.qml" line="66"/> + <source>Connected</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/NetworkStatusItem.qml" line="66"/> + <source>Disconnected</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>PrivacyLevelSmall</name> + <message> + <location filename="components/PrivacyLevelSmall.qml" line="102"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/PrivacyLevelSmall.qml" line="113"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/PrivacyLevelSmall.qml" line="124"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Receive</name> + <message> + <location filename="pages/Receive.qml" line="79"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Receive.qml" line="106"/> + <source>Integrated address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Receive.qml" line="136"/> + <source>Payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Receive.qml" line="168"/> + <source>Generate</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>RightPanel</name> + <message> + <location filename="RightPanel.qml" line="58"/> + <source>Twitter</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>SearchInput</name> + <message> + <location filename="components/SearchInput.qml" line="69"/> + <source>Search by...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/SearchInput.qml" line="230"/> + <source>SEARCH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>TickDelegate</name> + <message> + <location filename="components/TickDelegate.qml" line="55"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/TickDelegate.qml" line="56"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/TickDelegate.qml" line="57"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Transfer</name> + <message> + <location filename="pages/Transfer.qml" line="57"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="67"/> + <source>Transaction priority</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="89"/> + <source>Amount...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="127"/> + <source>Privacy Level</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="153"/> + <source>Cost</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="167"/> + <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> Address <font size='2'> ( Type in or select from </font> <a href='#'>Address</a><font size='2'> book )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="193"/> + <source>Payment ID <font size='2'>( Optional )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="217"/> + <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="237"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardConfigure</name> + <message> + <location filename="wizard/WizardConfigure.qml" line="79"/> + <source>We’re almost there - let’s just configure some Monero preferences</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="97"/> + <source>Kickstart the Monero blockchain?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="115"/> + <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="126"/> + <source>Enable disk conservation mode?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="144"/> + <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="156"/> + <source>Allow background mining?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="174"/> + <source>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.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardCreateWallet</name> + <message> + <location filename="wizard/WizardCreateWallet.qml" line="81"/> + <source>A new wallet has been created for you</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardCreateWallet.qml" line="82"/> + <source>This is the 25 word mnemonic for your wallet</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardDonation</name> + <message> + <location filename="wizard/WizardDonation.qml" line="93"/> + <source>Monero development is solely supported by donations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="113"/> + <source>Enable auto-donations of?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="153"/> + <source>% of my fee added to each transaction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="164"/> + <source>For every transaction, a small transaction fee is charged. This option lets you add an additional amount, 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.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="175"/> + <source>Allow background mining?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="193"/> + <source>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.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardFinish</name> + <message> + <location filename="wizard/WizardFinish.qml" line="41"/> + <source><b>Language:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="42"/> + <source><b>Account name:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="43"/> + <source><b>Words:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="44"/> + <source><b>Wallet Path: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="45"/> + <source><b>Enable auto donation: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="46"/> + <source><b>Auto donation amount: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="47"/> + <source><b>Allow background mining: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="51"/> + <source>An overview of your Monero configuration is below:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="102"/> + <source>You’re all setup!</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardMain</name> + <message> + <location filename="wizard/WizardMain.qml" line="85"/> + <source>Now that your wallet has been created, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardMain.qml" line="87"/> + <source>Now that your wallet has been restored, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardMain.qml" line="308"/> + <source>USE MONERO</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardManageWalletUI</name> + <message> + <location filename="wizard/WizardManageWalletUI.qml" line="103"/> + <source>This is the name of your wallet. You can change it to a different name if you’d like:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardManageWalletUI.qml" line="125"/> + <source>My account name</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardManageWalletUI.qml" line="175"/> + <source>Your wallet is stored in</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardMemoTextInput</name> + <message> + <location filename="wizard/WizardMemoTextInput.qml" line="76"/> + <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardOptions</name> + <message> + <location filename="wizard/WizardOptions.qml" line="62"/> + <source>Welcome to Monero!</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardOptions.qml" line="74"/> + <source>Please select one of the following options:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardOptions.qml" line="110"/> + <source>This is my first time, I want to<br/>create a new account</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardOptions.qml" line="141"/> + <source>I want to recover my account<br/>from my 24 work seed</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardPassword</name> + <message> + <location filename="wizard/WizardPassword.qml" line="121"/> + <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> + Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardRecoveryWallet</name> + <message> + <location filename="wizard/WizardRecoveryWallet.qml" line="69"/> + <source>My account name</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardRecoveryWallet.qml" line="70"/> + <source>We're ready to recover your account</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardRecoveryWallet.qml" line="71"/> + <source>Please enter your 25 word private key</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardWelcome</name> + <message> + <location filename="wizard/WizardWelcome.qml" line="65"/> + <source>Welcome</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardWelcome.qml" line="76"/> + <source>Please choose a language and regional format.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>main</name> + <message> + <location filename="main.qml" line="140"/> + <location filename="main.qml" line="206"/> + <location filename="main.qml" line="235"/> + <source>Error</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="141"/> + <source>Couldn't open wallet: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="207"/> + <source>Can't create transaction: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="219"/> + <source>Confirmation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="220"/> + <source>Please confirm transaction: + +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="221"/> + <source> +Address: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="222"/> + <source> +Payment ID: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="223"/> + <source> +Amount: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="224"/> + <source> +Fee: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="236"/> + <source>Couldn't send the money: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="239"/> + <source>Information</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="240"/> + <source>Money sent successfully</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="311"/> + <source>Initializing Wallet...</source> + <translation type="unfinished"></translation> + </message> +</context> +</TS> diff --git a/monero-core_ru.ts b/monero-core_ru.ts new file mode 100644 index 00000000..8682ecb9 --- /dev/null +++ b/monero-core_ru.ts @@ -0,0 +1,755 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="ru_RU"> +<context> + <name>AddressBook</name> + <message> + <location filename="pages/AddressBook.qml" line="47"/> + <source>Add new entry</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="56"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="58"/> + <source><b>Tip tekst test</b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="77"/> + <source>Payment ID <font size='2'>(Optional)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="79"/> + <source><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 thevtransfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="98"/> + <source>Description <font size='2'>(Local database)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="100"/> + <source><b>Tip tekst test</b><br/><br/>test line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="125"/> + <source>ADD</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>AddressBookTable</name> + <message> + <location filename="components/AddressBookTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/AddressBookTable.qml" line="106"/> + <source>Payment ID:</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>BasicPanel</name> + <message> + <location filename="BasicPanel.qml" line="78"/> + <source>Locked Balance:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="92"/> + <source>78.9239845</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="116"/> + <source>Availible Balance:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="130"/> + <source>2324.9239845</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="155"/> + <source>amount...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="163"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="179"/> + <source>destination...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="191"/> + <source>Privacy level</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="212"/> + <source>payment ID (optional)...</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Dashboard</name> + <message> + <location filename="pages/Dashboard.qml" line="57"/> + <source>Quick transfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Dashboard.qml" line="89"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Dashboard.qml" line="102"/> + <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> lookng for security level and address book? go to <a href='#'>Transfer</a> tab</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>DashboardTable</name> + <message> + <location filename="components/DashboardTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/DashboardTable.qml" line="137"/> + <source>Date</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/DashboardTable.qml" line="172"/> + <source>Balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/DashboardTable.qml" line="193"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>History</name> + <message> + <location filename="pages/History.qml" line="47"/> + <source>Filter trasactions history</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="56"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="58"/> + <location filename="pages/History.qml" line="122"/> + <location filename="pages/History.qml" line="142"/> + <location filename="pages/History.qml" line="190"/> + <location filename="pages/History.qml" line="224"/> + <location filename="pages/History.qml" line="245"/> + <source><b>Tip tekst test</b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="77"/> + <source>Payment ID <font size='2'>(Optional)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="79"/> + <source><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 thevtransfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="98"/> + <source>Description <font size='2'>(Local database)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="100"/> + <source><b>Tip tekst test</b><br/><br/>test line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="120"/> + <source>Date from</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="140"/> + <location filename="pages/History.qml" line="243"/> + <source>To</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="160"/> + <source>FILTER</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="169"/> + <source>Advance filtering</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="188"/> + <source>Type of transation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="222"/> + <source>Amount from</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>HistoryTable</name> + <message> + <location filename="components/HistoryTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="129"/> + <source>Payment ID:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="167"/> + <source>Date</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="202"/> + <source>Balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="223"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>LeftPanel</name> + <message> + <location filename="LeftPanel.qml" line="103"/> + <source>Balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="106"/> + <source>Test tip 1<br/><br/>line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="138"/> + <source>Unlocked balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="141"/> + <source>Test tip 2<br/><br/>line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="222"/> + <source>Transfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="223"/> + <source>T</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="245"/> + <source>Receive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="246"/> + <source>R</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>NetworkStatusItem</name> + <message> + <location filename="components/NetworkStatusItem.qml" line="58"/> + <source>Network status</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/NetworkStatusItem.qml" line="66"/> + <source>Connected</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/NetworkStatusItem.qml" line="66"/> + <source>Disconnected</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>PrivacyLevelSmall</name> + <message> + <location filename="components/PrivacyLevelSmall.qml" line="102"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/PrivacyLevelSmall.qml" line="113"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/PrivacyLevelSmall.qml" line="124"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Receive</name> + <message> + <location filename="pages/Receive.qml" line="79"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Receive.qml" line="106"/> + <source>Integrated address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Receive.qml" line="136"/> + <source>Payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Receive.qml" line="168"/> + <source>Generate</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>RightPanel</name> + <message> + <location filename="RightPanel.qml" line="58"/> + <source>Twitter</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>SearchInput</name> + <message> + <location filename="components/SearchInput.qml" line="69"/> + <source>Search by...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/SearchInput.qml" line="230"/> + <source>SEARCH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>TickDelegate</name> + <message> + <location filename="components/TickDelegate.qml" line="55"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/TickDelegate.qml" line="56"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/TickDelegate.qml" line="57"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Transfer</name> + <message> + <location filename="pages/Transfer.qml" line="57"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="67"/> + <source>Transaction priority</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="89"/> + <source>Amount...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="127"/> + <source>Privacy Level</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="153"/> + <source>Cost</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="167"/> + <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> Address <font size='2'> ( Type in or select from </font> <a href='#'>Address</a><font size='2'> book )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="193"/> + <source>Payment ID <font size='2'>( Optional )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="217"/> + <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="237"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardConfigure</name> + <message> + <location filename="wizard/WizardConfigure.qml" line="79"/> + <source>We’re almost there - let’s just configure some Monero preferences</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="97"/> + <source>Kickstart the Monero blockchain?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="115"/> + <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="126"/> + <source>Enable disk conservation mode?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="144"/> + <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="156"/> + <source>Allow background mining?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="174"/> + <source>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.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardCreateWallet</name> + <message> + <location filename="wizard/WizardCreateWallet.qml" line="81"/> + <source>A new wallet has been created for you</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardCreateWallet.qml" line="82"/> + <source>This is the 25 word mnemonic for your wallet</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardDonation</name> + <message> + <location filename="wizard/WizardDonation.qml" line="93"/> + <source>Monero development is solely supported by donations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="113"/> + <source>Enable auto-donations of?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="153"/> + <source>% of my fee added to each transaction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="164"/> + <source>For every transaction, a small transaction fee is charged. This option lets you add an additional amount, 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.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="175"/> + <source>Allow background mining?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="193"/> + <source>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.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardFinish</name> + <message> + <location filename="wizard/WizardFinish.qml" line="41"/> + <source><b>Language:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="42"/> + <source><b>Account name:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="43"/> + <source><b>Words:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="44"/> + <source><b>Wallet Path: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="45"/> + <source><b>Enable auto donation: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="46"/> + <source><b>Auto donation amount: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="47"/> + <source><b>Allow background mining: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="51"/> + <source>An overview of your Monero configuration is below:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="102"/> + <source>You’re all setup!</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardMain</name> + <message> + <location filename="wizard/WizardMain.qml" line="85"/> + <source>Now that your wallet has been created, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardMain.qml" line="87"/> + <source>Now that your wallet has been restored, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardMain.qml" line="308"/> + <source>USE MONERO</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardManageWalletUI</name> + <message> + <location filename="wizard/WizardManageWalletUI.qml" line="103"/> + <source>This is the name of your wallet. You can change it to a different name if you’d like:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardManageWalletUI.qml" line="125"/> + <source>My account name</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardManageWalletUI.qml" line="175"/> + <source>Your wallet is stored in</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardMemoTextInput</name> + <message> + <location filename="wizard/WizardMemoTextInput.qml" line="76"/> + <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardOptions</name> + <message> + <location filename="wizard/WizardOptions.qml" line="62"/> + <source>Welcome to Monero!</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardOptions.qml" line="74"/> + <source>Please select one of the following options:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardOptions.qml" line="110"/> + <source>This is my first time, I want to<br/>create a new account</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardOptions.qml" line="141"/> + <source>I want to recover my account<br/>from my 24 work seed</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardPassword</name> + <message> + <location filename="wizard/WizardPassword.qml" line="121"/> + <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> + Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardRecoveryWallet</name> + <message> + <location filename="wizard/WizardRecoveryWallet.qml" line="69"/> + <source>My account name</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardRecoveryWallet.qml" line="70"/> + <source>We're ready to recover your account</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardRecoveryWallet.qml" line="71"/> + <source>Please enter your 25 word private key</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardWelcome</name> + <message> + <location filename="wizard/WizardWelcome.qml" line="65"/> + <source>Welcome</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardWelcome.qml" line="76"/> + <source>Please choose a language and regional format.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>main</name> + <message> + <location filename="main.qml" line="140"/> + <location filename="main.qml" line="206"/> + <location filename="main.qml" line="235"/> + <source>Error</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="141"/> + <source>Couldn't open wallet: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="207"/> + <source>Can't create transaction: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="219"/> + <source>Confirmation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="220"/> + <source>Please confirm transaction: + +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="221"/> + <source> +Address: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="222"/> + <source> +Payment ID: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="223"/> + <source> +Amount: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="224"/> + <source> +Fee: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="236"/> + <source>Couldn't send the money: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="239"/> + <source>Information</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="240"/> + <source>Money sent successfully</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="311"/> + <source>Initializing Wallet...</source> + <translation type="unfinished"></translation> + </message> +</context> +</TS> diff --git a/monero-core_zh.ts b/monero-core_zh.ts new file mode 100644 index 00000000..411a8768 --- /dev/null +++ b/monero-core_zh.ts @@ -0,0 +1,755 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="zh_CN"> +<context> + <name>AddressBook</name> + <message> + <location filename="pages/AddressBook.qml" line="47"/> + <source>Add new entry</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="56"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="58"/> + <source><b>Tip tekst test</b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="77"/> + <source>Payment ID <font size='2'>(Optional)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="79"/> + <source><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 thevtransfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="98"/> + <source>Description <font size='2'>(Local database)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="100"/> + <source><b>Tip tekst test</b><br/><br/>test line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/AddressBook.qml" line="125"/> + <source>ADD</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>AddressBookTable</name> + <message> + <location filename="components/AddressBookTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/AddressBookTable.qml" line="106"/> + <source>Payment ID:</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>BasicPanel</name> + <message> + <location filename="BasicPanel.qml" line="78"/> + <source>Locked Balance:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="92"/> + <source>78.9239845</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="116"/> + <source>Availible Balance:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="130"/> + <source>2324.9239845</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="155"/> + <source>amount...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="163"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="179"/> + <source>destination...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="191"/> + <source>Privacy level</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="BasicPanel.qml" line="212"/> + <source>payment ID (optional)...</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Dashboard</name> + <message> + <location filename="pages/Dashboard.qml" line="57"/> + <source>Quick transfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Dashboard.qml" line="89"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Dashboard.qml" line="102"/> + <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> lookng for security level and address book? go to <a href='#'>Transfer</a> tab</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>DashboardTable</name> + <message> + <location filename="components/DashboardTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/DashboardTable.qml" line="137"/> + <source>Date</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/DashboardTable.qml" line="172"/> + <source>Balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/DashboardTable.qml" line="193"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>History</name> + <message> + <location filename="pages/History.qml" line="47"/> + <source>Filter trasactions history</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="56"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="58"/> + <location filename="pages/History.qml" line="122"/> + <location filename="pages/History.qml" line="142"/> + <location filename="pages/History.qml" line="190"/> + <location filename="pages/History.qml" line="224"/> + <location filename="pages/History.qml" line="245"/> + <source><b>Tip tekst test</b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="77"/> + <source>Payment ID <font size='2'>(Optional)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="79"/> + <source><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 thevtransfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="98"/> + <source>Description <font size='2'>(Local database)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="100"/> + <source><b>Tip tekst test</b><br/><br/>test line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="120"/> + <source>Date from</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="140"/> + <location filename="pages/History.qml" line="243"/> + <source>To</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="160"/> + <source>FILTER</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="169"/> + <source>Advance filtering</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="188"/> + <source>Type of transation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/History.qml" line="222"/> + <source>Amount from</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>HistoryTable</name> + <message> + <location filename="components/HistoryTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="129"/> + <source>Payment ID:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="167"/> + <source>Date</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="202"/> + <source>Balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/HistoryTable.qml" line="223"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>LeftPanel</name> + <message> + <location filename="LeftPanel.qml" line="103"/> + <source>Balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="106"/> + <source>Test tip 1<br/><br/>line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="138"/> + <source>Unlocked balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="141"/> + <source>Test tip 2<br/><br/>line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="222"/> + <source>Transfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="223"/> + <source>T</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="245"/> + <source>Receive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="LeftPanel.qml" line="246"/> + <source>R</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>NetworkStatusItem</name> + <message> + <location filename="components/NetworkStatusItem.qml" line="58"/> + <source>Network status</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/NetworkStatusItem.qml" line="66"/> + <source>Connected</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/NetworkStatusItem.qml" line="66"/> + <source>Disconnected</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>PrivacyLevelSmall</name> + <message> + <location filename="components/PrivacyLevelSmall.qml" line="102"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/PrivacyLevelSmall.qml" line="113"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/PrivacyLevelSmall.qml" line="124"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Receive</name> + <message> + <location filename="pages/Receive.qml" line="79"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Receive.qml" line="106"/> + <source>Integrated address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Receive.qml" line="136"/> + <source>Payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Receive.qml" line="168"/> + <source>Generate</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>RightPanel</name> + <message> + <location filename="RightPanel.qml" line="58"/> + <source>Twitter</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>SearchInput</name> + <message> + <location filename="components/SearchInput.qml" line="69"/> + <source>Search by...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/SearchInput.qml" line="230"/> + <source>SEARCH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>TickDelegate</name> + <message> + <location filename="components/TickDelegate.qml" line="55"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/TickDelegate.qml" line="56"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="components/TickDelegate.qml" line="57"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Transfer</name> + <message> + <location filename="pages/Transfer.qml" line="57"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="67"/> + <source>Transaction priority</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="89"/> + <source>Amount...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="127"/> + <source>Privacy Level</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="153"/> + <source>Cost</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="167"/> + <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> Address <font size='2'> ( Type in or select from </font> <a href='#'>Address</a><font size='2'> book )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="193"/> + <source>Payment ID <font size='2'>( Optional )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="217"/> + <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="pages/Transfer.qml" line="237"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardConfigure</name> + <message> + <location filename="wizard/WizardConfigure.qml" line="79"/> + <source>We’re almost there - let’s just configure some Monero preferences</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="97"/> + <source>Kickstart the Monero blockchain?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="115"/> + <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="126"/> + <source>Enable disk conservation mode?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="144"/> + <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="156"/> + <source>Allow background mining?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardConfigure.qml" line="174"/> + <source>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.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardCreateWallet</name> + <message> + <location filename="wizard/WizardCreateWallet.qml" line="81"/> + <source>A new wallet has been created for you</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardCreateWallet.qml" line="82"/> + <source>This is the 25 word mnemonic for your wallet</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardDonation</name> + <message> + <location filename="wizard/WizardDonation.qml" line="93"/> + <source>Monero development is solely supported by donations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="113"/> + <source>Enable auto-donations of?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="153"/> + <source>% of my fee added to each transaction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="164"/> + <source>For every transaction, a small transaction fee is charged. This option lets you add an additional amount, 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.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="175"/> + <source>Allow background mining?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardDonation.qml" line="193"/> + <source>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.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardFinish</name> + <message> + <location filename="wizard/WizardFinish.qml" line="41"/> + <source><b>Language:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="42"/> + <source><b>Account name:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="43"/> + <source><b>Words:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="44"/> + <source><b>Wallet Path: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="45"/> + <source><b>Enable auto donation: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="46"/> + <source><b>Auto donation amount: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="47"/> + <source><b>Allow background mining: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="51"/> + <source>An overview of your Monero configuration is below:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardFinish.qml" line="102"/> + <source>You’re all setup!</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardMain</name> + <message> + <location filename="wizard/WizardMain.qml" line="85"/> + <source>Now that your wallet has been created, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardMain.qml" line="87"/> + <source>Now that your wallet has been restored, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardMain.qml" line="308"/> + <source>USE MONERO</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardManageWalletUI</name> + <message> + <location filename="wizard/WizardManageWalletUI.qml" line="103"/> + <source>This is the name of your wallet. You can change it to a different name if you’d like:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardManageWalletUI.qml" line="125"/> + <source>My account name</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardManageWalletUI.qml" line="175"/> + <source>Your wallet is stored in</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardMemoTextInput</name> + <message> + <location filename="wizard/WizardMemoTextInput.qml" line="76"/> + <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardOptions</name> + <message> + <location filename="wizard/WizardOptions.qml" line="62"/> + <source>Welcome to Monero!</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardOptions.qml" line="74"/> + <source>Please select one of the following options:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardOptions.qml" line="110"/> + <source>This is my first time, I want to<br/>create a new account</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardOptions.qml" line="141"/> + <source>I want to recover my account<br/>from my 24 work seed</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardPassword</name> + <message> + <location filename="wizard/WizardPassword.qml" line="121"/> + <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> + Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardRecoveryWallet</name> + <message> + <location filename="wizard/WizardRecoveryWallet.qml" line="69"/> + <source>My account name</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardRecoveryWallet.qml" line="70"/> + <source>We're ready to recover your account</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardRecoveryWallet.qml" line="71"/> + <source>Please enter your 25 word private key</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardWelcome</name> + <message> + <location filename="wizard/WizardWelcome.qml" line="65"/> + <source>Welcome</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="wizard/WizardWelcome.qml" line="76"/> + <source>Please choose a language and regional format.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>main</name> + <message> + <location filename="main.qml" line="140"/> + <location filename="main.qml" line="206"/> + <location filename="main.qml" line="235"/> + <source>Error</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="141"/> + <source>Couldn't open wallet: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="207"/> + <source>Can't create transaction: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="219"/> + <source>Confirmation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="220"/> + <source>Please confirm transaction: + +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="221"/> + <source> +Address: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="222"/> + <source> +Payment ID: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="223"/> + <source> +Amount: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="224"/> + <source> +Fee: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="236"/> + <source>Couldn't send the money: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="239"/> + <source>Information</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="240"/> + <source>Money sent successfully</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="311"/> + <source>Initializing Wallet...</source> + <translation type="unfinished"></translation> + </message> +</context> +</TS> diff --git a/qml.qrc b/qml.qrc index 36861fe4..eca9f561 100644 --- a/qml.qrc +++ b/qml.qrc @@ -113,5 +113,6 @@ <file>wizard/utils.js</file> <file>pages/Receive.qml</file> <file>components/IconButton.qml</file> + <file>lang/flags/italy.png</file> </qresource> </RCC> diff --git a/wizard/WizardWelcome.qml b/wizard/WizardWelcome.qml index 8917d212..31bdbcb7 100644 --- a/wizard/WizardWelcome.qml +++ b/wizard/WizardWelcome.qml @@ -118,7 +118,7 @@ Item { radius: 30 color: gridView.currentIndex === index ? "#DBDBDB" : "#FFFFFF" Image { - anchors.centerIn: parent + anchors.fill: parent source: flag } } From 71da777375d41f0b57003d0d28edd83611136d42 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Thu, 14 Jul 2016 13:09:39 +0300 Subject: [PATCH 47/87] Init wallet asynchronously --- main.qml | 20 ++++---------------- src/libwalletqt/Wallet.cpp | 16 +++++++++++++++- src/libwalletqt/Wallet.h | 9 +++++++++ 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/main.qml b/main.qml index b96b5dea..168591df 100644 --- a/main.qml +++ b/main.qml @@ -145,23 +145,12 @@ ApplicationWindow { } console.log("Wallet opened successfully: ", wallet.errorString); } - // display splash screen... - - console.log("initializing with daemon address..") - if (!wallet.init(persistentSettings.daemon_address, 0)) { - console.log("Error initialize wallet: ", wallet.errorString); - return - } - console.log("Wallet initialized successfully") - // TODO: update network indicator - // subscribing for wallet updates wallet.updated.connect(onWalletUpdate); wallet.refreshed.connect(onWalletRefresh); - console.log("refreshing wallet async") - // TODO: refresh asynchronously without blocking UI, implement signal(s) - wallet.refreshAsync(); - console.log("wallet balance: ", wallet.balance) + + console.log("initializing with daemon address..") + wallet.initAsync(persistentSettings.daemon_address, 0); } @@ -173,8 +162,7 @@ ApplicationWindow { function onWalletRefresh() { console.log(">>> wallet refreshed") - leftPanel.unlockedBalanceText = walletManager.displayAmount(wallet.unlockedBalance); - leftPanel.balanceText = walletManager.displayAmount(wallet.balance); + onWalletUpdate(); } diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 3697984e..4c6995cb 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -28,6 +28,7 @@ public: // TODO Q_UNUSED(txId) Q_UNUSED(amount) + qDebug() << __FUNCTION__; } virtual void moneyReceived(const std::string &txId, uint64_t amount) @@ -35,16 +36,19 @@ public: // TODO Q_UNUSED(txId) Q_UNUSED(amount) + qDebug() << __FUNCTION__; } virtual void updated() { + qDebug() << __FUNCTION__; emit m_wallet->updated(); } // called when wallet refreshed by background thread or explicitly virtual void refreshed() { + qDebug() << __FUNCTION__; emit m_wallet->refreshed(); } @@ -74,6 +78,11 @@ Wallet::Status Wallet::status() const return static_cast<Status>(m_walletImpl->status()); } +bool Wallet::connected() const +{ + return m_walletImpl->connected(); +} + QString Wallet::errorString() const { return QString::fromStdString(m_walletImpl->errorString()); @@ -99,6 +108,11 @@ bool Wallet::init(const QString &daemonAddress, quint64 upperTransactionLimit) return m_walletImpl->init(daemonAddress.toStdString(), upperTransactionLimit); } +void Wallet::initAsync(const QString &daemonAddress, quint64 upperTransactionLimit) +{ + m_walletImpl->initAsync(daemonAddress.toStdString(), upperTransactionLimit); +} + bool Wallet::connectToDaemon() { return m_walletImpl->connectToDaemon(); @@ -183,7 +197,7 @@ void Wallet::setPaymentId(const QString &paymentId) Wallet::Wallet(Bitmonero::Wallet *w, QObject *parent) : QObject(parent), m_walletImpl(w), m_history(nullptr) { - + m_walletImpl->setListener(new WalletListenerImpl(this)); } Wallet::~Wallet() diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index 4d6a1ea0..feba75e0 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -20,6 +20,7 @@ class Wallet : public QObject Q_PROPERTY(QString seed READ getSeed) Q_PROPERTY(QString seedLanguage READ getSeedLanguage) Q_PROPERTY(Status status READ status) + Q_PROPERTY(bool connected READ connected) Q_PROPERTY(QString errorString READ errorString) Q_PROPERTY(QString address READ address) Q_PROPERTY(quint64 balance READ balance) @@ -27,6 +28,7 @@ class Wallet : public QObject Q_PROPERTY(TransactionHistory * history READ history) Q_PROPERTY(QString paymentId READ paymentId WRITE setPaymentId) + public: enum Status { Status_Ok = Bitmonero::Wallet::Status_Ok, @@ -47,6 +49,9 @@ public: //! returns last operation's status Status status() const; + //! returns of wallet connected + bool connected() const; + //! returns last operation's error message QString errorString() const; @@ -62,6 +67,9 @@ public: //! initializes wallet Q_INVOKABLE bool init(const QString &daemonAddress, quint64 upperTransactionLimit); + //! initializes wallet asynchronously + Q_INVOKABLE void initAsync(const QString &daemonAddress, quint64 upperTransactionLimit); + //! connects to daemon Q_INVOKABLE bool connectToDaemon(); @@ -124,6 +132,7 @@ private: // history lifetime managed by wallet; TransactionHistory * m_history; QString m_paymentId; + }; #endif // WALLET_H From 8b26bc4a4d57e68f2229a4fa7f9d1d5b5acd9004 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Thu, 14 Jul 2016 13:40:27 +0300 Subject: [PATCH 48/87] Update network status dynamically (closes #17) --- LeftPanel.qml | 2 +- main.qml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/LeftPanel.qml b/LeftPanel.qml index 0c1ccd12..e23d353c 100644 --- a/LeftPanel.qml +++ b/LeftPanel.qml @@ -352,7 +352,7 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom - connected: true + connected: false } } } diff --git a/main.qml b/main.qml index 168591df..b55ace8c 100644 --- a/main.qml +++ b/main.qml @@ -162,6 +162,7 @@ ApplicationWindow { function onWalletRefresh() { console.log(">>> wallet refreshed") + leftPanel.networkStatus.connected = wallet.connected onWalletUpdate(); } @@ -363,6 +364,7 @@ ApplicationWindow { visible: appWindow.rightPanelExpanded } + MiddlePanel { id: middlePanel anchors.bottom: parent.bottom From b0f77c817ca8a04c8d3684f980f7c0b9a72f68f6 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Thu, 14 Jul 2016 16:05:40 +0300 Subject: [PATCH 49/87] separate LIBS sections for macx, linux and win32 --- monero-core.pro | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/monero-core.pro b/monero-core.pro index f11cff8a..11e610b9 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -65,7 +65,7 @@ win32 { -lgdi32 } -unix { +linux { LIBS+= \ -Wl,-Bstatic \ -lboost_serialization \ @@ -82,6 +82,21 @@ unix { -ldl } +macx { + LIBS+= \ + -lboost_serialization \ + -lboost_thread \ + -lboost_system \ + -lboost_date_time \ + -lboost_filesystem \ + -lboost_regex \ + -lboost_chrono \ + -lboost_program_options \ + -lssl \ + -lcrypto \ + -ldl +} + # translations files; From 573711473aaa0af7c71cd2984c22ce042775c469 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Fri, 15 Jul 2016 11:03:18 +0300 Subject: [PATCH 50/87] update/build transations with release build. closes #23 --- monero-core.pro | 33 +- .../monero-core_de.ts | 296 +++++++++--------- .../monero-core_en.ts | 296 +++++++++--------- .../monero-core_it.ts | 278 ++++++++-------- .../monero-core_ru.ts | 278 ++++++++-------- .../monero-core_zh.ts | 278 ++++++++-------- 6 files changed, 730 insertions(+), 729 deletions(-) rename monero-core_de.ts => translations/monero-core_de.ts (70%) rename monero-core_en.ts => translations/monero-core_en.ts (70%) rename monero-core_it.ts => translations/monero-core_it.ts (70%) rename monero-core_ru.ts => translations/monero-core_ru.ts (70%) rename monero-core_zh.ts => translations/monero-core_zh.ts (70%) diff --git a/monero-core.pro b/monero-core.pro index 11e610b9..e03c31aa 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -100,29 +100,35 @@ macx { # translations files; -TRANSLATIONS = monero-core_en.ts \ # English (could be untranslated) - monero-core_de.ts \ # Deutsch - monero-core_zh.ts \ # Chineese - monero-core_ru.ts \ # Russian - monero-core_it.ts \ # Italy +TRANSLATIONS = $$PWD/translations/monero-core_en.ts \ # English (could be untranslated) + $$PWD/translations/monero-core_de.ts \ # Deutsch + $$PWD/translations/monero-core_zh.ts \ # Chineese + $$PWD/translations/monero-core_ru.ts \ # Russian + $$PWD/translations/monero-core_it.ts \ # Italy # extra make targets for lupdate and lrelease invocation # use "make lupdate" to update *.ts files and "make lrelease" to generate *.qm files -lupdate.commands = lupdate $$_PRO_FILE_ -lupdate.depends = $$SOURCES $$HEADERS -lrelease.commands = lrelease $$_PRO_FILE_ -lrelease.depends = lupdate -translate.commands = $(COPY) *.qm ${DESTDIR} -translate.depends = lrelease +trans_update.commands = lupdate $$_PRO_FILE_ +trans_update.depends = $$_PRO_FILE_ -QMAKE_EXTRA_TARGETS += lupdate lrelease +trans_release.commands = lrelease $$_PRO_FILE_ +trans_release.depends = trans_update $$TRANSLATIONS +translate.commands = $(COPY) $$PWD/*.qm ${DESTDIR} +translate.depends = trans_release +QMAKE_EXTRA_TARGETS += trans_update trans_release translate + +# updating transations only in release mode as this is requires to re-link project +# even if no changes were made. + +#PRE_TARGETDEPS += translate CONFIG(release, debug|release) { DESTDIR=release + PRE_TARGETDEPS += translate } CONFIG(debug, debug|release) { @@ -143,8 +149,7 @@ include(deployment.pri) OTHER_FILES += \ .gitignore \ - monero-core_de.ts \ - monero-core_en.ts + $$TRANSLATIONS DISTFILES += \ notes.txt diff --git a/monero-core_de.ts b/translations/monero-core_de.ts similarity index 70% rename from monero-core_de.ts rename to translations/monero-core_de.ts index 4b16cc31..09e96e70 100644 --- a/monero-core_de.ts +++ b/translations/monero-core_de.ts @@ -4,42 +4,42 @@ <context> <name>AddressBook</name> <message> - <location filename="pages/AddressBook.qml" line="47"/> + <location filename="../pages/AddressBook.qml" line="47"/> <source>Add new entry</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="56"/> + <location filename="../pages/AddressBook.qml" line="56"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="58"/> + <location filename="../pages/AddressBook.qml" line="58"/> <source><b>Tip tekst test</b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="77"/> + <location filename="../pages/AddressBook.qml" line="77"/> <source>Payment ID <font size='2'>(Optional)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="79"/> + <location filename="../pages/AddressBook.qml" line="79"/> <source><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 thevtransfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="98"/> + <location filename="../pages/AddressBook.qml" line="98"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="100"/> + <location filename="../pages/AddressBook.qml" line="100"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="125"/> + <location filename="../pages/AddressBook.qml" line="125"/> <source>ADD</source> <translation type="unfinished"></translation> </message> @@ -47,12 +47,12 @@ <context> <name>AddressBookTable</name> <message> - <location filename="components/AddressBookTable.qml" line="47"/> + <location filename="../components/AddressBookTable.qml" line="47"/> <source>No more results</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/AddressBookTable.qml" line="106"/> + <location filename="../components/AddressBookTable.qml" line="106"/> <source>Payment ID:</source> <translation type="unfinished"></translation> </message> @@ -60,47 +60,47 @@ <context> <name>BasicPanel</name> <message> - <location filename="BasicPanel.qml" line="78"/> + <location filename="../BasicPanel.qml" line="78"/> <source>Locked Balance:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="92"/> + <location filename="../BasicPanel.qml" line="92"/> <source>78.9239845</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="116"/> + <location filename="../BasicPanel.qml" line="116"/> <source>Availible Balance:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="130"/> + <location filename="../BasicPanel.qml" line="130"/> <source>2324.9239845</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="155"/> + <location filename="../BasicPanel.qml" line="155"/> <source>amount...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="163"/> + <location filename="../BasicPanel.qml" line="163"/> <source>SEND</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="179"/> + <location filename="../BasicPanel.qml" line="179"/> <source>destination...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="191"/> + <location filename="../BasicPanel.qml" line="191"/> <source>Privacy level</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="212"/> + <location filename="../BasicPanel.qml" line="212"/> <source>payment ID (optional)...</source> <translation type="unfinished"></translation> </message> @@ -108,17 +108,17 @@ <context> <name>Dashboard</name> <message> - <location filename="pages/Dashboard.qml" line="57"/> + <location filename="../pages/Dashboard.qml" line="57"/> <source>Quick transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Dashboard.qml" line="89"/> + <location filename="../pages/Dashboard.qml" line="89"/> <source>SEND</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Dashboard.qml" line="102"/> + <location filename="../pages/Dashboard.qml" line="102"/> <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> lookng for security level and address book? go to <a href='#'>Transfer</a> tab</source> <translation type="unfinished"></translation> </message> @@ -126,22 +126,22 @@ <context> <name>DashboardTable</name> <message> - <location filename="components/DashboardTable.qml" line="47"/> + <location filename="../components/DashboardTable.qml" line="47"/> <source>No more results</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/DashboardTable.qml" line="137"/> + <location filename="../components/DashboardTable.qml" line="137"/> <source>Date</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/DashboardTable.qml" line="172"/> + <location filename="../components/DashboardTable.qml" line="172"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/DashboardTable.qml" line="193"/> + <location filename="../components/DashboardTable.qml" line="193"/> <source>Amount</source> <translation type="unfinished"></translation> </message> @@ -149,73 +149,73 @@ <context> <name>History</name> <message> - <location filename="pages/History.qml" line="47"/> + <location filename="../pages/History.qml" line="47"/> <source>Filter trasactions history</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="56"/> + <location filename="../pages/History.qml" line="56"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="58"/> - <location filename="pages/History.qml" line="122"/> - <location filename="pages/History.qml" line="142"/> - <location filename="pages/History.qml" line="190"/> - <location filename="pages/History.qml" line="224"/> - <location filename="pages/History.qml" line="245"/> + <location filename="../pages/History.qml" line="58"/> + <location filename="../pages/History.qml" line="122"/> + <location filename="../pages/History.qml" line="142"/> + <location filename="../pages/History.qml" line="190"/> + <location filename="../pages/History.qml" line="224"/> + <location filename="../pages/History.qml" line="245"/> <source><b>Tip tekst test</b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="77"/> + <location filename="../pages/History.qml" line="77"/> <source>Payment ID <font size='2'>(Optional)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="79"/> + <location filename="../pages/History.qml" line="79"/> <source><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 thevtransfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="98"/> + <location filename="../pages/History.qml" line="98"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="100"/> + <location filename="../pages/History.qml" line="100"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="120"/> + <location filename="../pages/History.qml" line="120"/> <source>Date from</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="140"/> - <location filename="pages/History.qml" line="243"/> + <location filename="../pages/History.qml" line="140"/> + <location filename="../pages/History.qml" line="243"/> <source>To</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="160"/> + <location filename="../pages/History.qml" line="160"/> <source>FILTER</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="169"/> + <location filename="../pages/History.qml" line="169"/> <source>Advance filtering</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="188"/> + <location filename="../pages/History.qml" line="188"/> <source>Type of transation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="222"/> + <location filename="../pages/History.qml" line="222"/> <source>Amount from</source> <translation type="unfinished"></translation> </message> @@ -223,27 +223,27 @@ <context> <name>HistoryTable</name> <message> - <location filename="components/HistoryTable.qml" line="47"/> + <location filename="../components/HistoryTable.qml" line="47"/> <source>No more results</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="129"/> + <location filename="../components/HistoryTable.qml" line="129"/> <source>Payment ID:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="167"/> + <location filename="../components/HistoryTable.qml" line="167"/> <source>Date</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="202"/> + <location filename="../components/HistoryTable.qml" line="202"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="223"/> + <location filename="../components/HistoryTable.qml" line="223"/> <source>Amount</source> <translation type="unfinished"></translation> </message> @@ -251,42 +251,42 @@ <context> <name>LeftPanel</name> <message> - <location filename="LeftPanel.qml" line="106"/> - <source>Test tip 1<br/><br/>line 2</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="141"/> - <source>Test tip 2<br/><br/>line 2</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="103"/> + <location filename="../LeftPanel.qml" line="103"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="138"/> + <location filename="../LeftPanel.qml" line="106"/> + <source>Test tip 1<br/><br/>line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../LeftPanel.qml" line="138"/> <source>Unlocked balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="222"/> + <location filename="../LeftPanel.qml" line="141"/> + <source>Test tip 2<br/><br/>line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../LeftPanel.qml" line="222"/> <source>Transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="223"/> + <location filename="../LeftPanel.qml" line="223"/> <source>T</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="245"/> + <location filename="../LeftPanel.qml" line="245"/> <source>Receive</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="246"/> + <location filename="../LeftPanel.qml" line="246"/> <source>R</source> <translation type="unfinished"></translation> </message> @@ -294,17 +294,17 @@ <context> <name>NetworkStatusItem</name> <message> - <location filename="components/NetworkStatusItem.qml" line="58"/> + <location filename="../components/NetworkStatusItem.qml" line="58"/> <source>Network status</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/NetworkStatusItem.qml" line="66"/> + <location filename="../components/NetworkStatusItem.qml" line="66"/> <source>Connected</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/NetworkStatusItem.qml" line="66"/> + <location filename="../components/NetworkStatusItem.qml" line="66"/> <source>Disconnected</source> <translation type="unfinished"></translation> </message> @@ -312,17 +312,17 @@ <context> <name>PrivacyLevelSmall</name> <message> - <location filename="components/PrivacyLevelSmall.qml" line="102"/> + <location filename="../components/PrivacyLevelSmall.qml" line="102"/> <source>LOW</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/PrivacyLevelSmall.qml" line="113"/> + <location filename="../components/PrivacyLevelSmall.qml" line="113"/> <source>MEDIUM</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/PrivacyLevelSmall.qml" line="124"/> + <location filename="../components/PrivacyLevelSmall.qml" line="124"/> <source>HIGH</source> <translation type="unfinished"></translation> </message> @@ -330,22 +330,22 @@ <context> <name>Receive</name> <message> - <location filename="pages/Receive.qml" line="79"/> + <location filename="../pages/Receive.qml" line="79"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Receive.qml" line="106"/> + <location filename="../pages/Receive.qml" line="106"/> <source>Integrated address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Receive.qml" line="136"/> + <location filename="../pages/Receive.qml" line="136"/> <source>Payment ID</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Receive.qml" line="168"/> + <location filename="../pages/Receive.qml" line="168"/> <source>Generate</source> <translation type="unfinished"></translation> </message> @@ -353,7 +353,7 @@ <context> <name>RightPanel</name> <message> - <location filename="RightPanel.qml" line="58"/> + <location filename="../RightPanel.qml" line="58"/> <source>Twitter</source> <translation type="unfinished"></translation> </message> @@ -361,12 +361,12 @@ <context> <name>SearchInput</name> <message> - <location filename="components/SearchInput.qml" line="69"/> + <location filename="../components/SearchInput.qml" line="69"/> <source>Search by...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/SearchInput.qml" line="230"/> + <location filename="../components/SearchInput.qml" line="230"/> <source>SEARCH</source> <translation type="unfinished"></translation> </message> @@ -374,17 +374,17 @@ <context> <name>TickDelegate</name> <message> - <location filename="components/TickDelegate.qml" line="55"/> + <location filename="../components/TickDelegate.qml" line="55"/> <source>LOW</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/TickDelegate.qml" line="56"/> + <location filename="../components/TickDelegate.qml" line="56"/> <source>MEDIUM</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/TickDelegate.qml" line="57"/> + <location filename="../components/TickDelegate.qml" line="57"/> <source>HIGH</source> <translation type="unfinished"></translation> </message> @@ -392,47 +392,47 @@ <context> <name>Transfer</name> <message> - <location filename="pages/Transfer.qml" line="57"/> + <location filename="../pages/Transfer.qml" line="57"/> <source>Amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="67"/> + <location filename="../pages/Transfer.qml" line="67"/> <source>Transaction priority</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="89"/> + <location filename="../pages/Transfer.qml" line="89"/> <source>Amount...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="127"/> + <location filename="../pages/Transfer.qml" line="127"/> <source>Privacy Level</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="153"/> + <location filename="../pages/Transfer.qml" line="153"/> <source>Cost</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="167"/> + <location filename="../pages/Transfer.qml" line="167"/> <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> Address <font size='2'> ( Type in or select from </font> <a href='#'>Address</a><font size='2'> book )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="193"/> + <location filename="../pages/Transfer.qml" line="193"/> <source>Payment ID <font size='2'>( Optional )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="217"/> + <location filename="../pages/Transfer.qml" line="217"/> <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="237"/> + <location filename="../pages/Transfer.qml" line="237"/> <source>SEND</source> <translation type="unfinished"></translation> </message> @@ -440,37 +440,37 @@ <context> <name>WizardConfigure</name> <message> - <location filename="wizard/WizardConfigure.qml" line="79"/> + <location filename="../wizard/WizardConfigure.qml" line="79"/> <source>We’re almost there - let’s just configure some Monero preferences</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="97"/> + <location filename="../wizard/WizardConfigure.qml" line="97"/> <source>Kickstart the Monero blockchain?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="115"/> + <location filename="../wizard/WizardConfigure.qml" line="115"/> <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="126"/> + <location filename="../wizard/WizardConfigure.qml" line="126"/> <source>Enable disk conservation mode?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="144"/> + <location filename="../wizard/WizardConfigure.qml" line="144"/> <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="156"/> + <location filename="../wizard/WizardConfigure.qml" line="156"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="174"/> + <location filename="../wizard/WizardConfigure.qml" line="174"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -478,12 +478,12 @@ <context> <name>WizardCreateWallet</name> <message> - <location filename="wizard/WizardCreateWallet.qml" line="81"/> + <location filename="../wizard/WizardCreateWallet.qml" line="81"/> <source>A new wallet has been created for you</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardCreateWallet.qml" line="82"/> + <location filename="../wizard/WizardCreateWallet.qml" line="82"/> <source>This is the 25 word mnemonic for your wallet</source> <translation type="unfinished"></translation> </message> @@ -491,32 +491,32 @@ <context> <name>WizardDonation</name> <message> - <location filename="wizard/WizardDonation.qml" line="93"/> + <location filename="../wizard/WizardDonation.qml" line="93"/> <source>Monero development is solely supported by donations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="113"/> + <location filename="../wizard/WizardDonation.qml" line="113"/> <source>Enable auto-donations of?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="153"/> + <location filename="../wizard/WizardDonation.qml" line="153"/> <source>% of my fee added to each transaction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="164"/> + <location filename="../wizard/WizardDonation.qml" line="164"/> <source>For every transaction, a small transaction fee is charged. This option lets you add an additional amount, 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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="175"/> + <location filename="../wizard/WizardDonation.qml" line="175"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="193"/> + <location filename="../wizard/WizardDonation.qml" line="193"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -524,47 +524,47 @@ <context> <name>WizardFinish</name> <message> - <location filename="wizard/WizardFinish.qml" line="41"/> + <location filename="../wizard/WizardFinish.qml" line="41"/> <source><b>Language:</b> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="42"/> + <location filename="../wizard/WizardFinish.qml" line="42"/> <source><b>Account name:</b> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="43"/> + <location filename="../wizard/WizardFinish.qml" line="43"/> <source><b>Words:</b> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="44"/> + <location filename="../wizard/WizardFinish.qml" line="44"/> <source><b>Wallet Path: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="45"/> + <location filename="../wizard/WizardFinish.qml" line="45"/> <source><b>Enable auto donation: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="46"/> + <location filename="../wizard/WizardFinish.qml" line="46"/> <source><b>Auto donation amount: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="47"/> + <location filename="../wizard/WizardFinish.qml" line="47"/> <source><b>Allow background mining: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="51"/> + <location filename="../wizard/WizardFinish.qml" line="51"/> <source>An overview of your Monero configuration is below:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="102"/> + <location filename="../wizard/WizardFinish.qml" line="102"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -572,17 +572,17 @@ <context> <name>WizardMain</name> <message> - <location filename="wizard/WizardMain.qml" line="85"/> + <location filename="../wizard/WizardMain.qml" line="85"/> <source>Now that your wallet has been created, please set a password for the wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardMain.qml" line="87"/> + <location filename="../wizard/WizardMain.qml" line="87"/> <source>Now that your wallet has been restored, please set a password for the wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardMain.qml" line="308"/> + <location filename="../wizard/WizardMain.qml" line="308"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -590,17 +590,17 @@ <context> <name>WizardManageWalletUI</name> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="103"/> + <location filename="../wizard/WizardManageWalletUI.qml" line="103"/> <source>This is the name of your wallet. You can change it to a different name if you’d like:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="125"/> + <location filename="../wizard/WizardManageWalletUI.qml" line="125"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="175"/> + <location filename="../wizard/WizardManageWalletUI.qml" line="175"/> <source>Your wallet is stored in</source> <translation type="unfinished"></translation> </message> @@ -608,7 +608,7 @@ <context> <name>WizardMemoTextInput</name> <message> - <location filename="wizard/WizardMemoTextInput.qml" line="76"/> + <location filename="../wizard/WizardMemoTextInput.qml" line="76"/> <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> <translation type="unfinished"></translation> </message> @@ -616,22 +616,22 @@ <context> <name>WizardOptions</name> <message> - <location filename="wizard/WizardOptions.qml" line="62"/> + <location filename="../wizard/WizardOptions.qml" line="62"/> <source>Welcome to Monero!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="74"/> + <location filename="../wizard/WizardOptions.qml" line="74"/> <source>Please select one of the following options:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="110"/> + <location filename="../wizard/WizardOptions.qml" line="110"/> <source>This is my first time, I want to<br/>create a new account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="141"/> + <location filename="../wizard/WizardOptions.qml" line="141"/> <source>I want to recover my account<br/>from my 24 work seed</source> <translation type="unfinished"></translation> </message> @@ -639,28 +639,26 @@ <context> <name>WizardPassword</name> <message> - <location filename="wizard/WizardPassword.qml" line="121"/> + <location filename="../wizard/WizardPassword.qml" line="121"/> <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> - <oldsource>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> - Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</oldsource> <translation type="unfinished"></translation> </message> </context> <context> <name>WizardRecoveryWallet</name> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="69"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="69"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="70"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="70"/> <source>We're ready to recover your account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="71"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="71"/> <source>Please enter your 25 word private key</source> <translation type="unfinished"></translation> </message> @@ -668,12 +666,12 @@ <context> <name>WizardWelcome</name> <message> - <location filename="wizard/WizardWelcome.qml" line="65"/> + <location filename="../wizard/WizardWelcome.qml" line="65"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardWelcome.qml" line="76"/> + <location filename="../wizard/WizardWelcome.qml" line="76"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> @@ -681,75 +679,75 @@ <context> <name>main</name> <message> - <location filename="main.qml" line="140"/> - <location filename="main.qml" line="206"/> - <location filename="main.qml" line="235"/> + <location filename="../main.qml" line="140"/> + <location filename="../main.qml" line="195"/> + <location filename="../main.qml" line="224"/> <source>Error</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="141"/> + <location filename="../main.qml" line="141"/> <source>Couldn't open wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="207"/> + <location filename="../main.qml" line="196"/> <source>Can't create transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="219"/> + <location filename="../main.qml" line="208"/> <source>Confirmation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="220"/> + <location filename="../main.qml" line="209"/> <source>Please confirm transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="221"/> + <location filename="../main.qml" line="210"/> <source> Address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="222"/> + <location filename="../main.qml" line="211"/> <source> Payment ID: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="223"/> + <location filename="../main.qml" line="212"/> <source> Amount: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="224"/> + <location filename="../main.qml" line="213"/> <source> Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="236"/> + <location filename="../main.qml" line="225"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="239"/> + <location filename="../main.qml" line="228"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="240"/> + <location filename="../main.qml" line="229"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="311"/> + <location filename="../main.qml" line="300"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> diff --git a/monero-core_en.ts b/translations/monero-core_en.ts similarity index 70% rename from monero-core_en.ts rename to translations/monero-core_en.ts index bae9d7a9..307233ba 100644 --- a/monero-core_en.ts +++ b/translations/monero-core_en.ts @@ -4,42 +4,42 @@ <context> <name>AddressBook</name> <message> - <location filename="pages/AddressBook.qml" line="47"/> + <location filename="../pages/AddressBook.qml" line="47"/> <source>Add new entry</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="56"/> + <location filename="../pages/AddressBook.qml" line="56"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="58"/> + <location filename="../pages/AddressBook.qml" line="58"/> <source><b>Tip tekst test</b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="77"/> + <location filename="../pages/AddressBook.qml" line="77"/> <source>Payment ID <font size='2'>(Optional)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="79"/> + <location filename="../pages/AddressBook.qml" line="79"/> <source><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 thevtransfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="98"/> + <location filename="../pages/AddressBook.qml" line="98"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="100"/> + <location filename="../pages/AddressBook.qml" line="100"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="125"/> + <location filename="../pages/AddressBook.qml" line="125"/> <source>ADD</source> <translation type="unfinished"></translation> </message> @@ -47,12 +47,12 @@ <context> <name>AddressBookTable</name> <message> - <location filename="components/AddressBookTable.qml" line="47"/> + <location filename="../components/AddressBookTable.qml" line="47"/> <source>No more results</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/AddressBookTable.qml" line="106"/> + <location filename="../components/AddressBookTable.qml" line="106"/> <source>Payment ID:</source> <translation type="unfinished"></translation> </message> @@ -60,47 +60,47 @@ <context> <name>BasicPanel</name> <message> - <location filename="BasicPanel.qml" line="78"/> + <location filename="../BasicPanel.qml" line="78"/> <source>Locked Balance:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="92"/> + <location filename="../BasicPanel.qml" line="92"/> <source>78.9239845</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="116"/> + <location filename="../BasicPanel.qml" line="116"/> <source>Availible Balance:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="130"/> + <location filename="../BasicPanel.qml" line="130"/> <source>2324.9239845</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="155"/> + <location filename="../BasicPanel.qml" line="155"/> <source>amount...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="163"/> + <location filename="../BasicPanel.qml" line="163"/> <source>SEND</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="179"/> + <location filename="../BasicPanel.qml" line="179"/> <source>destination...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="191"/> + <location filename="../BasicPanel.qml" line="191"/> <source>Privacy level</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="212"/> + <location filename="../BasicPanel.qml" line="212"/> <source>payment ID (optional)...</source> <translation type="unfinished"></translation> </message> @@ -108,17 +108,17 @@ <context> <name>Dashboard</name> <message> - <location filename="pages/Dashboard.qml" line="57"/> + <location filename="../pages/Dashboard.qml" line="57"/> <source>Quick transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Dashboard.qml" line="89"/> + <location filename="../pages/Dashboard.qml" line="89"/> <source>SEND</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Dashboard.qml" line="102"/> + <location filename="../pages/Dashboard.qml" line="102"/> <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> lookng for security level and address book? go to <a href='#'>Transfer</a> tab</source> <translation type="unfinished"></translation> </message> @@ -126,22 +126,22 @@ <context> <name>DashboardTable</name> <message> - <location filename="components/DashboardTable.qml" line="47"/> + <location filename="../components/DashboardTable.qml" line="47"/> <source>No more results</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/DashboardTable.qml" line="137"/> + <location filename="../components/DashboardTable.qml" line="137"/> <source>Date</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/DashboardTable.qml" line="172"/> + <location filename="../components/DashboardTable.qml" line="172"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/DashboardTable.qml" line="193"/> + <location filename="../components/DashboardTable.qml" line="193"/> <source>Amount</source> <translation type="unfinished"></translation> </message> @@ -149,73 +149,73 @@ <context> <name>History</name> <message> - <location filename="pages/History.qml" line="47"/> + <location filename="../pages/History.qml" line="47"/> <source>Filter trasactions history</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="56"/> + <location filename="../pages/History.qml" line="56"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="58"/> - <location filename="pages/History.qml" line="122"/> - <location filename="pages/History.qml" line="142"/> - <location filename="pages/History.qml" line="190"/> - <location filename="pages/History.qml" line="224"/> - <location filename="pages/History.qml" line="245"/> + <location filename="../pages/History.qml" line="58"/> + <location filename="../pages/History.qml" line="122"/> + <location filename="../pages/History.qml" line="142"/> + <location filename="../pages/History.qml" line="190"/> + <location filename="../pages/History.qml" line="224"/> + <location filename="../pages/History.qml" line="245"/> <source><b>Tip tekst test</b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="77"/> + <location filename="../pages/History.qml" line="77"/> <source>Payment ID <font size='2'>(Optional)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="79"/> + <location filename="../pages/History.qml" line="79"/> <source><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 thevtransfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="98"/> + <location filename="../pages/History.qml" line="98"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="100"/> + <location filename="../pages/History.qml" line="100"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="120"/> + <location filename="../pages/History.qml" line="120"/> <source>Date from</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="140"/> - <location filename="pages/History.qml" line="243"/> + <location filename="../pages/History.qml" line="140"/> + <location filename="../pages/History.qml" line="243"/> <source>To</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="160"/> + <location filename="../pages/History.qml" line="160"/> <source>FILTER</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="169"/> + <location filename="../pages/History.qml" line="169"/> <source>Advance filtering</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="188"/> + <location filename="../pages/History.qml" line="188"/> <source>Type of transation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="222"/> + <location filename="../pages/History.qml" line="222"/> <source>Amount from</source> <translation type="unfinished"></translation> </message> @@ -223,27 +223,27 @@ <context> <name>HistoryTable</name> <message> - <location filename="components/HistoryTable.qml" line="47"/> + <location filename="../components/HistoryTable.qml" line="47"/> <source>No more results</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="129"/> + <location filename="../components/HistoryTable.qml" line="129"/> <source>Payment ID:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="167"/> + <location filename="../components/HistoryTable.qml" line="167"/> <source>Date</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="202"/> + <location filename="../components/HistoryTable.qml" line="202"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="223"/> + <location filename="../components/HistoryTable.qml" line="223"/> <source>Amount</source> <translation type="unfinished"></translation> </message> @@ -251,42 +251,42 @@ <context> <name>LeftPanel</name> <message> - <location filename="LeftPanel.qml" line="106"/> - <source>Test tip 1<br/><br/>line 2</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="141"/> - <source>Test tip 2<br/><br/>line 2</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="LeftPanel.qml" line="103"/> + <location filename="../LeftPanel.qml" line="103"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="138"/> + <location filename="../LeftPanel.qml" line="106"/> + <source>Test tip 1<br/><br/>line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../LeftPanel.qml" line="138"/> <source>Unlocked balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="222"/> + <location filename="../LeftPanel.qml" line="141"/> + <source>Test tip 2<br/><br/>line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../LeftPanel.qml" line="222"/> <source>Transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="223"/> + <location filename="../LeftPanel.qml" line="223"/> <source>T</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="245"/> + <location filename="../LeftPanel.qml" line="245"/> <source>Receive</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="246"/> + <location filename="../LeftPanel.qml" line="246"/> <source>R</source> <translation type="unfinished"></translation> </message> @@ -294,17 +294,17 @@ <context> <name>NetworkStatusItem</name> <message> - <location filename="components/NetworkStatusItem.qml" line="58"/> + <location filename="../components/NetworkStatusItem.qml" line="58"/> <source>Network status</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/NetworkStatusItem.qml" line="66"/> + <location filename="../components/NetworkStatusItem.qml" line="66"/> <source>Connected</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/NetworkStatusItem.qml" line="66"/> + <location filename="../components/NetworkStatusItem.qml" line="66"/> <source>Disconnected</source> <translation type="unfinished"></translation> </message> @@ -312,17 +312,17 @@ <context> <name>PrivacyLevelSmall</name> <message> - <location filename="components/PrivacyLevelSmall.qml" line="102"/> + <location filename="../components/PrivacyLevelSmall.qml" line="102"/> <source>LOW</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/PrivacyLevelSmall.qml" line="113"/> + <location filename="../components/PrivacyLevelSmall.qml" line="113"/> <source>MEDIUM</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/PrivacyLevelSmall.qml" line="124"/> + <location filename="../components/PrivacyLevelSmall.qml" line="124"/> <source>HIGH</source> <translation type="unfinished"></translation> </message> @@ -330,22 +330,22 @@ <context> <name>Receive</name> <message> - <location filename="pages/Receive.qml" line="79"/> + <location filename="../pages/Receive.qml" line="79"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Receive.qml" line="106"/> + <location filename="../pages/Receive.qml" line="106"/> <source>Integrated address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Receive.qml" line="136"/> + <location filename="../pages/Receive.qml" line="136"/> <source>Payment ID</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Receive.qml" line="168"/> + <location filename="../pages/Receive.qml" line="168"/> <source>Generate</source> <translation type="unfinished"></translation> </message> @@ -353,7 +353,7 @@ <context> <name>RightPanel</name> <message> - <location filename="RightPanel.qml" line="58"/> + <location filename="../RightPanel.qml" line="58"/> <source>Twitter</source> <translation type="unfinished"></translation> </message> @@ -361,12 +361,12 @@ <context> <name>SearchInput</name> <message> - <location filename="components/SearchInput.qml" line="69"/> + <location filename="../components/SearchInput.qml" line="69"/> <source>Search by...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/SearchInput.qml" line="230"/> + <location filename="../components/SearchInput.qml" line="230"/> <source>SEARCH</source> <translation type="unfinished"></translation> </message> @@ -374,17 +374,17 @@ <context> <name>TickDelegate</name> <message> - <location filename="components/TickDelegate.qml" line="55"/> + <location filename="../components/TickDelegate.qml" line="55"/> <source>LOW</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/TickDelegate.qml" line="56"/> + <location filename="../components/TickDelegate.qml" line="56"/> <source>MEDIUM</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/TickDelegate.qml" line="57"/> + <location filename="../components/TickDelegate.qml" line="57"/> <source>HIGH</source> <translation type="unfinished"></translation> </message> @@ -392,47 +392,47 @@ <context> <name>Transfer</name> <message> - <location filename="pages/Transfer.qml" line="57"/> + <location filename="../pages/Transfer.qml" line="57"/> <source>Amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="67"/> + <location filename="../pages/Transfer.qml" line="67"/> <source>Transaction priority</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="89"/> + <location filename="../pages/Transfer.qml" line="89"/> <source>Amount...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="127"/> + <location filename="../pages/Transfer.qml" line="127"/> <source>Privacy Level</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="153"/> + <location filename="../pages/Transfer.qml" line="153"/> <source>Cost</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="167"/> + <location filename="../pages/Transfer.qml" line="167"/> <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> Address <font size='2'> ( Type in or select from </font> <a href='#'>Address</a><font size='2'> book )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="193"/> + <location filename="../pages/Transfer.qml" line="193"/> <source>Payment ID <font size='2'>( Optional )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="217"/> + <location filename="../pages/Transfer.qml" line="217"/> <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="237"/> + <location filename="../pages/Transfer.qml" line="237"/> <source>SEND</source> <translation type="unfinished"></translation> </message> @@ -440,37 +440,37 @@ <context> <name>WizardConfigure</name> <message> - <location filename="wizard/WizardConfigure.qml" line="79"/> + <location filename="../wizard/WizardConfigure.qml" line="79"/> <source>We’re almost there - let’s just configure some Monero preferences</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="97"/> + <location filename="../wizard/WizardConfigure.qml" line="97"/> <source>Kickstart the Monero blockchain?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="115"/> + <location filename="../wizard/WizardConfigure.qml" line="115"/> <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="126"/> + <location filename="../wizard/WizardConfigure.qml" line="126"/> <source>Enable disk conservation mode?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="144"/> + <location filename="../wizard/WizardConfigure.qml" line="144"/> <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="156"/> + <location filename="../wizard/WizardConfigure.qml" line="156"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="174"/> + <location filename="../wizard/WizardConfigure.qml" line="174"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -478,12 +478,12 @@ <context> <name>WizardCreateWallet</name> <message> - <location filename="wizard/WizardCreateWallet.qml" line="81"/> + <location filename="../wizard/WizardCreateWallet.qml" line="81"/> <source>A new wallet has been created for you</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardCreateWallet.qml" line="82"/> + <location filename="../wizard/WizardCreateWallet.qml" line="82"/> <source>This is the 25 word mnemonic for your wallet</source> <translation type="unfinished"></translation> </message> @@ -491,32 +491,32 @@ <context> <name>WizardDonation</name> <message> - <location filename="wizard/WizardDonation.qml" line="93"/> + <location filename="../wizard/WizardDonation.qml" line="93"/> <source>Monero development is solely supported by donations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="113"/> + <location filename="../wizard/WizardDonation.qml" line="113"/> <source>Enable auto-donations of?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="153"/> + <location filename="../wizard/WizardDonation.qml" line="153"/> <source>% of my fee added to each transaction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="164"/> + <location filename="../wizard/WizardDonation.qml" line="164"/> <source>For every transaction, a small transaction fee is charged. This option lets you add an additional amount, 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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="175"/> + <location filename="../wizard/WizardDonation.qml" line="175"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="193"/> + <location filename="../wizard/WizardDonation.qml" line="193"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -524,47 +524,47 @@ <context> <name>WizardFinish</name> <message> - <location filename="wizard/WizardFinish.qml" line="41"/> + <location filename="../wizard/WizardFinish.qml" line="41"/> <source><b>Language:</b> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="42"/> + <location filename="../wizard/WizardFinish.qml" line="42"/> <source><b>Account name:</b> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="43"/> + <location filename="../wizard/WizardFinish.qml" line="43"/> <source><b>Words:</b> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="44"/> + <location filename="../wizard/WizardFinish.qml" line="44"/> <source><b>Wallet Path: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="45"/> + <location filename="../wizard/WizardFinish.qml" line="45"/> <source><b>Enable auto donation: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="46"/> + <location filename="../wizard/WizardFinish.qml" line="46"/> <source><b>Auto donation amount: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="47"/> + <location filename="../wizard/WizardFinish.qml" line="47"/> <source><b>Allow background mining: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="51"/> + <location filename="../wizard/WizardFinish.qml" line="51"/> <source>An overview of your Monero configuration is below:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="102"/> + <location filename="../wizard/WizardFinish.qml" line="102"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -572,17 +572,17 @@ <context> <name>WizardMain</name> <message> - <location filename="wizard/WizardMain.qml" line="85"/> + <location filename="../wizard/WizardMain.qml" line="85"/> <source>Now that your wallet has been created, please set a password for the wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardMain.qml" line="87"/> + <location filename="../wizard/WizardMain.qml" line="87"/> <source>Now that your wallet has been restored, please set a password for the wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardMain.qml" line="308"/> + <location filename="../wizard/WizardMain.qml" line="308"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -590,17 +590,17 @@ <context> <name>WizardManageWalletUI</name> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="103"/> + <location filename="../wizard/WizardManageWalletUI.qml" line="103"/> <source>This is the name of your wallet. You can change it to a different name if you’d like:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="125"/> + <location filename="../wizard/WizardManageWalletUI.qml" line="125"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="175"/> + <location filename="../wizard/WizardManageWalletUI.qml" line="175"/> <source>Your wallet is stored in</source> <translation type="unfinished"></translation> </message> @@ -608,7 +608,7 @@ <context> <name>WizardMemoTextInput</name> <message> - <location filename="wizard/WizardMemoTextInput.qml" line="76"/> + <location filename="../wizard/WizardMemoTextInput.qml" line="76"/> <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> <translation type="unfinished"></translation> </message> @@ -616,22 +616,22 @@ <context> <name>WizardOptions</name> <message> - <location filename="wizard/WizardOptions.qml" line="62"/> + <location filename="../wizard/WizardOptions.qml" line="62"/> <source>Welcome to Monero!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="74"/> + <location filename="../wizard/WizardOptions.qml" line="74"/> <source>Please select one of the following options:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="110"/> + <location filename="../wizard/WizardOptions.qml" line="110"/> <source>This is my first time, I want to<br/>create a new account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="141"/> + <location filename="../wizard/WizardOptions.qml" line="141"/> <source>I want to recover my account<br/>from my 24 work seed</source> <translation type="unfinished"></translation> </message> @@ -639,28 +639,26 @@ <context> <name>WizardPassword</name> <message> - <location filename="wizard/WizardPassword.qml" line="121"/> + <location filename="../wizard/WizardPassword.qml" line="121"/> <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> - <oldsource>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> - Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</oldsource> <translation type="unfinished"></translation> </message> </context> <context> <name>WizardRecoveryWallet</name> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="69"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="69"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="70"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="70"/> <source>We're ready to recover your account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="71"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="71"/> <source>Please enter your 25 word private key</source> <translation type="unfinished"></translation> </message> @@ -668,12 +666,12 @@ <context> <name>WizardWelcome</name> <message> - <location filename="wizard/WizardWelcome.qml" line="65"/> + <location filename="../wizard/WizardWelcome.qml" line="65"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardWelcome.qml" line="76"/> + <location filename="../wizard/WizardWelcome.qml" line="76"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> @@ -681,75 +679,75 @@ <context> <name>main</name> <message> - <location filename="main.qml" line="140"/> - <location filename="main.qml" line="206"/> - <location filename="main.qml" line="235"/> + <location filename="../main.qml" line="140"/> + <location filename="../main.qml" line="195"/> + <location filename="../main.qml" line="224"/> <source>Error</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="141"/> + <location filename="../main.qml" line="141"/> <source>Couldn't open wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="207"/> + <location filename="../main.qml" line="196"/> <source>Can't create transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="219"/> + <location filename="../main.qml" line="208"/> <source>Confirmation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="220"/> + <location filename="../main.qml" line="209"/> <source>Please confirm transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="221"/> + <location filename="../main.qml" line="210"/> <source> Address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="222"/> + <location filename="../main.qml" line="211"/> <source> Payment ID: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="223"/> + <location filename="../main.qml" line="212"/> <source> Amount: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="224"/> + <location filename="../main.qml" line="213"/> <source> Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="236"/> + <location filename="../main.qml" line="225"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="239"/> + <location filename="../main.qml" line="228"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="240"/> + <location filename="../main.qml" line="229"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="311"/> + <location filename="../main.qml" line="300"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> diff --git a/monero-core_it.ts b/translations/monero-core_it.ts similarity index 70% rename from monero-core_it.ts rename to translations/monero-core_it.ts index b6bec1a6..e59d65eb 100644 --- a/monero-core_it.ts +++ b/translations/monero-core_it.ts @@ -4,42 +4,42 @@ <context> <name>AddressBook</name> <message> - <location filename="pages/AddressBook.qml" line="47"/> + <location filename="../pages/AddressBook.qml" line="47"/> <source>Add new entry</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="56"/> + <location filename="../pages/AddressBook.qml" line="56"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="58"/> + <location filename="../pages/AddressBook.qml" line="58"/> <source><b>Tip tekst test</b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="77"/> + <location filename="../pages/AddressBook.qml" line="77"/> <source>Payment ID <font size='2'>(Optional)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="79"/> + <location filename="../pages/AddressBook.qml" line="79"/> <source><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 thevtransfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="98"/> + <location filename="../pages/AddressBook.qml" line="98"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="100"/> + <location filename="../pages/AddressBook.qml" line="100"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="125"/> + <location filename="../pages/AddressBook.qml" line="125"/> <source>ADD</source> <translation type="unfinished"></translation> </message> @@ -47,12 +47,12 @@ <context> <name>AddressBookTable</name> <message> - <location filename="components/AddressBookTable.qml" line="47"/> + <location filename="../components/AddressBookTable.qml" line="47"/> <source>No more results</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/AddressBookTable.qml" line="106"/> + <location filename="../components/AddressBookTable.qml" line="106"/> <source>Payment ID:</source> <translation type="unfinished"></translation> </message> @@ -60,47 +60,47 @@ <context> <name>BasicPanel</name> <message> - <location filename="BasicPanel.qml" line="78"/> + <location filename="../BasicPanel.qml" line="78"/> <source>Locked Balance:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="92"/> + <location filename="../BasicPanel.qml" line="92"/> <source>78.9239845</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="116"/> + <location filename="../BasicPanel.qml" line="116"/> <source>Availible Balance:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="130"/> + <location filename="../BasicPanel.qml" line="130"/> <source>2324.9239845</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="155"/> + <location filename="../BasicPanel.qml" line="155"/> <source>amount...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="163"/> + <location filename="../BasicPanel.qml" line="163"/> <source>SEND</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="179"/> + <location filename="../BasicPanel.qml" line="179"/> <source>destination...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="191"/> + <location filename="../BasicPanel.qml" line="191"/> <source>Privacy level</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="212"/> + <location filename="../BasicPanel.qml" line="212"/> <source>payment ID (optional)...</source> <translation type="unfinished"></translation> </message> @@ -108,17 +108,17 @@ <context> <name>Dashboard</name> <message> - <location filename="pages/Dashboard.qml" line="57"/> + <location filename="../pages/Dashboard.qml" line="57"/> <source>Quick transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Dashboard.qml" line="89"/> + <location filename="../pages/Dashboard.qml" line="89"/> <source>SEND</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Dashboard.qml" line="102"/> + <location filename="../pages/Dashboard.qml" line="102"/> <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> lookng for security level and address book? go to <a href='#'>Transfer</a> tab</source> <translation type="unfinished"></translation> </message> @@ -126,22 +126,22 @@ <context> <name>DashboardTable</name> <message> - <location filename="components/DashboardTable.qml" line="47"/> + <location filename="../components/DashboardTable.qml" line="47"/> <source>No more results</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/DashboardTable.qml" line="137"/> + <location filename="../components/DashboardTable.qml" line="137"/> <source>Date</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/DashboardTable.qml" line="172"/> + <location filename="../components/DashboardTable.qml" line="172"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/DashboardTable.qml" line="193"/> + <location filename="../components/DashboardTable.qml" line="193"/> <source>Amount</source> <translation type="unfinished"></translation> </message> @@ -149,73 +149,73 @@ <context> <name>History</name> <message> - <location filename="pages/History.qml" line="47"/> + <location filename="../pages/History.qml" line="47"/> <source>Filter trasactions history</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="56"/> + <location filename="../pages/History.qml" line="56"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="58"/> - <location filename="pages/History.qml" line="122"/> - <location filename="pages/History.qml" line="142"/> - <location filename="pages/History.qml" line="190"/> - <location filename="pages/History.qml" line="224"/> - <location filename="pages/History.qml" line="245"/> + <location filename="../pages/History.qml" line="58"/> + <location filename="../pages/History.qml" line="122"/> + <location filename="../pages/History.qml" line="142"/> + <location filename="../pages/History.qml" line="190"/> + <location filename="../pages/History.qml" line="224"/> + <location filename="../pages/History.qml" line="245"/> <source><b>Tip tekst test</b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="77"/> + <location filename="../pages/History.qml" line="77"/> <source>Payment ID <font size='2'>(Optional)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="79"/> + <location filename="../pages/History.qml" line="79"/> <source><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 thevtransfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="98"/> + <location filename="../pages/History.qml" line="98"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="100"/> + <location filename="../pages/History.qml" line="100"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="120"/> + <location filename="../pages/History.qml" line="120"/> <source>Date from</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="140"/> - <location filename="pages/History.qml" line="243"/> + <location filename="../pages/History.qml" line="140"/> + <location filename="../pages/History.qml" line="243"/> <source>To</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="160"/> + <location filename="../pages/History.qml" line="160"/> <source>FILTER</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="169"/> + <location filename="../pages/History.qml" line="169"/> <source>Advance filtering</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="188"/> + <location filename="../pages/History.qml" line="188"/> <source>Type of transation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="222"/> + <location filename="../pages/History.qml" line="222"/> <source>Amount from</source> <translation type="unfinished"></translation> </message> @@ -223,27 +223,27 @@ <context> <name>HistoryTable</name> <message> - <location filename="components/HistoryTable.qml" line="47"/> + <location filename="../components/HistoryTable.qml" line="47"/> <source>No more results</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="129"/> + <location filename="../components/HistoryTable.qml" line="129"/> <source>Payment ID:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="167"/> + <location filename="../components/HistoryTable.qml" line="167"/> <source>Date</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="202"/> + <location filename="../components/HistoryTable.qml" line="202"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="223"/> + <location filename="../components/HistoryTable.qml" line="223"/> <source>Amount</source> <translation type="unfinished"></translation> </message> @@ -251,42 +251,42 @@ <context> <name>LeftPanel</name> <message> - <location filename="LeftPanel.qml" line="103"/> + <location filename="../LeftPanel.qml" line="103"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="106"/> + <location filename="../LeftPanel.qml" line="106"/> <source>Test tip 1<br/><br/>line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="138"/> + <location filename="../LeftPanel.qml" line="138"/> <source>Unlocked balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="141"/> + <location filename="../LeftPanel.qml" line="141"/> <source>Test tip 2<br/><br/>line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="222"/> + <location filename="../LeftPanel.qml" line="222"/> <source>Transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="223"/> + <location filename="../LeftPanel.qml" line="223"/> <source>T</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="245"/> + <location filename="../LeftPanel.qml" line="245"/> <source>Receive</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="246"/> + <location filename="../LeftPanel.qml" line="246"/> <source>R</source> <translation type="unfinished"></translation> </message> @@ -294,17 +294,17 @@ <context> <name>NetworkStatusItem</name> <message> - <location filename="components/NetworkStatusItem.qml" line="58"/> + <location filename="../components/NetworkStatusItem.qml" line="58"/> <source>Network status</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/NetworkStatusItem.qml" line="66"/> + <location filename="../components/NetworkStatusItem.qml" line="66"/> <source>Connected</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/NetworkStatusItem.qml" line="66"/> + <location filename="../components/NetworkStatusItem.qml" line="66"/> <source>Disconnected</source> <translation type="unfinished"></translation> </message> @@ -312,17 +312,17 @@ <context> <name>PrivacyLevelSmall</name> <message> - <location filename="components/PrivacyLevelSmall.qml" line="102"/> + <location filename="../components/PrivacyLevelSmall.qml" line="102"/> <source>LOW</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/PrivacyLevelSmall.qml" line="113"/> + <location filename="../components/PrivacyLevelSmall.qml" line="113"/> <source>MEDIUM</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/PrivacyLevelSmall.qml" line="124"/> + <location filename="../components/PrivacyLevelSmall.qml" line="124"/> <source>HIGH</source> <translation type="unfinished"></translation> </message> @@ -330,22 +330,22 @@ <context> <name>Receive</name> <message> - <location filename="pages/Receive.qml" line="79"/> + <location filename="../pages/Receive.qml" line="79"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Receive.qml" line="106"/> + <location filename="../pages/Receive.qml" line="106"/> <source>Integrated address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Receive.qml" line="136"/> + <location filename="../pages/Receive.qml" line="136"/> <source>Payment ID</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Receive.qml" line="168"/> + <location filename="../pages/Receive.qml" line="168"/> <source>Generate</source> <translation type="unfinished"></translation> </message> @@ -353,7 +353,7 @@ <context> <name>RightPanel</name> <message> - <location filename="RightPanel.qml" line="58"/> + <location filename="../RightPanel.qml" line="58"/> <source>Twitter</source> <translation type="unfinished"></translation> </message> @@ -361,12 +361,12 @@ <context> <name>SearchInput</name> <message> - <location filename="components/SearchInput.qml" line="69"/> + <location filename="../components/SearchInput.qml" line="69"/> <source>Search by...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/SearchInput.qml" line="230"/> + <location filename="../components/SearchInput.qml" line="230"/> <source>SEARCH</source> <translation type="unfinished"></translation> </message> @@ -374,17 +374,17 @@ <context> <name>TickDelegate</name> <message> - <location filename="components/TickDelegate.qml" line="55"/> + <location filename="../components/TickDelegate.qml" line="55"/> <source>LOW</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/TickDelegate.qml" line="56"/> + <location filename="../components/TickDelegate.qml" line="56"/> <source>MEDIUM</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/TickDelegate.qml" line="57"/> + <location filename="../components/TickDelegate.qml" line="57"/> <source>HIGH</source> <translation type="unfinished"></translation> </message> @@ -392,47 +392,47 @@ <context> <name>Transfer</name> <message> - <location filename="pages/Transfer.qml" line="57"/> + <location filename="../pages/Transfer.qml" line="57"/> <source>Amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="67"/> + <location filename="../pages/Transfer.qml" line="67"/> <source>Transaction priority</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="89"/> + <location filename="../pages/Transfer.qml" line="89"/> <source>Amount...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="127"/> + <location filename="../pages/Transfer.qml" line="127"/> <source>Privacy Level</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="153"/> + <location filename="../pages/Transfer.qml" line="153"/> <source>Cost</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="167"/> + <location filename="../pages/Transfer.qml" line="167"/> <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> Address <font size='2'> ( Type in or select from </font> <a href='#'>Address</a><font size='2'> book )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="193"/> + <location filename="../pages/Transfer.qml" line="193"/> <source>Payment ID <font size='2'>( Optional )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="217"/> + <location filename="../pages/Transfer.qml" line="217"/> <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="237"/> + <location filename="../pages/Transfer.qml" line="237"/> <source>SEND</source> <translation type="unfinished"></translation> </message> @@ -440,37 +440,37 @@ <context> <name>WizardConfigure</name> <message> - <location filename="wizard/WizardConfigure.qml" line="79"/> + <location filename="../wizard/WizardConfigure.qml" line="79"/> <source>We’re almost there - let’s just configure some Monero preferences</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="97"/> + <location filename="../wizard/WizardConfigure.qml" line="97"/> <source>Kickstart the Monero blockchain?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="115"/> + <location filename="../wizard/WizardConfigure.qml" line="115"/> <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="126"/> + <location filename="../wizard/WizardConfigure.qml" line="126"/> <source>Enable disk conservation mode?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="144"/> + <location filename="../wizard/WizardConfigure.qml" line="144"/> <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="156"/> + <location filename="../wizard/WizardConfigure.qml" line="156"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="174"/> + <location filename="../wizard/WizardConfigure.qml" line="174"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -478,12 +478,12 @@ <context> <name>WizardCreateWallet</name> <message> - <location filename="wizard/WizardCreateWallet.qml" line="81"/> + <location filename="../wizard/WizardCreateWallet.qml" line="81"/> <source>A new wallet has been created for you</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardCreateWallet.qml" line="82"/> + <location filename="../wizard/WizardCreateWallet.qml" line="82"/> <source>This is the 25 word mnemonic for your wallet</source> <translation type="unfinished"></translation> </message> @@ -491,32 +491,32 @@ <context> <name>WizardDonation</name> <message> - <location filename="wizard/WizardDonation.qml" line="93"/> + <location filename="../wizard/WizardDonation.qml" line="93"/> <source>Monero development is solely supported by donations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="113"/> + <location filename="../wizard/WizardDonation.qml" line="113"/> <source>Enable auto-donations of?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="153"/> + <location filename="../wizard/WizardDonation.qml" line="153"/> <source>% of my fee added to each transaction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="164"/> + <location filename="../wizard/WizardDonation.qml" line="164"/> <source>For every transaction, a small transaction fee is charged. This option lets you add an additional amount, 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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="175"/> + <location filename="../wizard/WizardDonation.qml" line="175"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="193"/> + <location filename="../wizard/WizardDonation.qml" line="193"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -524,47 +524,47 @@ <context> <name>WizardFinish</name> <message> - <location filename="wizard/WizardFinish.qml" line="41"/> + <location filename="../wizard/WizardFinish.qml" line="41"/> <source><b>Language:</b> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="42"/> + <location filename="../wizard/WizardFinish.qml" line="42"/> <source><b>Account name:</b> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="43"/> + <location filename="../wizard/WizardFinish.qml" line="43"/> <source><b>Words:</b> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="44"/> + <location filename="../wizard/WizardFinish.qml" line="44"/> <source><b>Wallet Path: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="45"/> + <location filename="../wizard/WizardFinish.qml" line="45"/> <source><b>Enable auto donation: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="46"/> + <location filename="../wizard/WizardFinish.qml" line="46"/> <source><b>Auto donation amount: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="47"/> + <location filename="../wizard/WizardFinish.qml" line="47"/> <source><b>Allow background mining: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="51"/> + <location filename="../wizard/WizardFinish.qml" line="51"/> <source>An overview of your Monero configuration is below:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="102"/> + <location filename="../wizard/WizardFinish.qml" line="102"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -572,17 +572,17 @@ <context> <name>WizardMain</name> <message> - <location filename="wizard/WizardMain.qml" line="85"/> + <location filename="../wizard/WizardMain.qml" line="85"/> <source>Now that your wallet has been created, please set a password for the wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardMain.qml" line="87"/> + <location filename="../wizard/WizardMain.qml" line="87"/> <source>Now that your wallet has been restored, please set a password for the wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardMain.qml" line="308"/> + <location filename="../wizard/WizardMain.qml" line="308"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -590,17 +590,17 @@ <context> <name>WizardManageWalletUI</name> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="103"/> + <location filename="../wizard/WizardManageWalletUI.qml" line="103"/> <source>This is the name of your wallet. You can change it to a different name if you’d like:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="125"/> + <location filename="../wizard/WizardManageWalletUI.qml" line="125"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="175"/> + <location filename="../wizard/WizardManageWalletUI.qml" line="175"/> <source>Your wallet is stored in</source> <translation type="unfinished"></translation> </message> @@ -608,7 +608,7 @@ <context> <name>WizardMemoTextInput</name> <message> - <location filename="wizard/WizardMemoTextInput.qml" line="76"/> + <location filename="../wizard/WizardMemoTextInput.qml" line="76"/> <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> <translation type="unfinished"></translation> </message> @@ -616,22 +616,22 @@ <context> <name>WizardOptions</name> <message> - <location filename="wizard/WizardOptions.qml" line="62"/> + <location filename="../wizard/WizardOptions.qml" line="62"/> <source>Welcome to Monero!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="74"/> + <location filename="../wizard/WizardOptions.qml" line="74"/> <source>Please select one of the following options:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="110"/> + <location filename="../wizard/WizardOptions.qml" line="110"/> <source>This is my first time, I want to<br/>create a new account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="141"/> + <location filename="../wizard/WizardOptions.qml" line="141"/> <source>I want to recover my account<br/>from my 24 work seed</source> <translation type="unfinished"></translation> </message> @@ -639,7 +639,7 @@ <context> <name>WizardPassword</name> <message> - <location filename="wizard/WizardPassword.qml" line="121"/> + <location filename="../wizard/WizardPassword.qml" line="121"/> <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> <translation type="unfinished"></translation> @@ -648,17 +648,17 @@ <context> <name>WizardRecoveryWallet</name> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="69"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="69"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="70"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="70"/> <source>We're ready to recover your account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="71"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="71"/> <source>Please enter your 25 word private key</source> <translation type="unfinished"></translation> </message> @@ -666,12 +666,12 @@ <context> <name>WizardWelcome</name> <message> - <location filename="wizard/WizardWelcome.qml" line="65"/> + <location filename="../wizard/WizardWelcome.qml" line="65"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardWelcome.qml" line="76"/> + <location filename="../wizard/WizardWelcome.qml" line="76"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> @@ -679,75 +679,75 @@ <context> <name>main</name> <message> - <location filename="main.qml" line="140"/> - <location filename="main.qml" line="206"/> - <location filename="main.qml" line="235"/> + <location filename="../main.qml" line="140"/> + <location filename="../main.qml" line="195"/> + <location filename="../main.qml" line="224"/> <source>Error</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="141"/> + <location filename="../main.qml" line="141"/> <source>Couldn't open wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="207"/> + <location filename="../main.qml" line="196"/> <source>Can't create transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="219"/> + <location filename="../main.qml" line="208"/> <source>Confirmation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="220"/> + <location filename="../main.qml" line="209"/> <source>Please confirm transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="221"/> + <location filename="../main.qml" line="210"/> <source> Address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="222"/> + <location filename="../main.qml" line="211"/> <source> Payment ID: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="223"/> + <location filename="../main.qml" line="212"/> <source> Amount: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="224"/> + <location filename="../main.qml" line="213"/> <source> Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="236"/> + <location filename="../main.qml" line="225"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="239"/> + <location filename="../main.qml" line="228"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="240"/> + <location filename="../main.qml" line="229"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="311"/> + <location filename="../main.qml" line="300"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> diff --git a/monero-core_ru.ts b/translations/monero-core_ru.ts similarity index 70% rename from monero-core_ru.ts rename to translations/monero-core_ru.ts index 8682ecb9..a5c61585 100644 --- a/monero-core_ru.ts +++ b/translations/monero-core_ru.ts @@ -4,42 +4,42 @@ <context> <name>AddressBook</name> <message> - <location filename="pages/AddressBook.qml" line="47"/> + <location filename="../pages/AddressBook.qml" line="47"/> <source>Add new entry</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="56"/> + <location filename="../pages/AddressBook.qml" line="56"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="58"/> + <location filename="../pages/AddressBook.qml" line="58"/> <source><b>Tip tekst test</b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="77"/> + <location filename="../pages/AddressBook.qml" line="77"/> <source>Payment ID <font size='2'>(Optional)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="79"/> + <location filename="../pages/AddressBook.qml" line="79"/> <source><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 thevtransfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="98"/> + <location filename="../pages/AddressBook.qml" line="98"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="100"/> + <location filename="../pages/AddressBook.qml" line="100"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="125"/> + <location filename="../pages/AddressBook.qml" line="125"/> <source>ADD</source> <translation type="unfinished"></translation> </message> @@ -47,12 +47,12 @@ <context> <name>AddressBookTable</name> <message> - <location filename="components/AddressBookTable.qml" line="47"/> + <location filename="../components/AddressBookTable.qml" line="47"/> <source>No more results</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/AddressBookTable.qml" line="106"/> + <location filename="../components/AddressBookTable.qml" line="106"/> <source>Payment ID:</source> <translation type="unfinished"></translation> </message> @@ -60,47 +60,47 @@ <context> <name>BasicPanel</name> <message> - <location filename="BasicPanel.qml" line="78"/> + <location filename="../BasicPanel.qml" line="78"/> <source>Locked Balance:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="92"/> + <location filename="../BasicPanel.qml" line="92"/> <source>78.9239845</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="116"/> + <location filename="../BasicPanel.qml" line="116"/> <source>Availible Balance:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="130"/> + <location filename="../BasicPanel.qml" line="130"/> <source>2324.9239845</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="155"/> + <location filename="../BasicPanel.qml" line="155"/> <source>amount...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="163"/> + <location filename="../BasicPanel.qml" line="163"/> <source>SEND</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="179"/> + <location filename="../BasicPanel.qml" line="179"/> <source>destination...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="191"/> + <location filename="../BasicPanel.qml" line="191"/> <source>Privacy level</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="212"/> + <location filename="../BasicPanel.qml" line="212"/> <source>payment ID (optional)...</source> <translation type="unfinished"></translation> </message> @@ -108,17 +108,17 @@ <context> <name>Dashboard</name> <message> - <location filename="pages/Dashboard.qml" line="57"/> + <location filename="../pages/Dashboard.qml" line="57"/> <source>Quick transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Dashboard.qml" line="89"/> + <location filename="../pages/Dashboard.qml" line="89"/> <source>SEND</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Dashboard.qml" line="102"/> + <location filename="../pages/Dashboard.qml" line="102"/> <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> lookng for security level and address book? go to <a href='#'>Transfer</a> tab</source> <translation type="unfinished"></translation> </message> @@ -126,22 +126,22 @@ <context> <name>DashboardTable</name> <message> - <location filename="components/DashboardTable.qml" line="47"/> + <location filename="../components/DashboardTable.qml" line="47"/> <source>No more results</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/DashboardTable.qml" line="137"/> + <location filename="../components/DashboardTable.qml" line="137"/> <source>Date</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/DashboardTable.qml" line="172"/> + <location filename="../components/DashboardTable.qml" line="172"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/DashboardTable.qml" line="193"/> + <location filename="../components/DashboardTable.qml" line="193"/> <source>Amount</source> <translation type="unfinished"></translation> </message> @@ -149,73 +149,73 @@ <context> <name>History</name> <message> - <location filename="pages/History.qml" line="47"/> + <location filename="../pages/History.qml" line="47"/> <source>Filter trasactions history</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="56"/> + <location filename="../pages/History.qml" line="56"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="58"/> - <location filename="pages/History.qml" line="122"/> - <location filename="pages/History.qml" line="142"/> - <location filename="pages/History.qml" line="190"/> - <location filename="pages/History.qml" line="224"/> - <location filename="pages/History.qml" line="245"/> + <location filename="../pages/History.qml" line="58"/> + <location filename="../pages/History.qml" line="122"/> + <location filename="../pages/History.qml" line="142"/> + <location filename="../pages/History.qml" line="190"/> + <location filename="../pages/History.qml" line="224"/> + <location filename="../pages/History.qml" line="245"/> <source><b>Tip tekst test</b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="77"/> + <location filename="../pages/History.qml" line="77"/> <source>Payment ID <font size='2'>(Optional)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="79"/> + <location filename="../pages/History.qml" line="79"/> <source><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 thevtransfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="98"/> + <location filename="../pages/History.qml" line="98"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="100"/> + <location filename="../pages/History.qml" line="100"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="120"/> + <location filename="../pages/History.qml" line="120"/> <source>Date from</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="140"/> - <location filename="pages/History.qml" line="243"/> + <location filename="../pages/History.qml" line="140"/> + <location filename="../pages/History.qml" line="243"/> <source>To</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="160"/> + <location filename="../pages/History.qml" line="160"/> <source>FILTER</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="169"/> + <location filename="../pages/History.qml" line="169"/> <source>Advance filtering</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="188"/> + <location filename="../pages/History.qml" line="188"/> <source>Type of transation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="222"/> + <location filename="../pages/History.qml" line="222"/> <source>Amount from</source> <translation type="unfinished"></translation> </message> @@ -223,27 +223,27 @@ <context> <name>HistoryTable</name> <message> - <location filename="components/HistoryTable.qml" line="47"/> + <location filename="../components/HistoryTable.qml" line="47"/> <source>No more results</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="129"/> + <location filename="../components/HistoryTable.qml" line="129"/> <source>Payment ID:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="167"/> + <location filename="../components/HistoryTable.qml" line="167"/> <source>Date</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="202"/> + <location filename="../components/HistoryTable.qml" line="202"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="223"/> + <location filename="../components/HistoryTable.qml" line="223"/> <source>Amount</source> <translation type="unfinished"></translation> </message> @@ -251,42 +251,42 @@ <context> <name>LeftPanel</name> <message> - <location filename="LeftPanel.qml" line="103"/> + <location filename="../LeftPanel.qml" line="103"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="106"/> + <location filename="../LeftPanel.qml" line="106"/> <source>Test tip 1<br/><br/>line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="138"/> + <location filename="../LeftPanel.qml" line="138"/> <source>Unlocked balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="141"/> + <location filename="../LeftPanel.qml" line="141"/> <source>Test tip 2<br/><br/>line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="222"/> + <location filename="../LeftPanel.qml" line="222"/> <source>Transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="223"/> + <location filename="../LeftPanel.qml" line="223"/> <source>T</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="245"/> + <location filename="../LeftPanel.qml" line="245"/> <source>Receive</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="246"/> + <location filename="../LeftPanel.qml" line="246"/> <source>R</source> <translation type="unfinished"></translation> </message> @@ -294,17 +294,17 @@ <context> <name>NetworkStatusItem</name> <message> - <location filename="components/NetworkStatusItem.qml" line="58"/> + <location filename="../components/NetworkStatusItem.qml" line="58"/> <source>Network status</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/NetworkStatusItem.qml" line="66"/> + <location filename="../components/NetworkStatusItem.qml" line="66"/> <source>Connected</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/NetworkStatusItem.qml" line="66"/> + <location filename="../components/NetworkStatusItem.qml" line="66"/> <source>Disconnected</source> <translation type="unfinished"></translation> </message> @@ -312,17 +312,17 @@ <context> <name>PrivacyLevelSmall</name> <message> - <location filename="components/PrivacyLevelSmall.qml" line="102"/> + <location filename="../components/PrivacyLevelSmall.qml" line="102"/> <source>LOW</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/PrivacyLevelSmall.qml" line="113"/> + <location filename="../components/PrivacyLevelSmall.qml" line="113"/> <source>MEDIUM</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/PrivacyLevelSmall.qml" line="124"/> + <location filename="../components/PrivacyLevelSmall.qml" line="124"/> <source>HIGH</source> <translation type="unfinished"></translation> </message> @@ -330,22 +330,22 @@ <context> <name>Receive</name> <message> - <location filename="pages/Receive.qml" line="79"/> + <location filename="../pages/Receive.qml" line="79"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Receive.qml" line="106"/> + <location filename="../pages/Receive.qml" line="106"/> <source>Integrated address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Receive.qml" line="136"/> + <location filename="../pages/Receive.qml" line="136"/> <source>Payment ID</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Receive.qml" line="168"/> + <location filename="../pages/Receive.qml" line="168"/> <source>Generate</source> <translation type="unfinished"></translation> </message> @@ -353,7 +353,7 @@ <context> <name>RightPanel</name> <message> - <location filename="RightPanel.qml" line="58"/> + <location filename="../RightPanel.qml" line="58"/> <source>Twitter</source> <translation type="unfinished"></translation> </message> @@ -361,12 +361,12 @@ <context> <name>SearchInput</name> <message> - <location filename="components/SearchInput.qml" line="69"/> + <location filename="../components/SearchInput.qml" line="69"/> <source>Search by...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/SearchInput.qml" line="230"/> + <location filename="../components/SearchInput.qml" line="230"/> <source>SEARCH</source> <translation type="unfinished"></translation> </message> @@ -374,17 +374,17 @@ <context> <name>TickDelegate</name> <message> - <location filename="components/TickDelegate.qml" line="55"/> + <location filename="../components/TickDelegate.qml" line="55"/> <source>LOW</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/TickDelegate.qml" line="56"/> + <location filename="../components/TickDelegate.qml" line="56"/> <source>MEDIUM</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/TickDelegate.qml" line="57"/> + <location filename="../components/TickDelegate.qml" line="57"/> <source>HIGH</source> <translation type="unfinished"></translation> </message> @@ -392,47 +392,47 @@ <context> <name>Transfer</name> <message> - <location filename="pages/Transfer.qml" line="57"/> + <location filename="../pages/Transfer.qml" line="57"/> <source>Amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="67"/> + <location filename="../pages/Transfer.qml" line="67"/> <source>Transaction priority</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="89"/> + <location filename="../pages/Transfer.qml" line="89"/> <source>Amount...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="127"/> + <location filename="../pages/Transfer.qml" line="127"/> <source>Privacy Level</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="153"/> + <location filename="../pages/Transfer.qml" line="153"/> <source>Cost</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="167"/> + <location filename="../pages/Transfer.qml" line="167"/> <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> Address <font size='2'> ( Type in or select from </font> <a href='#'>Address</a><font size='2'> book )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="193"/> + <location filename="../pages/Transfer.qml" line="193"/> <source>Payment ID <font size='2'>( Optional )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="217"/> + <location filename="../pages/Transfer.qml" line="217"/> <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="237"/> + <location filename="../pages/Transfer.qml" line="237"/> <source>SEND</source> <translation type="unfinished"></translation> </message> @@ -440,37 +440,37 @@ <context> <name>WizardConfigure</name> <message> - <location filename="wizard/WizardConfigure.qml" line="79"/> + <location filename="../wizard/WizardConfigure.qml" line="79"/> <source>We’re almost there - let’s just configure some Monero preferences</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="97"/> + <location filename="../wizard/WizardConfigure.qml" line="97"/> <source>Kickstart the Monero blockchain?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="115"/> + <location filename="../wizard/WizardConfigure.qml" line="115"/> <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="126"/> + <location filename="../wizard/WizardConfigure.qml" line="126"/> <source>Enable disk conservation mode?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="144"/> + <location filename="../wizard/WizardConfigure.qml" line="144"/> <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="156"/> + <location filename="../wizard/WizardConfigure.qml" line="156"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="174"/> + <location filename="../wizard/WizardConfigure.qml" line="174"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -478,12 +478,12 @@ <context> <name>WizardCreateWallet</name> <message> - <location filename="wizard/WizardCreateWallet.qml" line="81"/> + <location filename="../wizard/WizardCreateWallet.qml" line="81"/> <source>A new wallet has been created for you</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardCreateWallet.qml" line="82"/> + <location filename="../wizard/WizardCreateWallet.qml" line="82"/> <source>This is the 25 word mnemonic for your wallet</source> <translation type="unfinished"></translation> </message> @@ -491,32 +491,32 @@ <context> <name>WizardDonation</name> <message> - <location filename="wizard/WizardDonation.qml" line="93"/> + <location filename="../wizard/WizardDonation.qml" line="93"/> <source>Monero development is solely supported by donations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="113"/> + <location filename="../wizard/WizardDonation.qml" line="113"/> <source>Enable auto-donations of?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="153"/> + <location filename="../wizard/WizardDonation.qml" line="153"/> <source>% of my fee added to each transaction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="164"/> + <location filename="../wizard/WizardDonation.qml" line="164"/> <source>For every transaction, a small transaction fee is charged. This option lets you add an additional amount, 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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="175"/> + <location filename="../wizard/WizardDonation.qml" line="175"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="193"/> + <location filename="../wizard/WizardDonation.qml" line="193"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -524,47 +524,47 @@ <context> <name>WizardFinish</name> <message> - <location filename="wizard/WizardFinish.qml" line="41"/> + <location filename="../wizard/WizardFinish.qml" line="41"/> <source><b>Language:</b> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="42"/> + <location filename="../wizard/WizardFinish.qml" line="42"/> <source><b>Account name:</b> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="43"/> + <location filename="../wizard/WizardFinish.qml" line="43"/> <source><b>Words:</b> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="44"/> + <location filename="../wizard/WizardFinish.qml" line="44"/> <source><b>Wallet Path: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="45"/> + <location filename="../wizard/WizardFinish.qml" line="45"/> <source><b>Enable auto donation: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="46"/> + <location filename="../wizard/WizardFinish.qml" line="46"/> <source><b>Auto donation amount: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="47"/> + <location filename="../wizard/WizardFinish.qml" line="47"/> <source><b>Allow background mining: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="51"/> + <location filename="../wizard/WizardFinish.qml" line="51"/> <source>An overview of your Monero configuration is below:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="102"/> + <location filename="../wizard/WizardFinish.qml" line="102"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -572,17 +572,17 @@ <context> <name>WizardMain</name> <message> - <location filename="wizard/WizardMain.qml" line="85"/> + <location filename="../wizard/WizardMain.qml" line="85"/> <source>Now that your wallet has been created, please set a password for the wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardMain.qml" line="87"/> + <location filename="../wizard/WizardMain.qml" line="87"/> <source>Now that your wallet has been restored, please set a password for the wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardMain.qml" line="308"/> + <location filename="../wizard/WizardMain.qml" line="308"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -590,17 +590,17 @@ <context> <name>WizardManageWalletUI</name> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="103"/> + <location filename="../wizard/WizardManageWalletUI.qml" line="103"/> <source>This is the name of your wallet. You can change it to a different name if you’d like:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="125"/> + <location filename="../wizard/WizardManageWalletUI.qml" line="125"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="175"/> + <location filename="../wizard/WizardManageWalletUI.qml" line="175"/> <source>Your wallet is stored in</source> <translation type="unfinished"></translation> </message> @@ -608,7 +608,7 @@ <context> <name>WizardMemoTextInput</name> <message> - <location filename="wizard/WizardMemoTextInput.qml" line="76"/> + <location filename="../wizard/WizardMemoTextInput.qml" line="76"/> <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> <translation type="unfinished"></translation> </message> @@ -616,22 +616,22 @@ <context> <name>WizardOptions</name> <message> - <location filename="wizard/WizardOptions.qml" line="62"/> + <location filename="../wizard/WizardOptions.qml" line="62"/> <source>Welcome to Monero!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="74"/> + <location filename="../wizard/WizardOptions.qml" line="74"/> <source>Please select one of the following options:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="110"/> + <location filename="../wizard/WizardOptions.qml" line="110"/> <source>This is my first time, I want to<br/>create a new account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="141"/> + <location filename="../wizard/WizardOptions.qml" line="141"/> <source>I want to recover my account<br/>from my 24 work seed</source> <translation type="unfinished"></translation> </message> @@ -639,7 +639,7 @@ <context> <name>WizardPassword</name> <message> - <location filename="wizard/WizardPassword.qml" line="121"/> + <location filename="../wizard/WizardPassword.qml" line="121"/> <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> <translation type="unfinished"></translation> @@ -648,17 +648,17 @@ <context> <name>WizardRecoveryWallet</name> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="69"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="69"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="70"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="70"/> <source>We're ready to recover your account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="71"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="71"/> <source>Please enter your 25 word private key</source> <translation type="unfinished"></translation> </message> @@ -666,12 +666,12 @@ <context> <name>WizardWelcome</name> <message> - <location filename="wizard/WizardWelcome.qml" line="65"/> + <location filename="../wizard/WizardWelcome.qml" line="65"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardWelcome.qml" line="76"/> + <location filename="../wizard/WizardWelcome.qml" line="76"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> @@ -679,75 +679,75 @@ <context> <name>main</name> <message> - <location filename="main.qml" line="140"/> - <location filename="main.qml" line="206"/> - <location filename="main.qml" line="235"/> + <location filename="../main.qml" line="140"/> + <location filename="../main.qml" line="195"/> + <location filename="../main.qml" line="224"/> <source>Error</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="141"/> + <location filename="../main.qml" line="141"/> <source>Couldn't open wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="207"/> + <location filename="../main.qml" line="196"/> <source>Can't create transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="219"/> + <location filename="../main.qml" line="208"/> <source>Confirmation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="220"/> + <location filename="../main.qml" line="209"/> <source>Please confirm transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="221"/> + <location filename="../main.qml" line="210"/> <source> Address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="222"/> + <location filename="../main.qml" line="211"/> <source> Payment ID: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="223"/> + <location filename="../main.qml" line="212"/> <source> Amount: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="224"/> + <location filename="../main.qml" line="213"/> <source> Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="236"/> + <location filename="../main.qml" line="225"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="239"/> + <location filename="../main.qml" line="228"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="240"/> + <location filename="../main.qml" line="229"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="311"/> + <location filename="../main.qml" line="300"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> diff --git a/monero-core_zh.ts b/translations/monero-core_zh.ts similarity index 70% rename from monero-core_zh.ts rename to translations/monero-core_zh.ts index 411a8768..5dc6440a 100644 --- a/monero-core_zh.ts +++ b/translations/monero-core_zh.ts @@ -4,42 +4,42 @@ <context> <name>AddressBook</name> <message> - <location filename="pages/AddressBook.qml" line="47"/> + <location filename="../pages/AddressBook.qml" line="47"/> <source>Add new entry</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="56"/> + <location filename="../pages/AddressBook.qml" line="56"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="58"/> + <location filename="../pages/AddressBook.qml" line="58"/> <source><b>Tip tekst test</b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="77"/> + <location filename="../pages/AddressBook.qml" line="77"/> <source>Payment ID <font size='2'>(Optional)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="79"/> + <location filename="../pages/AddressBook.qml" line="79"/> <source><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 thevtransfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="98"/> + <location filename="../pages/AddressBook.qml" line="98"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="100"/> + <location filename="../pages/AddressBook.qml" line="100"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/AddressBook.qml" line="125"/> + <location filename="../pages/AddressBook.qml" line="125"/> <source>ADD</source> <translation type="unfinished"></translation> </message> @@ -47,12 +47,12 @@ <context> <name>AddressBookTable</name> <message> - <location filename="components/AddressBookTable.qml" line="47"/> + <location filename="../components/AddressBookTable.qml" line="47"/> <source>No more results</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/AddressBookTable.qml" line="106"/> + <location filename="../components/AddressBookTable.qml" line="106"/> <source>Payment ID:</source> <translation type="unfinished"></translation> </message> @@ -60,47 +60,47 @@ <context> <name>BasicPanel</name> <message> - <location filename="BasicPanel.qml" line="78"/> + <location filename="../BasicPanel.qml" line="78"/> <source>Locked Balance:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="92"/> + <location filename="../BasicPanel.qml" line="92"/> <source>78.9239845</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="116"/> + <location filename="../BasicPanel.qml" line="116"/> <source>Availible Balance:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="130"/> + <location filename="../BasicPanel.qml" line="130"/> <source>2324.9239845</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="155"/> + <location filename="../BasicPanel.qml" line="155"/> <source>amount...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="163"/> + <location filename="../BasicPanel.qml" line="163"/> <source>SEND</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="179"/> + <location filename="../BasicPanel.qml" line="179"/> <source>destination...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="191"/> + <location filename="../BasicPanel.qml" line="191"/> <source>Privacy level</source> <translation type="unfinished"></translation> </message> <message> - <location filename="BasicPanel.qml" line="212"/> + <location filename="../BasicPanel.qml" line="212"/> <source>payment ID (optional)...</source> <translation type="unfinished"></translation> </message> @@ -108,17 +108,17 @@ <context> <name>Dashboard</name> <message> - <location filename="pages/Dashboard.qml" line="57"/> + <location filename="../pages/Dashboard.qml" line="57"/> <source>Quick transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Dashboard.qml" line="89"/> + <location filename="../pages/Dashboard.qml" line="89"/> <source>SEND</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Dashboard.qml" line="102"/> + <location filename="../pages/Dashboard.qml" line="102"/> <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> lookng for security level and address book? go to <a href='#'>Transfer</a> tab</source> <translation type="unfinished"></translation> </message> @@ -126,22 +126,22 @@ <context> <name>DashboardTable</name> <message> - <location filename="components/DashboardTable.qml" line="47"/> + <location filename="../components/DashboardTable.qml" line="47"/> <source>No more results</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/DashboardTable.qml" line="137"/> + <location filename="../components/DashboardTable.qml" line="137"/> <source>Date</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/DashboardTable.qml" line="172"/> + <location filename="../components/DashboardTable.qml" line="172"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/DashboardTable.qml" line="193"/> + <location filename="../components/DashboardTable.qml" line="193"/> <source>Amount</source> <translation type="unfinished"></translation> </message> @@ -149,73 +149,73 @@ <context> <name>History</name> <message> - <location filename="pages/History.qml" line="47"/> + <location filename="../pages/History.qml" line="47"/> <source>Filter trasactions history</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="56"/> + <location filename="../pages/History.qml" line="56"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="58"/> - <location filename="pages/History.qml" line="122"/> - <location filename="pages/History.qml" line="142"/> - <location filename="pages/History.qml" line="190"/> - <location filename="pages/History.qml" line="224"/> - <location filename="pages/History.qml" line="245"/> + <location filename="../pages/History.qml" line="58"/> + <location filename="../pages/History.qml" line="122"/> + <location filename="../pages/History.qml" line="142"/> + <location filename="../pages/History.qml" line="190"/> + <location filename="../pages/History.qml" line="224"/> + <location filename="../pages/History.qml" line="245"/> <source><b>Tip tekst test</b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="77"/> + <location filename="../pages/History.qml" line="77"/> <source>Payment ID <font size='2'>(Optional)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="79"/> + <location filename="../pages/History.qml" line="79"/> <source><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 thevtransfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="98"/> + <location filename="../pages/History.qml" line="98"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="100"/> + <location filename="../pages/History.qml" line="100"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="120"/> + <location filename="../pages/History.qml" line="120"/> <source>Date from</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="140"/> - <location filename="pages/History.qml" line="243"/> + <location filename="../pages/History.qml" line="140"/> + <location filename="../pages/History.qml" line="243"/> <source>To</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="160"/> + <location filename="../pages/History.qml" line="160"/> <source>FILTER</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="169"/> + <location filename="../pages/History.qml" line="169"/> <source>Advance filtering</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="188"/> + <location filename="../pages/History.qml" line="188"/> <source>Type of transation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/History.qml" line="222"/> + <location filename="../pages/History.qml" line="222"/> <source>Amount from</source> <translation type="unfinished"></translation> </message> @@ -223,27 +223,27 @@ <context> <name>HistoryTable</name> <message> - <location filename="components/HistoryTable.qml" line="47"/> + <location filename="../components/HistoryTable.qml" line="47"/> <source>No more results</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="129"/> + <location filename="../components/HistoryTable.qml" line="129"/> <source>Payment ID:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="167"/> + <location filename="../components/HistoryTable.qml" line="167"/> <source>Date</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="202"/> + <location filename="../components/HistoryTable.qml" line="202"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/HistoryTable.qml" line="223"/> + <location filename="../components/HistoryTable.qml" line="223"/> <source>Amount</source> <translation type="unfinished"></translation> </message> @@ -251,42 +251,42 @@ <context> <name>LeftPanel</name> <message> - <location filename="LeftPanel.qml" line="103"/> + <location filename="../LeftPanel.qml" line="103"/> <source>Balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="106"/> + <location filename="../LeftPanel.qml" line="106"/> <source>Test tip 1<br/><br/>line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="138"/> + <location filename="../LeftPanel.qml" line="138"/> <source>Unlocked balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="141"/> + <location filename="../LeftPanel.qml" line="141"/> <source>Test tip 2<br/><br/>line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="222"/> + <location filename="../LeftPanel.qml" line="222"/> <source>Transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="223"/> + <location filename="../LeftPanel.qml" line="223"/> <source>T</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="245"/> + <location filename="../LeftPanel.qml" line="245"/> <source>Receive</source> <translation type="unfinished"></translation> </message> <message> - <location filename="LeftPanel.qml" line="246"/> + <location filename="../LeftPanel.qml" line="246"/> <source>R</source> <translation type="unfinished"></translation> </message> @@ -294,17 +294,17 @@ <context> <name>NetworkStatusItem</name> <message> - <location filename="components/NetworkStatusItem.qml" line="58"/> + <location filename="../components/NetworkStatusItem.qml" line="58"/> <source>Network status</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/NetworkStatusItem.qml" line="66"/> + <location filename="../components/NetworkStatusItem.qml" line="66"/> <source>Connected</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/NetworkStatusItem.qml" line="66"/> + <location filename="../components/NetworkStatusItem.qml" line="66"/> <source>Disconnected</source> <translation type="unfinished"></translation> </message> @@ -312,17 +312,17 @@ <context> <name>PrivacyLevelSmall</name> <message> - <location filename="components/PrivacyLevelSmall.qml" line="102"/> + <location filename="../components/PrivacyLevelSmall.qml" line="102"/> <source>LOW</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/PrivacyLevelSmall.qml" line="113"/> + <location filename="../components/PrivacyLevelSmall.qml" line="113"/> <source>MEDIUM</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/PrivacyLevelSmall.qml" line="124"/> + <location filename="../components/PrivacyLevelSmall.qml" line="124"/> <source>HIGH</source> <translation type="unfinished"></translation> </message> @@ -330,22 +330,22 @@ <context> <name>Receive</name> <message> - <location filename="pages/Receive.qml" line="79"/> + <location filename="../pages/Receive.qml" line="79"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Receive.qml" line="106"/> + <location filename="../pages/Receive.qml" line="106"/> <source>Integrated address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Receive.qml" line="136"/> + <location filename="../pages/Receive.qml" line="136"/> <source>Payment ID</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Receive.qml" line="168"/> + <location filename="../pages/Receive.qml" line="168"/> <source>Generate</source> <translation type="unfinished"></translation> </message> @@ -353,7 +353,7 @@ <context> <name>RightPanel</name> <message> - <location filename="RightPanel.qml" line="58"/> + <location filename="../RightPanel.qml" line="58"/> <source>Twitter</source> <translation type="unfinished"></translation> </message> @@ -361,12 +361,12 @@ <context> <name>SearchInput</name> <message> - <location filename="components/SearchInput.qml" line="69"/> + <location filename="../components/SearchInput.qml" line="69"/> <source>Search by...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/SearchInput.qml" line="230"/> + <location filename="../components/SearchInput.qml" line="230"/> <source>SEARCH</source> <translation type="unfinished"></translation> </message> @@ -374,17 +374,17 @@ <context> <name>TickDelegate</name> <message> - <location filename="components/TickDelegate.qml" line="55"/> + <location filename="../components/TickDelegate.qml" line="55"/> <source>LOW</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/TickDelegate.qml" line="56"/> + <location filename="../components/TickDelegate.qml" line="56"/> <source>MEDIUM</source> <translation type="unfinished"></translation> </message> <message> - <location filename="components/TickDelegate.qml" line="57"/> + <location filename="../components/TickDelegate.qml" line="57"/> <source>HIGH</source> <translation type="unfinished"></translation> </message> @@ -392,47 +392,47 @@ <context> <name>Transfer</name> <message> - <location filename="pages/Transfer.qml" line="57"/> + <location filename="../pages/Transfer.qml" line="57"/> <source>Amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="67"/> + <location filename="../pages/Transfer.qml" line="67"/> <source>Transaction priority</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="89"/> + <location filename="../pages/Transfer.qml" line="89"/> <source>Amount...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="127"/> + <location filename="../pages/Transfer.qml" line="127"/> <source>Privacy Level</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="153"/> + <location filename="../pages/Transfer.qml" line="153"/> <source>Cost</source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="167"/> + <location filename="../pages/Transfer.qml" line="167"/> <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> Address <font size='2'> ( Type in or select from </font> <a href='#'>Address</a><font size='2'> book )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="193"/> + <location filename="../pages/Transfer.qml" line="193"/> <source>Payment ID <font size='2'>( Optional )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="217"/> + <location filename="../pages/Transfer.qml" line="217"/> <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="pages/Transfer.qml" line="237"/> + <location filename="../pages/Transfer.qml" line="237"/> <source>SEND</source> <translation type="unfinished"></translation> </message> @@ -440,37 +440,37 @@ <context> <name>WizardConfigure</name> <message> - <location filename="wizard/WizardConfigure.qml" line="79"/> + <location filename="../wizard/WizardConfigure.qml" line="79"/> <source>We’re almost there - let’s just configure some Monero preferences</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="97"/> + <location filename="../wizard/WizardConfigure.qml" line="97"/> <source>Kickstart the Monero blockchain?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="115"/> + <location filename="../wizard/WizardConfigure.qml" line="115"/> <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="126"/> + <location filename="../wizard/WizardConfigure.qml" line="126"/> <source>Enable disk conservation mode?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="144"/> + <location filename="../wizard/WizardConfigure.qml" line="144"/> <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="156"/> + <location filename="../wizard/WizardConfigure.qml" line="156"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardConfigure.qml" line="174"/> + <location filename="../wizard/WizardConfigure.qml" line="174"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -478,12 +478,12 @@ <context> <name>WizardCreateWallet</name> <message> - <location filename="wizard/WizardCreateWallet.qml" line="81"/> + <location filename="../wizard/WizardCreateWallet.qml" line="81"/> <source>A new wallet has been created for you</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardCreateWallet.qml" line="82"/> + <location filename="../wizard/WizardCreateWallet.qml" line="82"/> <source>This is the 25 word mnemonic for your wallet</source> <translation type="unfinished"></translation> </message> @@ -491,32 +491,32 @@ <context> <name>WizardDonation</name> <message> - <location filename="wizard/WizardDonation.qml" line="93"/> + <location filename="../wizard/WizardDonation.qml" line="93"/> <source>Monero development is solely supported by donations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="113"/> + <location filename="../wizard/WizardDonation.qml" line="113"/> <source>Enable auto-donations of?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="153"/> + <location filename="../wizard/WizardDonation.qml" line="153"/> <source>% of my fee added to each transaction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="164"/> + <location filename="../wizard/WizardDonation.qml" line="164"/> <source>For every transaction, a small transaction fee is charged. This option lets you add an additional amount, 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.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="175"/> + <location filename="../wizard/WizardDonation.qml" line="175"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardDonation.qml" line="193"/> + <location filename="../wizard/WizardDonation.qml" line="193"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -524,47 +524,47 @@ <context> <name>WizardFinish</name> <message> - <location filename="wizard/WizardFinish.qml" line="41"/> + <location filename="../wizard/WizardFinish.qml" line="41"/> <source><b>Language:</b> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="42"/> + <location filename="../wizard/WizardFinish.qml" line="42"/> <source><b>Account name:</b> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="43"/> + <location filename="../wizard/WizardFinish.qml" line="43"/> <source><b>Words:</b> </source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="44"/> + <location filename="../wizard/WizardFinish.qml" line="44"/> <source><b>Wallet Path: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="45"/> + <location filename="../wizard/WizardFinish.qml" line="45"/> <source><b>Enable auto donation: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="46"/> + <location filename="../wizard/WizardFinish.qml" line="46"/> <source><b>Auto donation amount: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="47"/> + <location filename="../wizard/WizardFinish.qml" line="47"/> <source><b>Allow background mining: </b></source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="51"/> + <location filename="../wizard/WizardFinish.qml" line="51"/> <source>An overview of your Monero configuration is below:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardFinish.qml" line="102"/> + <location filename="../wizard/WizardFinish.qml" line="102"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -572,17 +572,17 @@ <context> <name>WizardMain</name> <message> - <location filename="wizard/WizardMain.qml" line="85"/> + <location filename="../wizard/WizardMain.qml" line="85"/> <source>Now that your wallet has been created, please set a password for the wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardMain.qml" line="87"/> + <location filename="../wizard/WizardMain.qml" line="87"/> <source>Now that your wallet has been restored, please set a password for the wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardMain.qml" line="308"/> + <location filename="../wizard/WizardMain.qml" line="308"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -590,17 +590,17 @@ <context> <name>WizardManageWalletUI</name> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="103"/> + <location filename="../wizard/WizardManageWalletUI.qml" line="103"/> <source>This is the name of your wallet. You can change it to a different name if you’d like:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="125"/> + <location filename="../wizard/WizardManageWalletUI.qml" line="125"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardManageWalletUI.qml" line="175"/> + <location filename="../wizard/WizardManageWalletUI.qml" line="175"/> <source>Your wallet is stored in</source> <translation type="unfinished"></translation> </message> @@ -608,7 +608,7 @@ <context> <name>WizardMemoTextInput</name> <message> - <location filename="wizard/WizardMemoTextInput.qml" line="76"/> + <location filename="../wizard/WizardMemoTextInput.qml" line="76"/> <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> <translation type="unfinished"></translation> </message> @@ -616,22 +616,22 @@ <context> <name>WizardOptions</name> <message> - <location filename="wizard/WizardOptions.qml" line="62"/> + <location filename="../wizard/WizardOptions.qml" line="62"/> <source>Welcome to Monero!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="74"/> + <location filename="../wizard/WizardOptions.qml" line="74"/> <source>Please select one of the following options:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="110"/> + <location filename="../wizard/WizardOptions.qml" line="110"/> <source>This is my first time, I want to<br/>create a new account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardOptions.qml" line="141"/> + <location filename="../wizard/WizardOptions.qml" line="141"/> <source>I want to recover my account<br/>from my 24 work seed</source> <translation type="unfinished"></translation> </message> @@ -639,7 +639,7 @@ <context> <name>WizardPassword</name> <message> - <location filename="wizard/WizardPassword.qml" line="121"/> + <location filename="../wizard/WizardPassword.qml" line="121"/> <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> <translation type="unfinished"></translation> @@ -648,17 +648,17 @@ <context> <name>WizardRecoveryWallet</name> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="69"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="69"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="70"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="70"/> <source>We're ready to recover your account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardRecoveryWallet.qml" line="71"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="71"/> <source>Please enter your 25 word private key</source> <translation type="unfinished"></translation> </message> @@ -666,12 +666,12 @@ <context> <name>WizardWelcome</name> <message> - <location filename="wizard/WizardWelcome.qml" line="65"/> + <location filename="../wizard/WizardWelcome.qml" line="65"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="wizard/WizardWelcome.qml" line="76"/> + <location filename="../wizard/WizardWelcome.qml" line="76"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> @@ -679,75 +679,75 @@ <context> <name>main</name> <message> - <location filename="main.qml" line="140"/> - <location filename="main.qml" line="206"/> - <location filename="main.qml" line="235"/> + <location filename="../main.qml" line="140"/> + <location filename="../main.qml" line="195"/> + <location filename="../main.qml" line="224"/> <source>Error</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="141"/> + <location filename="../main.qml" line="141"/> <source>Couldn't open wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="207"/> + <location filename="../main.qml" line="196"/> <source>Can't create transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="219"/> + <location filename="../main.qml" line="208"/> <source>Confirmation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="220"/> + <location filename="../main.qml" line="209"/> <source>Please confirm transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="221"/> + <location filename="../main.qml" line="210"/> <source> Address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="222"/> + <location filename="../main.qml" line="211"/> <source> Payment ID: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="223"/> + <location filename="../main.qml" line="212"/> <source> Amount: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="224"/> + <location filename="../main.qml" line="213"/> <source> Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="236"/> + <location filename="../main.qml" line="225"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="239"/> + <location filename="../main.qml" line="228"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="240"/> + <location filename="../main.qml" line="229"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="main.qml" line="311"/> + <location filename="../main.qml" line="300"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> From de7bd2eb971e9a0a796728599478330454bc13a6 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Fri, 15 Jul 2016 11:17:09 +0300 Subject: [PATCH 51/87] Polish translation file --- monero-core.pro | 3 +- translations/monero-core_pl.ts | 755 +++++++++++++++++++++++++++++++++ 2 files changed, 757 insertions(+), 1 deletion(-) create mode 100644 translations/monero-core_pl.ts diff --git a/monero-core.pro b/monero-core.pro index e03c31aa..845e0501 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -104,7 +104,8 @@ TRANSLATIONS = $$PWD/translations/monero-core_en.ts \ # English (could be untran $$PWD/translations/monero-core_de.ts \ # Deutsch $$PWD/translations/monero-core_zh.ts \ # Chineese $$PWD/translations/monero-core_ru.ts \ # Russian - $$PWD/translations/monero-core_it.ts \ # Italy + $$PWD/translations/monero-core_it.ts \ # Italian + $$PWD/translations/monero-core_pl.ts \ # Polish diff --git a/translations/monero-core_pl.ts b/translations/monero-core_pl.ts new file mode 100644 index 00000000..237bf62b --- /dev/null +++ b/translations/monero-core_pl.ts @@ -0,0 +1,755 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="pl_PL"> +<context> + <name>AddressBook</name> + <message> + <location filename="../pages/AddressBook.qml" line="47"/> + <source>Add new entry</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/AddressBook.qml" line="56"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/AddressBook.qml" line="58"/> + <source><b>Tip tekst test</b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/AddressBook.qml" line="77"/> + <source>Payment ID <font size='2'>(Optional)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/AddressBook.qml" line="79"/> + <source><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 thevtransfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/AddressBook.qml" line="98"/> + <source>Description <font size='2'>(Local database)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/AddressBook.qml" line="100"/> + <source><b>Tip tekst test</b><br/><br/>test line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/AddressBook.qml" line="125"/> + <source>ADD</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>AddressBookTable</name> + <message> + <location filename="../components/AddressBookTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../components/AddressBookTable.qml" line="106"/> + <source>Payment ID:</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>BasicPanel</name> + <message> + <location filename="../BasicPanel.qml" line="78"/> + <source>Locked Balance:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../BasicPanel.qml" line="92"/> + <source>78.9239845</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../BasicPanel.qml" line="116"/> + <source>Availible Balance:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../BasicPanel.qml" line="130"/> + <source>2324.9239845</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../BasicPanel.qml" line="155"/> + <source>amount...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../BasicPanel.qml" line="163"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../BasicPanel.qml" line="179"/> + <source>destination...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../BasicPanel.qml" line="191"/> + <source>Privacy level</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../BasicPanel.qml" line="212"/> + <source>payment ID (optional)...</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Dashboard</name> + <message> + <location filename="../pages/Dashboard.qml" line="57"/> + <source>Quick transfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Dashboard.qml" line="89"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Dashboard.qml" line="102"/> + <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> lookng for security level and address book? go to <a href='#'>Transfer</a> tab</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>DashboardTable</name> + <message> + <location filename="../components/DashboardTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../components/DashboardTable.qml" line="137"/> + <source>Date</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../components/DashboardTable.qml" line="172"/> + <source>Balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../components/DashboardTable.qml" line="193"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>History</name> + <message> + <location filename="../pages/History.qml" line="47"/> + <source>Filter trasactions history</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/History.qml" line="56"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/History.qml" line="58"/> + <location filename="../pages/History.qml" line="122"/> + <location filename="../pages/History.qml" line="142"/> + <location filename="../pages/History.qml" line="190"/> + <location filename="../pages/History.qml" line="224"/> + <location filename="../pages/History.qml" line="245"/> + <source><b>Tip tekst test</b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/History.qml" line="77"/> + <source>Payment ID <font size='2'>(Optional)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/History.qml" line="79"/> + <source><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 thevtransfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/History.qml" line="98"/> + <source>Description <font size='2'>(Local database)</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/History.qml" line="100"/> + <source><b>Tip tekst test</b><br/><br/>test line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/History.qml" line="120"/> + <source>Date from</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/History.qml" line="140"/> + <location filename="../pages/History.qml" line="243"/> + <source>To</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/History.qml" line="160"/> + <source>FILTER</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/History.qml" line="169"/> + <source>Advance filtering</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/History.qml" line="188"/> + <source>Type of transation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/History.qml" line="222"/> + <source>Amount from</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>HistoryTable</name> + <message> + <location filename="../components/HistoryTable.qml" line="47"/> + <source>No more results</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../components/HistoryTable.qml" line="129"/> + <source>Payment ID:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../components/HistoryTable.qml" line="167"/> + <source>Date</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../components/HistoryTable.qml" line="202"/> + <source>Balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../components/HistoryTable.qml" line="223"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>LeftPanel</name> + <message> + <location filename="../LeftPanel.qml" line="103"/> + <source>Balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../LeftPanel.qml" line="106"/> + <source>Test tip 1<br/><br/>line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../LeftPanel.qml" line="138"/> + <source>Unlocked balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../LeftPanel.qml" line="141"/> + <source>Test tip 2<br/><br/>line 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../LeftPanel.qml" line="222"/> + <source>Transfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../LeftPanel.qml" line="223"/> + <source>T</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../LeftPanel.qml" line="245"/> + <source>Receive</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../LeftPanel.qml" line="246"/> + <source>R</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>NetworkStatusItem</name> + <message> + <location filename="../components/NetworkStatusItem.qml" line="58"/> + <source>Network status</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../components/NetworkStatusItem.qml" line="66"/> + <source>Connected</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../components/NetworkStatusItem.qml" line="66"/> + <source>Disconnected</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>PrivacyLevelSmall</name> + <message> + <location filename="../components/PrivacyLevelSmall.qml" line="102"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../components/PrivacyLevelSmall.qml" line="113"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../components/PrivacyLevelSmall.qml" line="124"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Receive</name> + <message> + <location filename="../pages/Receive.qml" line="79"/> + <source>Address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Receive.qml" line="106"/> + <source>Integrated address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Receive.qml" line="136"/> + <source>Payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Receive.qml" line="168"/> + <source>Generate</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>RightPanel</name> + <message> + <location filename="../RightPanel.qml" line="58"/> + <source>Twitter</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>SearchInput</name> + <message> + <location filename="../components/SearchInput.qml" line="69"/> + <source>Search by...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../components/SearchInput.qml" line="230"/> + <source>SEARCH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>TickDelegate</name> + <message> + <location filename="../components/TickDelegate.qml" line="55"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../components/TickDelegate.qml" line="56"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../components/TickDelegate.qml" line="57"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Transfer</name> + <message> + <location filename="../pages/Transfer.qml" line="57"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="67"/> + <source>Transaction priority</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="89"/> + <source>Amount...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="127"/> + <source>Privacy Level</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="153"/> + <source>Cost</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="167"/> + <source><style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style> Address <font size='2'> ( Type in or select from </font> <a href='#'>Address</a><font size='2'> book )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="193"/> + <source>Payment ID <font size='2'>( Optional )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="217"/> + <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="237"/> + <source>SEND</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardConfigure</name> + <message> + <location filename="../wizard/WizardConfigure.qml" line="79"/> + <source>We’re almost there - let’s just configure some Monero preferences</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardConfigure.qml" line="97"/> + <source>Kickstart the Monero blockchain?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardConfigure.qml" line="115"/> + <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardConfigure.qml" line="126"/> + <source>Enable disk conservation mode?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardConfigure.qml" line="144"/> + <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardConfigure.qml" line="156"/> + <source>Allow background mining?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardConfigure.qml" line="174"/> + <source>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.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardCreateWallet</name> + <message> + <location filename="../wizard/WizardCreateWallet.qml" line="81"/> + <source>A new wallet has been created for you</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardCreateWallet.qml" line="82"/> + <source>This is the 25 word mnemonic for your wallet</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardDonation</name> + <message> + <location filename="../wizard/WizardDonation.qml" line="93"/> + <source>Monero development is solely supported by donations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardDonation.qml" line="113"/> + <source>Enable auto-donations of?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardDonation.qml" line="153"/> + <source>% of my fee added to each transaction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardDonation.qml" line="164"/> + <source>For every transaction, a small transaction fee is charged. This option lets you add an additional amount, 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.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardDonation.qml" line="175"/> + <source>Allow background mining?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardDonation.qml" line="193"/> + <source>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.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardFinish</name> + <message> + <location filename="../wizard/WizardFinish.qml" line="41"/> + <source><b>Language:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardFinish.qml" line="42"/> + <source><b>Account name:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardFinish.qml" line="43"/> + <source><b>Words:</b> </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardFinish.qml" line="44"/> + <source><b>Wallet Path: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardFinish.qml" line="45"/> + <source><b>Enable auto donation: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardFinish.qml" line="46"/> + <source><b>Auto donation amount: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardFinish.qml" line="47"/> + <source><b>Allow background mining: </b></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardFinish.qml" line="51"/> + <source>An overview of your Monero configuration is below:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardFinish.qml" line="102"/> + <source>You’re all setup!</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardMain</name> + <message> + <location filename="../wizard/WizardMain.qml" line="85"/> + <source>Now that your wallet has been created, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardMain.qml" line="87"/> + <source>Now that your wallet has been restored, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardMain.qml" line="308"/> + <source>USE MONERO</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardManageWalletUI</name> + <message> + <location filename="../wizard/WizardManageWalletUI.qml" line="103"/> + <source>This is the name of your wallet. You can change it to a different name if you’d like:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardManageWalletUI.qml" line="125"/> + <source>My account name</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardManageWalletUI.qml" line="175"/> + <source>Your wallet is stored in</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardMemoTextInput</name> + <message> + <location filename="../wizard/WizardMemoTextInput.qml" line="76"/> + <source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardOptions</name> + <message> + <location filename="../wizard/WizardOptions.qml" line="62"/> + <source>Welcome to Monero!</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardOptions.qml" line="74"/> + <source>Please select one of the following options:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardOptions.qml" line="110"/> + <source>This is my first time, I want to<br/>create a new account</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardOptions.qml" line="141"/> + <source>I want to recover my account<br/>from my 24 work seed</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardPassword</name> + <message> + <location filename="../wizard/WizardPassword.qml" line="121"/> + <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> + Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardRecoveryWallet</name> + <message> + <location filename="../wizard/WizardRecoveryWallet.qml" line="69"/> + <source>My account name</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardRecoveryWallet.qml" line="70"/> + <source>We're ready to recover your account</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardRecoveryWallet.qml" line="71"/> + <source>Please enter your 25 word private key</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WizardWelcome</name> + <message> + <location filename="../wizard/WizardWelcome.qml" line="65"/> + <source>Welcome</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardWelcome.qml" line="76"/> + <source>Please choose a language and regional format.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>main</name> + <message> + <location filename="../main.qml" line="140"/> + <location filename="../main.qml" line="195"/> + <location filename="../main.qml" line="224"/> + <source>Error</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="141"/> + <source>Couldn't open wallet: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="196"/> + <source>Can't create transaction: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="208"/> + <source>Confirmation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="209"/> + <source>Please confirm transaction: + +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="210"/> + <source> +Address: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="211"/> + <source> +Payment ID: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="212"/> + <source> +Amount: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="213"/> + <source> +Fee: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="225"/> + <source>Couldn't send the money: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="228"/> + <source>Information</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="229"/> + <source>Money sent successfully</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="300"/> + <source>Initializing Wallet...</source> + <translation type="unfinished"></translation> + </message> +</context> +</TS> From a9339838ac295a4d045433c1b20fd5666fb35575 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Tue, 19 Jul 2016 23:31:09 +0300 Subject: [PATCH 52/87] TranslationManager, Russian translation example --- TranslationManager.cpp | 63 ++++++++++++++++++++++++++++++++++ TranslationManager.h | 29 ++++++++++++++++ get_libwallet_api.sh | 2 +- lang/languages.xml | 33 ++++++++++++------ main.cpp | 11 ++++++ monero-core.pro | 18 +++++----- translations/monero-core_de.ts | 5 +-- translations/monero-core_en.ts | 5 +-- translations/monero-core_it.ts | 5 +-- translations/monero-core_pl.ts | 5 +-- translations/monero-core_ru.ts | 11 +++--- translations/monero-core_zh.ts | 5 +-- wizard/WizardWelcome.qml | 39 ++++++++++++++++++--- 13 files changed, 192 insertions(+), 39 deletions(-) create mode 100644 TranslationManager.cpp create mode 100644 TranslationManager.h diff --git a/TranslationManager.cpp b/TranslationManager.cpp new file mode 100644 index 00000000..69448ce2 --- /dev/null +++ b/TranslationManager.cpp @@ -0,0 +1,63 @@ +#include "TranslationManager.h" + +#include <QApplication> +#include <QTranslator> +#include <QDir> +#include <QDebug> +#include <QFileInfo> + + +TranslationManager * TranslationManager::m_instance = nullptr; + + +TranslationManager::TranslationManager(QObject *parent) : QObject(parent) +{ + m_translator = new QTranslator(this); +} + +bool TranslationManager::setLanguage(const QString &language) +{ + qDebug() << __FUNCTION__ << " " << language; + // if language is "en", remove translator + if (language.toLower() == "en") { + qApp->removeTranslator(m_translator); + emit languageChanged(); + return true; + } + + // we expecting to have translation files in "i18n" directory + QString dir = qApp->applicationDirPath() + QDir::separator() + "i18n"; + + QString filename = "monero-core_" + language; + + qDebug("%s: loading translation file '%s' from '%s", + __FUNCTION__, qPrintable(filename), qPrintable(dir)); + + + if (m_translator->load(filename, dir)) { + qDebug("%s: translation for language '%s' loaded successfully", + __FUNCTION__, qPrintable(language)); + // TODO: apply locale? + qApp->installTranslator(m_translator); + emit languageChanged(); + return true; + } else { + qCritical("%s: error loading translation for language '%s'", + __FUNCTION__, qPrintable(language)); + return false; + } +} + +TranslationManager *TranslationManager::instance() +{ + if (!m_instance) { + m_instance = new TranslationManager(); + } + return m_instance; +} + +QString TranslationManager::emptyString() +{ + return ""; +} + diff --git a/TranslationManager.h b/TranslationManager.h new file mode 100644 index 00000000..94d0e50e --- /dev/null +++ b/TranslationManager.h @@ -0,0 +1,29 @@ +#ifndef TRANSLATIONMANAGER_H +#define TRANSLATIONMANAGER_H + +#include <QObject> + +class QTranslator; +class TranslationManager : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString emptyString READ emptyString NOTIFY languageChanged) +public: + Q_INVOKABLE bool setLanguage(const QString &language); + static TranslationManager *instance(); + + QString emptyString(); + +signals: + void languageChanged(); + +private: + explicit TranslationManager(QObject *parent = 0); + +private: + static TranslationManager * m_instance; + QTranslator * m_translator; + +}; + +#endif // TRANSLATIONMANAGER_H diff --git a/get_libwallet_api.sh b/get_libwallet_api.sh index 9e69235e..53ae9268 100755 --- a/get_libwallet_api.sh +++ b/get_libwallet_api.sh @@ -2,7 +2,7 @@ BITMONERO_URL=https://github.com/mbg033/bitmonero.git -BITMONERO_BRANCH=devel +BITMONERO_BRANCH=master # thanks to SO: http://stackoverflow.com/a/20283965/4118915 CPU_CORE_COUNT=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu) pushd $(pwd) diff --git a/lang/languages.xml b/lang/languages.xml index 8f5120a7..cc47eaa1 100644 --- a/lang/languages.xml +++ b/lang/languages.xml @@ -1,14 +1,25 @@ <?xml version="1.0" encoding="utf-8"?> <languages> - <language display_name="US English" locale="en_US" wallet_name="English" flag="/lang/flags/usa.png" qs="none"/> - <language display_name="UK English" locale="en_GB" wallet_name="English" flag="/lang/flags/uk.png" qs="none"/> - <language display_name="Russia" locale="ru_RU" wallet_name="English" flag="/lang/flags/russia.png" qs="none"/> - <language display_name="RPA" locale="TODO" wallet_name="English" flag="/lang/flags/rpa.png" qs="none"/> - <language display_name="Palestine" locale="TODO" wallet_name="English" flag="/lang/flags/palestine.png" qs="none"/> - <language display_name="India" locale="hi_IN" wallet_name="English" flag="/lang/flags/india.png" qs="none"/> - <language display_name="Italy" locale="it_IT" wallet_name="English" flag="/lang/flags/italy.png" qs="none"/> - <language display_name="German" locale="de_DE" wallet_name="English" flag="/lang/flags/german.png" qs="none"/> - <language display_name="China" locale="zh_CN" wallet_name="English" flag="/lang/flags/china.png" qs="none"/> - <language display_name="Brazil" locale="pt_BR" wallet_name="English" flag="/lang/flags/brazil.png" qs="none"/> - <language display_name="Bangladesh" locale="TODO" wallet_name="English" flag="/lang/flags/bangladesh.png" qs="none"/> + +<!-- +List of available languages for your wallet's seed: +0 : English +1 : Spanish +2 : German +3 : Italian +4 : Portuguese +5 : Russian +6 : Japanese +--> + <language display_name="US English" locale="en_US" wallet_language="English" flag="/lang/flags/usa.png" qs="none"/> + <language display_name="UK English" locale="en_GB" wallet_language="English" flag="/lang/flags/uk.png" qs="none"/> + <language display_name="Russia" locale="ru_RU" wallet_language="Russian" flag="/lang/flags/russia.png" qs="none"/> + <language display_name="RPA" locale="en_SA" wallet_language="English" flag="/lang/flags/rpa.png" qs="none"/> + <language display_name="Palestine" locale="ar_PS" wallet_language="English" flag="/lang/flags/palestine.png" qs="none"/> + <language display_name="India" locale="hi_IN" wallet_language="English" flag="/lang/flags/india.png" qs="none"/> + <language display_name="Italy" locale="it_IT" wallet_language="Italian" flag="/lang/flags/italy.png" qs="none"/> + <language display_name="German" locale="de_DE" wallet_language="German" flag="/lang/flags/german.png" qs="none"/> + <language display_name="China" locale="zh_CN" wallet_language="English" flag="/lang/flags/china.png" qs="none"/> + <language display_name="Brazil" locale="pt_BR" wallet_language="Portuguese" flag="/lang/flags/brazil.png" qs="none"/> + <language display_name="Bangladesh" locale="en_US" wallet_language="English" flag="/lang/flags/bangladesh.png" qs="none"/> </languages> diff --git a/main.cpp b/main.cpp index 43ef8186..030a21c3 100644 --- a/main.cpp +++ b/main.cpp @@ -37,6 +37,7 @@ #include "WalletManager.h" #include "Wallet.h" #include "PendingTransaction.h" +#include "TranslationManager.h" @@ -53,10 +54,18 @@ int main(int argc, char *argv[]) app.installEventFilter(eventFilter); qmlRegisterType<clipboardAdapter>("moneroComponents", 1, 0, "Clipboard"); + qmlRegisterUncreatableType<Wallet>("Bitmonero.Wallet", 1, 0, "Wallet", "Wallet can't be instantiated directly"); + qmlRegisterUncreatableType<PendingTransaction>("Bitmonero.PendingTransaction", 1, 0, "PendingTransaction", "PendingTransaction can't be instantiated directly"); + qmlRegisterUncreatableType<WalletManager>("Bitmonero.WalletManager", 1, 0, "WalletManager", + "WalletManager can't be instantiated directly"); + + qmlRegisterUncreatableType<TranslationManager>("moneroComponents", 1, 0, "TranslationManager", + "TranslationManager can't be instantiated directly"); + qRegisterMetaType<PendingTransaction::Priority>(); @@ -69,6 +78,8 @@ int main(int argc, char *argv[]) engine.rootContext()->setContextProperty("walletManager", WalletManager::instance()); + engine.rootContext()->setContextProperty("translationManager", TranslationManager::instance()); + // export to QML monero accounts root directory // wizard is talking about where // to save the wallet file (.keys, .bin), they have to be user-accessible for diff --git a/monero-core.pro b/monero-core.pro index 845e0501..a5b170e5 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -19,7 +19,8 @@ HEADERS += \ src/libwalletqt/PendingTransaction.h \ src/libwalletqt/TransactionHistory.h \ src/libwalletqt/TransactionInfo.h \ - oshelper.h + oshelper.h \ + TranslationManager.h SOURCES += main.cpp \ @@ -31,7 +32,8 @@ SOURCES += main.cpp \ src/libwalletqt/PendingTransaction.cpp \ src/libwalletqt/TransactionHistory.cpp \ src/libwalletqt/TransactionInfo.cpp \ - oshelper.cpp + oshelper.cpp \ + TranslationManager.cpp lupdate_only { SOURCES = *.qml \ @@ -101,11 +103,11 @@ macx { # translations files; TRANSLATIONS = $$PWD/translations/monero-core_en.ts \ # English (could be untranslated) - $$PWD/translations/monero-core_de.ts \ # Deutsch - $$PWD/translations/monero-core_zh.ts \ # Chineese - $$PWD/translations/monero-core_ru.ts \ # Russian - $$PWD/translations/monero-core_it.ts \ # Italian - $$PWD/translations/monero-core_pl.ts \ # Polish + $$PWD/translations/monero-core_de.ts \ # Deutsch + $$PWD/translations/monero-core_zh.ts \ # Chineese + $$PWD/translations/monero-core_ru.ts \ # Russian + $$PWD/translations/monero-core_it.ts \ # Italian + $$PWD/translations/monero-core_pl.ts \ # Polish @@ -117,7 +119,7 @@ trans_update.depends = $$_PRO_FILE_ trans_release.commands = lrelease $$_PRO_FILE_ trans_release.depends = trans_update $$TRANSLATIONS -translate.commands = $(COPY) $$PWD/*.qm ${DESTDIR} +translate.commands = $(MKDIR) ${DESTDIR}/i18n && $(COPY) $$PWD/translations/*.qm ${DESTDIR}/i18n translate.depends = trans_release QMAKE_EXTRA_TARGETS += trans_update trans_release translate diff --git a/translations/monero-core_de.ts b/translations/monero-core_de.ts index 09e96e70..53c8bef3 100644 --- a/translations/monero-core_de.ts +++ b/translations/monero-core_de.ts @@ -666,12 +666,13 @@ <context> <name>WizardWelcome</name> <message> - <location filename="../wizard/WizardWelcome.qml" line="65"/> + <location filename="../wizard/WizardWelcome.qml" line="49"/> + <location filename="../wizard/WizardWelcome.qml" line="73"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardWelcome.qml" line="76"/> + <location filename="../wizard/WizardWelcome.qml" line="86"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> diff --git a/translations/monero-core_en.ts b/translations/monero-core_en.ts index 307233ba..957bfdd0 100644 --- a/translations/monero-core_en.ts +++ b/translations/monero-core_en.ts @@ -666,12 +666,13 @@ <context> <name>WizardWelcome</name> <message> - <location filename="../wizard/WizardWelcome.qml" line="65"/> + <location filename="../wizard/WizardWelcome.qml" line="49"/> + <location filename="../wizard/WizardWelcome.qml" line="73"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardWelcome.qml" line="76"/> + <location filename="../wizard/WizardWelcome.qml" line="86"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> diff --git a/translations/monero-core_it.ts b/translations/monero-core_it.ts index e59d65eb..a24a0501 100644 --- a/translations/monero-core_it.ts +++ b/translations/monero-core_it.ts @@ -666,12 +666,13 @@ <context> <name>WizardWelcome</name> <message> - <location filename="../wizard/WizardWelcome.qml" line="65"/> + <location filename="../wizard/WizardWelcome.qml" line="49"/> + <location filename="../wizard/WizardWelcome.qml" line="73"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardWelcome.qml" line="76"/> + <location filename="../wizard/WizardWelcome.qml" line="86"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> diff --git a/translations/monero-core_pl.ts b/translations/monero-core_pl.ts index 237bf62b..67e8a0aa 100644 --- a/translations/monero-core_pl.ts +++ b/translations/monero-core_pl.ts @@ -666,12 +666,13 @@ <context> <name>WizardWelcome</name> <message> - <location filename="../wizard/WizardWelcome.qml" line="65"/> + <location filename="../wizard/WizardWelcome.qml" line="49"/> + <location filename="../wizard/WizardWelcome.qml" line="73"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardWelcome.qml" line="76"/> + <location filename="../wizard/WizardWelcome.qml" line="86"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> diff --git a/translations/monero-core_ru.ts b/translations/monero-core_ru.ts index a5c61585..ab0d509c 100644 --- a/translations/monero-core_ru.ts +++ b/translations/monero-core_ru.ts @@ -6,7 +6,7 @@ <message> <location filename="../pages/AddressBook.qml" line="47"/> <source>Add new entry</source> - <translation type="unfinished"></translation> + <translation>Новая запись</translation> </message> <message> <location filename="../pages/AddressBook.qml" line="56"/> @@ -666,14 +666,15 @@ <context> <name>WizardWelcome</name> <message> - <location filename="../wizard/WizardWelcome.qml" line="65"/> + <location filename="../wizard/WizardWelcome.qml" line="49"/> + <location filename="../wizard/WizardWelcome.qml" line="73"/> <source>Welcome</source> - <translation type="unfinished"></translation> + <translation>Добро пожаловать</translation> </message> <message> - <location filename="../wizard/WizardWelcome.qml" line="76"/> + <location filename="../wizard/WizardWelcome.qml" line="86"/> <source>Please choose a language and regional format.</source> - <translation type="unfinished"></translation> + <translation>Пожалуйста выберите язык и региональный формат.</translation> </message> </context> <context> diff --git a/translations/monero-core_zh.ts b/translations/monero-core_zh.ts index 5dc6440a..d47f1c24 100644 --- a/translations/monero-core_zh.ts +++ b/translations/monero-core_zh.ts @@ -666,12 +666,13 @@ <context> <name>WizardWelcome</name> <message> - <location filename="../wizard/WizardWelcome.qml" line="65"/> + <location filename="../wizard/WizardWelcome.qml" line="49"/> + <location filename="../wizard/WizardWelcome.qml" line="73"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardWelcome.qml" line="76"/> + <location filename="../wizard/WizardWelcome.qml" line="86"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> diff --git a/wizard/WizardWelcome.qml b/wizard/WizardWelcome.qml index 31bdbcb7..72bf27cc 100644 --- a/wizard/WizardWelcome.qml +++ b/wizard/WizardWelcome.qml @@ -39,11 +39,25 @@ Item { function onPageClosed(settingsObject) { var lang = languagesModel.get(gridView.currentIndex); settingsObject['language'] = lang.display_name; - settingsObject['wallet_language'] = lang.wallet_name; + settingsObject['wallet_language'] = lang.wallet_language; settingsObject['locale'] = lang.locale; return true } + +// function retranslateUi() { +// welcomeText.text = qsTr("Welcome") +// } + + +// Connections { +// target: translationManager +// onEmptyStringChanged: { +// console.log("languageChanged") +// retranslateUi() +// } +// } + Column { id: headerColumn anchors.left: parent.left @@ -55,6 +69,7 @@ Item { spacing: 24 Text { + id: welcomeText anchors.left: parent.left anchors.right: parent.right font.family: "Arial" @@ -62,10 +77,14 @@ Item { //renderType: Text.NativeRendering color: "#3F3F3F" wrapMode: Text.Wrap - text: qsTr("Welcome") + // hack to implement dynamic translation + // https://wiki.qt.io/How_to_do_dynamic_translation_in_QML + text: qsTr("Welcome") + + translationManager.emptyString } Text { + id: selectLanguageText anchors.left: parent.left anchors.right: parent.right font.family: "Arial" @@ -74,6 +93,7 @@ Item { color: "#4A4646" wrapMode: Text.Wrap text: qsTr("Please choose a language and regional format.") + + translationManager.emptyString } } @@ -84,11 +104,13 @@ Item { XmlRole { name: "display_name"; query: "@display_name/string()" } XmlRole { name: "locale"; query: "@locale/string()" } - XmlRole { name: "wallet_name"; query: "@wallet_name/string()" } + XmlRole { name: "wallet_language"; query: "@wallet_language/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()" } + + } GridView { @@ -111,6 +133,8 @@ Item { height: gridView.cellHeight + + Rectangle { id: flagRect width: 60; height: 60 @@ -139,8 +163,15 @@ Item { anchors.fill: parent onClicked: { gridView.currentIndex = index + var data = languagesModel.get(gridView.currentIndex); + if (data !== null || data !== undefined) { + var locale = data.locale + translationManager.setLanguage(locale.split("_")[0]); + } } } - } + } // delegate + + } } From 39b88daf326cdbbbac5f757769168d41e6d3517b Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Tue, 19 Jul 2016 23:45:12 +0300 Subject: [PATCH 53/87] Apply translation for "normal" mode --- LeftPanel.qml | 2 +- main.qml | 9 +++++++ translations/monero-core_de.ts | 37 ++++++++++++++--------------- translations/monero-core_en.ts | 37 ++++++++++++++--------------- translations/monero-core_it.ts | 37 ++++++++++++++--------------- translations/monero-core_pl.ts | 37 ++++++++++++++--------------- translations/monero-core_ru.ts | 43 +++++++++++++++++----------------- translations/monero-core_zh.ts | 37 ++++++++++++++--------------- wizard/WizardMain.qml | 1 + wizard/WizardWelcome.qml | 16 ------------- 10 files changed, 122 insertions(+), 134 deletions(-) diff --git a/LeftPanel.qml b/LeftPanel.qml index e23d353c..6e067d03 100644 --- a/LeftPanel.qml +++ b/LeftPanel.qml @@ -100,7 +100,7 @@ Rectangle { spacing: 6 Label { - text: qsTr("Balance") + text: qsTr("Balance") + translationManager.emptyString anchors.left: parent.left anchors.leftMargin: 50 tipText: qsTr("Test tip 1<br/><br/>line 2") diff --git a/main.qml b/main.qml index b55ace8c..7316fc56 100644 --- a/main.qml +++ b/main.qml @@ -125,8 +125,16 @@ ApplicationWindow { function initialize() { console.log("initializing..") + + // setup language + var locale = persistentSettings.locale + if (locale !== "") { + translationManager.setLanguage(locale.split("_")[0]); + } + middlePanel.paymentClicked.connect(handlePayment); + if (typeof wizard.settings['wallet'] !== 'undefined') { wallet = wizard.settings['wallet']; } else { @@ -262,6 +270,7 @@ ApplicationWindow { Settings { id: persistentSettings property string language + property string locale property string account_name property string wallet_path property bool auto_donations_enabled : true diff --git a/translations/monero-core_de.ts b/translations/monero-core_de.ts index 53c8bef3..f2c59688 100644 --- a/translations/monero-core_de.ts +++ b/translations/monero-core_de.ts @@ -582,7 +582,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardMain.qml" line="308"/> + <location filename="../wizard/WizardMain.qml" line="309"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -666,13 +666,12 @@ <context> <name>WizardWelcome</name> <message> - <location filename="../wizard/WizardWelcome.qml" line="49"/> - <location filename="../wizard/WizardWelcome.qml" line="73"/> + <location filename="../wizard/WizardWelcome.qml" line="69"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardWelcome.qml" line="86"/> + <location filename="../wizard/WizardWelcome.qml" line="82"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> @@ -680,75 +679,75 @@ <context> <name>main</name> <message> - <location filename="../main.qml" line="140"/> - <location filename="../main.qml" line="195"/> - <location filename="../main.qml" line="224"/> + <location filename="../main.qml" line="148"/> + <location filename="../main.qml" line="203"/> + <location filename="../main.qml" line="232"/> <source>Error</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="141"/> + <location filename="../main.qml" line="149"/> <source>Couldn't open wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="196"/> + <location filename="../main.qml" line="204"/> <source>Can't create transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="208"/> + <location filename="../main.qml" line="216"/> <source>Confirmation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="209"/> + <location filename="../main.qml" line="217"/> <source>Please confirm transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="210"/> + <location filename="../main.qml" line="218"/> <source> Address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="211"/> + <location filename="../main.qml" line="219"/> <source> Payment ID: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="212"/> + <location filename="../main.qml" line="220"/> <source> Amount: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="213"/> + <location filename="../main.qml" line="221"/> <source> Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="225"/> + <location filename="../main.qml" line="233"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="228"/> + <location filename="../main.qml" line="236"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="229"/> + <location filename="../main.qml" line="237"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="300"/> + <location filename="../main.qml" line="309"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> diff --git a/translations/monero-core_en.ts b/translations/monero-core_en.ts index 957bfdd0..f8f7b3ea 100644 --- a/translations/monero-core_en.ts +++ b/translations/monero-core_en.ts @@ -582,7 +582,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardMain.qml" line="308"/> + <location filename="../wizard/WizardMain.qml" line="309"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -666,13 +666,12 @@ <context> <name>WizardWelcome</name> <message> - <location filename="../wizard/WizardWelcome.qml" line="49"/> - <location filename="../wizard/WizardWelcome.qml" line="73"/> + <location filename="../wizard/WizardWelcome.qml" line="69"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardWelcome.qml" line="86"/> + <location filename="../wizard/WizardWelcome.qml" line="82"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> @@ -680,75 +679,75 @@ <context> <name>main</name> <message> - <location filename="../main.qml" line="140"/> - <location filename="../main.qml" line="195"/> - <location filename="../main.qml" line="224"/> + <location filename="../main.qml" line="148"/> + <location filename="../main.qml" line="203"/> + <location filename="../main.qml" line="232"/> <source>Error</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="141"/> + <location filename="../main.qml" line="149"/> <source>Couldn't open wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="196"/> + <location filename="../main.qml" line="204"/> <source>Can't create transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="208"/> + <location filename="../main.qml" line="216"/> <source>Confirmation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="209"/> + <location filename="../main.qml" line="217"/> <source>Please confirm transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="210"/> + <location filename="../main.qml" line="218"/> <source> Address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="211"/> + <location filename="../main.qml" line="219"/> <source> Payment ID: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="212"/> + <location filename="../main.qml" line="220"/> <source> Amount: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="213"/> + <location filename="../main.qml" line="221"/> <source> Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="225"/> + <location filename="../main.qml" line="233"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="228"/> + <location filename="../main.qml" line="236"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="229"/> + <location filename="../main.qml" line="237"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="300"/> + <location filename="../main.qml" line="309"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> diff --git a/translations/monero-core_it.ts b/translations/monero-core_it.ts index a24a0501..3b4e2760 100644 --- a/translations/monero-core_it.ts +++ b/translations/monero-core_it.ts @@ -582,7 +582,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardMain.qml" line="308"/> + <location filename="../wizard/WizardMain.qml" line="309"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -666,13 +666,12 @@ <context> <name>WizardWelcome</name> <message> - <location filename="../wizard/WizardWelcome.qml" line="49"/> - <location filename="../wizard/WizardWelcome.qml" line="73"/> + <location filename="../wizard/WizardWelcome.qml" line="69"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardWelcome.qml" line="86"/> + <location filename="../wizard/WizardWelcome.qml" line="82"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> @@ -680,75 +679,75 @@ <context> <name>main</name> <message> - <location filename="../main.qml" line="140"/> - <location filename="../main.qml" line="195"/> - <location filename="../main.qml" line="224"/> + <location filename="../main.qml" line="148"/> + <location filename="../main.qml" line="203"/> + <location filename="../main.qml" line="232"/> <source>Error</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="141"/> + <location filename="../main.qml" line="149"/> <source>Couldn't open wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="196"/> + <location filename="../main.qml" line="204"/> <source>Can't create transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="208"/> + <location filename="../main.qml" line="216"/> <source>Confirmation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="209"/> + <location filename="../main.qml" line="217"/> <source>Please confirm transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="210"/> + <location filename="../main.qml" line="218"/> <source> Address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="211"/> + <location filename="../main.qml" line="219"/> <source> Payment ID: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="212"/> + <location filename="../main.qml" line="220"/> <source> Amount: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="213"/> + <location filename="../main.qml" line="221"/> <source> Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="225"/> + <location filename="../main.qml" line="233"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="228"/> + <location filename="../main.qml" line="236"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="229"/> + <location filename="../main.qml" line="237"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="300"/> + <location filename="../main.qml" line="309"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> diff --git a/translations/monero-core_pl.ts b/translations/monero-core_pl.ts index 67e8a0aa..6c15a0b0 100644 --- a/translations/monero-core_pl.ts +++ b/translations/monero-core_pl.ts @@ -582,7 +582,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardMain.qml" line="308"/> + <location filename="../wizard/WizardMain.qml" line="309"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -666,13 +666,12 @@ <context> <name>WizardWelcome</name> <message> - <location filename="../wizard/WizardWelcome.qml" line="49"/> - <location filename="../wizard/WizardWelcome.qml" line="73"/> + <location filename="../wizard/WizardWelcome.qml" line="69"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardWelcome.qml" line="86"/> + <location filename="../wizard/WizardWelcome.qml" line="82"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> @@ -680,75 +679,75 @@ <context> <name>main</name> <message> - <location filename="../main.qml" line="140"/> - <location filename="../main.qml" line="195"/> - <location filename="../main.qml" line="224"/> + <location filename="../main.qml" line="148"/> + <location filename="../main.qml" line="203"/> + <location filename="../main.qml" line="232"/> <source>Error</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="141"/> + <location filename="../main.qml" line="149"/> <source>Couldn't open wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="196"/> + <location filename="../main.qml" line="204"/> <source>Can't create transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="208"/> + <location filename="../main.qml" line="216"/> <source>Confirmation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="209"/> + <location filename="../main.qml" line="217"/> <source>Please confirm transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="210"/> + <location filename="../main.qml" line="218"/> <source> Address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="211"/> + <location filename="../main.qml" line="219"/> <source> Payment ID: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="212"/> + <location filename="../main.qml" line="220"/> <source> Amount: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="213"/> + <location filename="../main.qml" line="221"/> <source> Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="225"/> + <location filename="../main.qml" line="233"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="228"/> + <location filename="../main.qml" line="236"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="229"/> + <location filename="../main.qml" line="237"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="300"/> + <location filename="../main.qml" line="309"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> diff --git a/translations/monero-core_ru.ts b/translations/monero-core_ru.ts index ab0d509c..7921567d 100644 --- a/translations/monero-core_ru.ts +++ b/translations/monero-core_ru.ts @@ -138,7 +138,7 @@ <message> <location filename="../components/DashboardTable.qml" line="172"/> <source>Balance</source> - <translation type="unfinished"></translation> + <translation type="unfinished">Баланс</translation> </message> <message> <location filename="../components/DashboardTable.qml" line="193"/> @@ -240,7 +240,7 @@ <message> <location filename="../components/HistoryTable.qml" line="202"/> <source>Balance</source> - <translation type="unfinished"></translation> + <translation type="unfinished">Баланс</translation> </message> <message> <location filename="../components/HistoryTable.qml" line="223"/> @@ -253,7 +253,7 @@ <message> <location filename="../LeftPanel.qml" line="103"/> <source>Balance</source> - <translation type="unfinished"></translation> + <translation>Баланс</translation> </message> <message> <location filename="../LeftPanel.qml" line="106"/> @@ -582,7 +582,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardMain.qml" line="308"/> + <location filename="../wizard/WizardMain.qml" line="309"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -666,13 +666,12 @@ <context> <name>WizardWelcome</name> <message> - <location filename="../wizard/WizardWelcome.qml" line="49"/> - <location filename="../wizard/WizardWelcome.qml" line="73"/> + <location filename="../wizard/WizardWelcome.qml" line="69"/> <source>Welcome</source> <translation>Добро пожаловать</translation> </message> <message> - <location filename="../wizard/WizardWelcome.qml" line="86"/> + <location filename="../wizard/WizardWelcome.qml" line="82"/> <source>Please choose a language and regional format.</source> <translation>Пожалуйста выберите язык и региональный формат.</translation> </message> @@ -680,75 +679,75 @@ <context> <name>main</name> <message> - <location filename="../main.qml" line="140"/> - <location filename="../main.qml" line="195"/> - <location filename="../main.qml" line="224"/> + <location filename="../main.qml" line="148"/> + <location filename="../main.qml" line="203"/> + <location filename="../main.qml" line="232"/> <source>Error</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="141"/> + <location filename="../main.qml" line="149"/> <source>Couldn't open wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="196"/> + <location filename="../main.qml" line="204"/> <source>Can't create transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="208"/> + <location filename="../main.qml" line="216"/> <source>Confirmation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="209"/> + <location filename="../main.qml" line="217"/> <source>Please confirm transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="210"/> + <location filename="../main.qml" line="218"/> <source> Address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="211"/> + <location filename="../main.qml" line="219"/> <source> Payment ID: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="212"/> + <location filename="../main.qml" line="220"/> <source> Amount: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="213"/> + <location filename="../main.qml" line="221"/> <source> Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="225"/> + <location filename="../main.qml" line="233"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="228"/> + <location filename="../main.qml" line="236"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="229"/> + <location filename="../main.qml" line="237"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="300"/> + <location filename="../main.qml" line="309"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> diff --git a/translations/monero-core_zh.ts b/translations/monero-core_zh.ts index d47f1c24..0a2faf01 100644 --- a/translations/monero-core_zh.ts +++ b/translations/monero-core_zh.ts @@ -582,7 +582,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardMain.qml" line="308"/> + <location filename="../wizard/WizardMain.qml" line="309"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -666,13 +666,12 @@ <context> <name>WizardWelcome</name> <message> - <location filename="../wizard/WizardWelcome.qml" line="49"/> - <location filename="../wizard/WizardWelcome.qml" line="73"/> + <location filename="../wizard/WizardWelcome.qml" line="69"/> <source>Welcome</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardWelcome.qml" line="86"/> + <location filename="../wizard/WizardWelcome.qml" line="82"/> <source>Please choose a language and regional format.</source> <translation type="unfinished"></translation> </message> @@ -680,75 +679,75 @@ <context> <name>main</name> <message> - <location filename="../main.qml" line="140"/> - <location filename="../main.qml" line="195"/> - <location filename="../main.qml" line="224"/> + <location filename="../main.qml" line="148"/> + <location filename="../main.qml" line="203"/> + <location filename="../main.qml" line="232"/> <source>Error</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="141"/> + <location filename="../main.qml" line="149"/> <source>Couldn't open wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="196"/> + <location filename="../main.qml" line="204"/> <source>Can't create transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="208"/> + <location filename="../main.qml" line="216"/> <source>Confirmation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="209"/> + <location filename="../main.qml" line="217"/> <source>Please confirm transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="210"/> + <location filename="../main.qml" line="218"/> <source> Address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="211"/> + <location filename="../main.qml" line="219"/> <source> Payment ID: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="212"/> + <location filename="../main.qml" line="220"/> <source> Amount: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="213"/> + <location filename="../main.qml" line="221"/> <source> Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="225"/> + <location filename="../main.qml" line="233"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="228"/> + <location filename="../main.qml" line="236"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="229"/> + <location filename="../main.qml" line="237"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="300"/> + <location filename="../main.qml" line="309"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index 3c4103ce..987ac897 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -147,6 +147,7 @@ Rectangle { // persist settings appWindow.persistentSettings.language = settings.language + appWindow.persistentSettings.locale = settings.locale appWindow.persistentSettings.account_name = settings.account_name appWindow.persistentSettings.wallet_path = settings.wallet_path appWindow.persistentSettings.allow_background_mining = settings.allow_background_mining diff --git a/wizard/WizardWelcome.qml b/wizard/WizardWelcome.qml index 72bf27cc..bc4c5a1b 100644 --- a/wizard/WizardWelcome.qml +++ b/wizard/WizardWelcome.qml @@ -45,19 +45,6 @@ Item { } -// function retranslateUi() { -// welcomeText.text = qsTr("Welcome") -// } - - -// Connections { -// target: translationManager -// onEmptyStringChanged: { -// console.log("languageChanged") -// retranslateUi() -// } -// } - Column { id: headerColumn anchors.left: parent.left @@ -132,9 +119,6 @@ Item { width: gridView.cellWidth height: gridView.cellHeight - - - Rectangle { id: flagRect width: 60; height: 60 From 32ebf180acce258f8efb9bcaeca945a1fdd311ce Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 20 Jul 2016 22:28:11 +0300 Subject: [PATCH 54/87] dynamic translation support. closes #24 --- BasicPanel.qml | 8 +- LeftPanel.qml | 34 +++---- RightPanel.qml | 6 +- components/AddressBookTable.qml | 4 +- components/DashboardTable.qml | 8 +- components/HistoryTable.qml | 10 +-- components/NetworkStatusItem.qml | 2 +- components/PrivacyLevelSmall.qml | 6 +- components/SearchInput.qml | 2 +- components/TickDelegate.qml | 6 +- components/TitleBar.qml | 2 +- main.qml | 19 ++-- pages/AddressBook.qml | 17 ++-- pages/Dashboard.qml | 3 +- pages/History.qml | 27 +++--- pages/Receive.qml | 12 +-- pages/Transfer.qml | 20 +++-- translations/monero-core_de.ts | 150 ++++++++++++++++++++++++------- translations/monero-core_en.ts | 150 ++++++++++++++++++++++++------- translations/monero-core_it.ts | 150 ++++++++++++++++++++++++------- translations/monero-core_pl.ts | 150 ++++++++++++++++++++++++------- translations/monero-core_ru.ts | 150 ++++++++++++++++++++++++------- translations/monero-core_zh.ts | 150 ++++++++++++++++++++++++------- wizard/WizardConfigure.qml | 11 ++- wizard/WizardCreateWallet.qml | 4 +- wizard/WizardDonation.qml | 10 ++- wizard/WizardFinish.qml | 5 +- wizard/WizardMain.qml | 6 +- wizard/WizardManageWalletUI.qml | 8 +- wizard/WizardMemoTextInput.qml | 1 + wizard/WizardOptions.qml | 8 +- wizard/WizardPassword.qml | 1 + wizard/WizardRecoveryWallet.qml | 6 +- wizard/utils.js | 5 ++ 34 files changed, 837 insertions(+), 314 deletions(-) diff --git a/BasicPanel.qml b/BasicPanel.qml index 5698316f..3c8de955 100644 --- a/BasicPanel.qml +++ b/BasicPanel.qml @@ -152,7 +152,7 @@ Rectangle { height: 32 fontSize: 15 width: parent.width - sendButton.width - row.spacing - placeholderText: qsTr("amount...") + placeholderText: qsTr("amount...") + translationManager.emptyString } StandardButton { @@ -176,7 +176,7 @@ Rectangle { anchors.margins: 12 fontSize: 15 height: 32 - placeholderText: qsTr("destination...") + placeholderText: qsTr("destination...") + translationManager.emptyString } Text { @@ -188,7 +188,7 @@ Rectangle { font.family: "Arial" font.pixelSize: 12 color: "#535353" - text: qsTr("Privacy level") + text: qsTr("Privacy level") + translationManager.emptyString } PrivacyLevelSmall { @@ -209,6 +209,6 @@ Rectangle { anchors.margins: 12 fontSize: 15 height: 32 - placeholderText: qsTr("payment ID (optional)...") + placeholderText: qsTr("payment ID (optional)...") + translationManager.emptyString } } diff --git a/LeftPanel.qml b/LeftPanel.qml index 6e067d03..604f2d6e 100644 --- a/LeftPanel.qml +++ b/LeftPanel.qml @@ -103,7 +103,7 @@ Rectangle { text: qsTr("Balance") + translationManager.emptyString anchors.left: parent.left anchors.leftMargin: 50 - tipText: qsTr("Test tip 1<br/><br/>line 2") + tipText: qsTr("Test tip 1<br/><br/>line 2") + translationManager.emptyString } Row { @@ -135,10 +135,10 @@ Rectangle { } Label { - text: qsTr("Unlocked balance") + text: qsTr("Unlocked balance") + translationManager.emptyString anchors.left: parent.left anchors.leftMargin: 50 - tipText: qsTr("Test tip 2<br/><br/>line 2") + tipText: qsTr("Test tip 2<br/><br/>line 2") + translationManager.emptyString } Text { @@ -192,8 +192,8 @@ Rectangle { id: dashboardButton anchors.left: parent.left anchors.right: parent.right - text: qsTr("Dashboard") - symbol: qsTr("D") + text: qsTr("Dashboard") + translationManager.emptyString + symbol: qsTr("D") + translationManager.emptyString dotColor: "#FFE00A" checked: true onClicked: { @@ -219,8 +219,8 @@ Rectangle { id: transferButton anchors.left: parent.left anchors.right: parent.right - text: qsTr("Transfer") - symbol: qsTr("T") + text: qsTr("Transfer") + translationManager.emptyString + symbol: qsTr("T") + translationManager.emptyString dotColor: "#FF6C3C" onClicked: { parent.previousButton.checked = false @@ -242,8 +242,8 @@ Rectangle { id: receiveButton anchors.left: parent.left anchors.right: parent.right - text: qsTr("Receive") - symbol: qsTr("R") + text: qsTr("Receive") + translationManager.emptyString + symbol: qsTr("R") + translationManager.emptyString dotColor: "#AAFFBB" onClicked: { parent.previousButton.checked = false @@ -266,8 +266,8 @@ Rectangle { id: historyButton anchors.left: parent.left anchors.right: parent.right - text: qsTr("History") - symbol: qsTr("H") + text: qsTr("History") + translationManager.emptyString + symbol: qsTr("H") + translationManager.emptyString dotColor: "#6B0072" onClicked: { parent.previousButton.checked = false @@ -289,8 +289,8 @@ Rectangle { id: addressBookButton anchors.left: parent.left anchors.right: parent.right - text: qsTr("Address book") - symbol: qsTr("B") + text: qsTr("Address book") + translationManager.emptyString + symbol: qsTr("B") + translationManager.emptyString dotColor: "#FF4F41" onClicked: { parent.previousButton.checked = false @@ -312,8 +312,8 @@ Rectangle { id: miningButton anchors.left: parent.left anchors.right: parent.right - text: qsTr("Mining") - symbol: qsTr("M") + text: qsTr("Mining") + translationManager.emptyString + symbol: qsTr("M") + translationManager.emptyString dotColor: "#FFD781" onClicked: { parent.previousButton.checked = false @@ -335,8 +335,8 @@ Rectangle { id: settingsButton anchors.left: parent.left anchors.right: parent.right - text: qsTr("Settings") - symbol: qsTr("S") + text: qsTr("Settings") + translationManager.emptyString + symbol: qsTr("S") + translationManager.emptyString dotColor: "#36B25C" onClicked: { parent.previousButton.checked = false diff --git a/RightPanel.qml b/RightPanel.qml index c5878146..932b3916 100644 --- a/RightPanel.qml +++ b/RightPanel.qml @@ -56,9 +56,9 @@ Rectangle { Tab { id: twitter; title: qsTr("Twitter"); source: "tabs/Twitter.qml" } - Tab { title: "News" } - Tab { title: "Help" } - Tab { title: "About" } + Tab { title: qsTr("News") + translationManager.emptyString } + Tab { title: qsTr("Help") + translationManager.emptyString } + Tab { title: qsTr("About") + translationManager.emptyString } diff --git a/components/AddressBookTable.qml b/components/AddressBookTable.qml index ab4bf61d..756445f7 100644 --- a/components/AddressBookTable.qml +++ b/components/AddressBookTable.qml @@ -44,7 +44,7 @@ ListView { font.family: "Arial" font.pixelSize: 14 color: "#545454" - text: qsTr("No more results") + text: qsTr("No more results") + translationManager.emptyString } } @@ -103,7 +103,7 @@ ListView { font.pixelSize: 12 font.letterSpacing: -1 color: "#535353" - text: qsTr("Payment ID:") + text: qsTr("Payment ID:") + + translationManager.emptyString } Text { diff --git a/components/DashboardTable.qml b/components/DashboardTable.qml index 07fe6ac2..05b23c6e 100644 --- a/components/DashboardTable.qml +++ b/components/DashboardTable.qml @@ -44,7 +44,7 @@ ListView { font.family: "Arial" font.pixelSize: 14 color: "#545454" - text: qsTr("No more results") + text: qsTr("No more results") + translationManager.emptyString } } @@ -134,7 +134,7 @@ ListView { font.family: "Arial" font.pixelSize: 12 color: "#545454" - text: qsTr("Date") + text: qsTr("Date") + translationManager.emptyString } Row { @@ -169,7 +169,7 @@ ListView { font.family: "Arial" font.pixelSize: 12 color: "#545454" - text: qsTr("Balance") + text: qsTr("Balance") + translationManager.emptyString } Text { @@ -190,7 +190,7 @@ ListView { font.family: "Arial" font.pixelSize: 12 color: "#545454" - text: qsTr("Amount") + text: qsTr("Amount") + translationManager.emptyString } Row { diff --git a/components/HistoryTable.qml b/components/HistoryTable.qml index 3ee8c82c..db92aa69 100644 --- a/components/HistoryTable.qml +++ b/components/HistoryTable.qml @@ -44,7 +44,7 @@ ListView { font.family: "Arial" font.pixelSize: 14 color: "#545454" - text: qsTr("No more results") + text: qsTr("No more results") + translationManager.emptyString } } @@ -126,7 +126,7 @@ ListView { font.pixelSize: 12 font.letterSpacing: -1 color: "#535353" - text: paymentId !== "" ? qsTr("Payment ID:") : "" + text: paymentId !== "" ? qsTr("Payment ID:") + translationManager.emptyString : "" } Text { @@ -164,7 +164,7 @@ ListView { font.family: "Arial" font.pixelSize: 12 color: "#545454" - text: qsTr("Date") + text: qsTr("Date") + translationManager.emptyString } Row { @@ -199,7 +199,7 @@ ListView { font.family: "Arial" font.pixelSize: 12 color: "#545454" - text: qsTr("Balance") + text: qsTr("Balance") + translationManager.emptyString } Text { @@ -220,7 +220,7 @@ ListView { font.family: "Arial" font.pixelSize: 12 color: "#545454" - text: qsTr("Amount") + text: qsTr("Amount") + translationManager.emptyString } Row { diff --git a/components/NetworkStatusItem.qml b/components/NetworkStatusItem.qml index 720fe536..6fb1d2eb 100644 --- a/components/NetworkStatusItem.qml +++ b/components/NetworkStatusItem.qml @@ -63,7 +63,7 @@ Row { font.family: "Arial" font.pixelSize: 18 color: item.connected ? "#FF6C3B" : "#AAAAAA" - text: item.connected ? qsTr("Connected") : qsTr("Disconnected") + text: (item.connected ? qsTr("Connected") : qsTr("Disconnected")) + translationManager.emptyString } } } diff --git a/components/PrivacyLevelSmall.qml b/components/PrivacyLevelSmall.qml index 9321ffbd..cb1cd36e 100644 --- a/components/PrivacyLevelSmall.qml +++ b/components/PrivacyLevelSmall.qml @@ -99,7 +99,7 @@ Item { font.bold: true color: "#000000" x: row.x + (row.positions[0] !== undefined ? row.positions[0].currentX - 3 : 0) - width - text: qsTr("LOW") + text: qsTr("LOW") + translationManager.emptyString } Text { @@ -110,7 +110,7 @@ Item { font.bold: true color: "#000000" x: row.x + (row.positions[4] !== undefined ? row.positions[4].currentX - 3 : 0) - width - text: qsTr("MEDIUM") + text: qsTr("MEDIUM") + translationManager.emptyString } Text { @@ -121,7 +121,7 @@ Item { font.bold: true color: "#000000" x: row.x + (row.positions[13] !== undefined ? row.positions[13].currentX - 3 : 0) - width - text: qsTr("HIGH") + text: qsTr("HIGH") + translationManager.emptyString } MouseArea { diff --git a/components/SearchInput.qml b/components/SearchInput.qml index b104247c..35be896f 100644 --- a/components/SearchInput.qml +++ b/components/SearchInput.qml @@ -66,7 +66,7 @@ Item { anchors.leftMargin: 45 font.pixelSize: 18 verticalAlignment: TextInput.AlignVCenter - placeholderText: qsTr("Search by...") + placeholderText: qsTr("Search by...") + translationManager.emptyString } Item { diff --git a/components/TickDelegate.qml b/components/TickDelegate.qml index 70ef1b50..2163d3e7 100644 --- a/components/TickDelegate.qml +++ b/components/TickDelegate.qml @@ -52,9 +52,9 @@ Item { font.pixelSize: 12 color: "#4A4949" text: { - if(currentIndex === 0) return qsTr("LOW") - if(currentIndex === 3) return qsTr("MEDIUM") - if(currentIndex === 13) return qsTr("HIGH") + if(currentIndex === 0) return qsTr("LOW") + translationManager.emptyString + if(currentIndex === 3) return qsTr("MEDIUM") + translationManager.emptyString + if(currentIndex === 13) return qsTr("HIGH") + translationManager.emptyString return "" } } diff --git a/components/TitleBar.qml b/components/TitleBar.qml index f27caf73..e0baf8f1 100644 --- a/components/TitleBar.qml +++ b/components/TitleBar.qml @@ -35,7 +35,7 @@ Rectangle { color: "#000000" y: -height property int mouseX: 0 - property string title: "Monero - Donations" + property string title: qsTr("Monero - Donations") + translationManager.emptyString property bool containsMouse: false property alias maximizeButtonVisible: maximizeButton.visible property alias basicButtonVisible: goToBasicVersionButton.visible diff --git a/main.qml b/main.qml index 7316fc56..da8545af 100644 --- a/main.qml +++ b/main.qml @@ -145,7 +145,7 @@ ApplicationWindow { wallet = walletManager.openWallet(wallet_path, "", persistentSettings.testnet); if (wallet.status !== Wallet.Status_Ok) { console.log("Error opening wallet: ", wallet.errorString); - informationPopup.title = qsTr("Error"); + informationPopup.title = qsTr("Error") + translationManager.emptyString; informationPopup.text = qsTr("Couldn't open wallet: ") + wallet.errorString; informationPopup.icon = StandardIcon.Critical informationPopup.open() @@ -200,7 +200,7 @@ ApplicationWindow { transaction = wallet.createTransaction(address, paymentId, amountxmr, mixinCount, priority); if (transaction.status !== PendingTransaction.Status_Ok) { console.error("Can't create transaction: ", transaction.errorString); - informationPopup.title = qsTr("Error"); + informationPopup.title = qsTr("Error") + translationManager.emptyString; informationPopup.text = qsTr("Can't create transaction: ") + transaction.errorString informationPopup.icon = StandardIcon.Critical informationPopup.open(); @@ -213,12 +213,13 @@ ApplicationWindow { // here we show confirmation popup; - transactionConfirmationPopup.title = qsTr("Confirmation") + transactionConfirmationPopup.title = qsTr("Confirmation") + translationManager.emptyString transactionConfirmationPopup.text = qsTr("Please confirm transaction:\n\n") + qsTr("\nAddress: ") + address + qsTr("\nPayment ID: ") + paymentId + qsTr("\nAmount: ") + walletManager.displayAmount(transaction.amount) + qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee) + + translationManager.emptyString transactionConfirmationPopup.icon = StandardIcon.Question transactionConfirmationPopup.open() // committing transaction @@ -229,12 +230,12 @@ ApplicationWindow { function handleTransactionConfirmed() { if (!transaction.commit()) { console.log("Error committing transaction: " + transaction.errorString); - informationPopup.title = qsTr("Error"); + informationPopup.title = qsTr("Error") + translationManager.emptyString informationPopup.text = qsTr("Couldn't send the money: ") + transaction.errorString informationPopup.icon = StandardIcon.Critical } else { - informationPopup.title = qsTr("Information") - informationPopup.text = qsTr("Money sent successfully") + informationPopup.title = qsTr("Information") + translationManager.emptyString + informationPopup.text = qsTr("Money sent successfully") + translationManager.emptyString informationPopup.icon = StandardIcon.Information } @@ -332,7 +333,7 @@ ApplicationWindow { PropertyChanges { target: titleBar; maximizeButtonVisible: false } PropertyChanges { target: frameArea; blocked: true } PropertyChanges { target: titleBar; y: 0 } - PropertyChanges { target: titleBar; title: "Program setup wizard" } + PropertyChanges { target: titleBar; title: qsTr("Program setup wizard") + translationManager.emptyString } }, State { name: "normal" PropertyChanges { target: leftPanel; visible: true } @@ -346,7 +347,7 @@ ApplicationWindow { PropertyChanges { target: titleBar; maximizeButtonVisible: true } PropertyChanges { target: frameArea; blocked: false } PropertyChanges { target: titleBar; y: -titleBar.height } - PropertyChanges { target: titleBar; title: "Monero - Donations" } + PropertyChanges { target: titleBar; title: qsTr("Monero - Donations") + translationManager.emptyString } } ] @@ -385,7 +386,7 @@ ApplicationWindow { TipItem { id: tipItem - text: "send to the same destination" + text: qsTr("send to the same destination") + translationManager.emptyString visible: false } diff --git a/pages/AddressBook.qml b/pages/AddressBook.qml index 2fcd939a..7ca79f35 100644 --- a/pages/AddressBook.qml +++ b/pages/AddressBook.qml @@ -44,7 +44,7 @@ Rectangle { font.family: "Arial" font.pixelSize: 18 color: "#4A4949" - text: qsTr("Add new entry") + text: qsTr("Add new entry") + translationManager.emptyString } Label { @@ -55,7 +55,7 @@ Rectangle { anchors.topMargin: 17 text: qsTr("Address") fontSize: 14 - tipText: qsTr("<b>Tip tekst test</b>") + tipText: qsTr("<b>Tip tekst test</b>") + translationManager.emptyString } LineEdit { @@ -74,9 +74,10 @@ Rectangle { anchors.top: addressLine.bottom anchors.leftMargin: 17 anchors.topMargin: 17 - text: qsTr("Payment ID <font size='2'>(Optional)</font>") + text: qsTr("Payment ID <font size='2'>(Optional)</font>") + translationManager.emptyString fontSize: 14 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 thevtransfer") + + translationManager.emptyString } LineEdit { @@ -95,9 +96,9 @@ Rectangle { anchors.top: paymentIdLine.bottom anchors.leftMargin: 17 anchors.topMargin: 17 - text: qsTr("Description <font size='2'>(Local database)</font>") + text: qsTr("Description <font size='2'>(Local database)</font>") + translationManager.emptyString fontSize: 14 - tipText: qsTr("<b>Tip tekst test</b><br/><br/>test line 2") + tipText: qsTr("<b>Tip tekst test</b><br/><br/>test line 2") + translationManager.emptyString } LineEdit { @@ -169,9 +170,9 @@ Rectangle { ListModel { id: columnsModel - ListElement { columnName: "Address"; columnWidth: 148 } - ListElement { columnName: "Payment ID"; columnWidth: 148 } - ListElement { columnName: "Description"; columnWidth: 148 } + 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 { diff --git a/pages/Dashboard.qml b/pages/Dashboard.qml index da8642ec..3f1621ed 100644 --- a/pages/Dashboard.qml +++ b/pages/Dashboard.qml @@ -54,7 +54,7 @@ Rectangle { font.family: "Arial" font.pixelSize: 18 color: "#4A4949" - text: qsTr("Quick transfer") + text: qsTr("Quick transfer") + translationManager.emptyString } LineEdit { @@ -101,6 +101,7 @@ Rectangle { textFormat: Text.RichText text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>\ lookng for security level and address book? go to <a href='#'>Transfer</a> tab") + + translationManager.emptyString font.underline: false onLinkActivated: appWindow.showPageRequest("Transfer") } diff --git a/pages/History.qml b/pages/History.qml index 6e67d04e..9ec2dd2b 100644 --- a/pages/History.qml +++ b/pages/History.qml @@ -44,7 +44,7 @@ Rectangle { font.family: "Arial" font.pixelSize: 18 color: "#4A4949" - text: qsTr("Filter trasactions history") + text: qsTr("Filter trasactions history") + translationManager.emptyString } Label { @@ -55,7 +55,7 @@ Rectangle { anchors.topMargin: 17 text: qsTr("Address") fontSize: 14 - tipText: qsTr("<b>Tip tekst test</b>") + tipText: qsTr("<b>Tip tekst test</b>") + translationManager.emptyString } LineEdit { @@ -74,9 +74,10 @@ Rectangle { anchors.top: addressLine.bottom anchors.leftMargin: 17 anchors.topMargin: 17 - text: qsTr("Payment ID <font size='2'>(Optional)</font>") + text: qsTr("Payment ID <font size='2'>(Optional)</font>") + translationManager.emptyString fontSize: 14 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 thevtransfer") + + translationManager.emptyString } LineEdit { @@ -95,9 +96,9 @@ Rectangle { anchors.top: paymentIdLine.bottom anchors.leftMargin: 17 anchors.topMargin: 17 - text: qsTr("Description <font size='2'>(Local database)</font>") + text: qsTr("Description <font size='2'>(Local database)</font>") + translationManager.emptyString fontSize: 14 - tipText: qsTr("<b>Tip tekst test</b><br/><br/>test line 2") + tipText: qsTr("<b>Tip tekst test</b><br/><br/>test line 2") + translationManager.emptyString } LineEdit { @@ -117,9 +118,9 @@ Rectangle { anchors.leftMargin: 17 anchors.topMargin: 17 width: 156 - text: qsTr("Date from") + text: qsTr("Date from") + translationManager.emptyString fontSize: 14 - tipText: qsTr("<b>Tip tekst test</b>") + tipText: qsTr("<b>Tip tekst test</b>") + translationManager.emptyString } DatePicker { @@ -139,7 +140,7 @@ Rectangle { anchors.topMargin: 17 text: qsTr("To") fontSize: 14 - tipText: qsTr("<b>Tip tekst test</b>") + tipText: qsTr("<b>Tip tekst test</b>") + translationManager.emptyString } DatePicker { @@ -185,9 +186,9 @@ Rectangle { anchors.leftMargin: 17 anchors.topMargin: 17 width: 156 - text: qsTr("Type of transation") + text: qsTr("Type of transation") + translationManager.emptyString fontSize: 14 - tipText: qsTr("<b>Tip tekst test</b>") + tipText: qsTr("<b>Tip tekst test</b>") + translationManager.emptyString } ListModel { @@ -219,9 +220,9 @@ Rectangle { anchors.leftMargin: 17 anchors.topMargin: 17 width: 156 - text: qsTr("Amount from") + text: qsTr("Amount from") + translationManager.emptyString fontSize: 14 - tipText: qsTr("<b>Tip tekst test</b>") + tipText: qsTr("<b>Tip tekst test</b>") + translationManager.emptyString } LineEdit { @@ -242,7 +243,7 @@ Rectangle { width: 156 text: qsTr("To") fontSize: 14 - tipText: qsTr("<b>Tip tekst test</b>") + tipText: qsTr("<b>Tip tekst test</b>") + translationManager.emptyString } LineEdit { diff --git a/pages/Receive.qml b/pages/Receive.qml index 623c629d..1218ed7c 100644 --- a/pages/Receive.qml +++ b/pages/Receive.qml @@ -76,14 +76,14 @@ Rectangle { Label { id: addressLabel fontSize: 14 - text: qsTr("Address") + text: qsTr("Address") + translationManager.emptyString width: mainLayout.labelWidth } LineEdit { id: addressLine fontSize: mainLayout.lineEditFontSize - placeholderText: "ReadOnly wallet address displayed here"; + placeholderText: qsTr("ReadOnly wallet address displayed here") + translationManager.emptyString; readOnly: true width: mainLayout.editWidth Layout.fillWidth: true @@ -103,7 +103,7 @@ Rectangle { Label { id: integratedAddressLabel fontSize: 14 - text: qsTr("Integrated address") + text: qsTr("Integrated address") + translationManager.emptyString width: mainLayout.labelWidth } @@ -112,7 +112,7 @@ Rectangle { id: integratedAddressLine fontSize: mainLayout.lineEditFontSize - placeholderText: "ReadOnly wallet integrated address displayed here"; + placeholderText: qsTr("ReadOnly wallet integrated address displayed here") + translationManager.emptyString readOnly: true width: mainLayout.editWidth Layout.fillWidth: true @@ -133,7 +133,7 @@ Rectangle { Label { id: paymentIdLabel fontSize: 14 - text: qsTr("Payment ID") + text: qsTr("Payment ID") + translationManager.emptyString width: mainLayout.labelWidth } @@ -141,7 +141,7 @@ Rectangle { LineEdit { id: paymentIdLine fontSize: mainLayout.lineEditFontSize - placeholderText: "PaymentID here"; + placeholderText: qsTr("PaymentID here") + translationManager.emptyString; readOnly: false width: mainLayout.editWidth diff --git a/pages/Transfer.qml b/pages/Transfer.qml index aa79c18f..342e73cb 100644 --- a/pages/Transfer.qml +++ b/pages/Transfer.qml @@ -54,7 +54,7 @@ Rectangle { anchors.leftMargin: 17 anchors.rightMargin: 17 anchors.topMargin: 17 - text: qsTr("Amount") + text: qsTr("Amount") + translationManager.emptyString fontSize: 14 } @@ -64,7 +64,7 @@ Rectangle { anchors.topMargin: 17 fontSize: 14 x: (parent.width - 17) / 2 + 17 - text: qsTr("Transaction priority") + text: qsTr("Transaction priority") + translationManager.emptyString } Row { @@ -86,16 +86,16 @@ Rectangle { // Amount input LineEdit { id: amountLine - placeholderText: qsTr("Amount...") + placeholderText: qsTr("Amount...") + translationManager.emptyString width: parent.width - 37 - 17 } } ListModel { id: priorityModel - ListElement { column1: "LOW"; column2: ""; priority: PendingTransaction.Priority_Low } - ListElement { column1: "MEDIUM"; column2: ""; priority: PendingTransaction.Priority_Medium } - ListElement { column1: "HIGH"; column2: ""; priority: PendingTransaction.Priority_High } + ListElement { column1: qsTr("LOW") + translationManager.emptyString; column2: ""; priority: PendingTransaction.Priority_Low } + ListElement { column1: qsTr("MEDIUM") + translationManager.emptyString; column2: ""; priority: PendingTransaction.Priority_Medium } + ListElement { column1: qsTr("HIGH") + translationManager.emptyString; column2: ""; priority: PendingTransaction.Priority_High } } StandardDropdown { @@ -124,7 +124,7 @@ Rectangle { anchors.rightMargin: 17 anchors.topMargin: 30 fontSize: 14 - text: qsTr("Privacy Level") + text: qsTr("Privacy Level") + translationManager.emptyString } PrivacyLevel { @@ -166,6 +166,7 @@ Rectangle { textFormat: Text.RichText text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>\ Address <font size='2'> ( Type in or select from </font> <a href='#'>Address</a><font size='2'> book )</font>") + + translationManager.emptyString onLinkActivated: appWindow.showPageRequest("AddressBook") } @@ -190,7 +191,7 @@ Rectangle { anchors.rightMargin: 17 anchors.topMargin: 17 fontSize: 14 - text: qsTr("Payment ID <font size='2'>( Optional )</font>") + text: qsTr("Payment ID <font size='2'>( Optional )</font>") + translationManager.emptyString } // payment id input @@ -215,6 +216,7 @@ Rectangle { anchors.topMargin: 17 fontSize: 14 text: qsTr("Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font>") + + translationManager.emptyString } LineEdit { @@ -234,7 +236,7 @@ Rectangle { anchors.leftMargin: 17 anchors.topMargin: 17 width: 60 - text: qsTr("SEND") + text: qsTr("SEND") + translationManager.emptyString shadowReleasedColor: "#FF4304" shadowPressedColor: "#B32D00" releasedColor: "#FF6C3C" diff --git a/translations/monero-core_de.ts b/translations/monero-core_de.ts index f2c59688..ea08d710 100644 --- a/translations/monero-core_de.ts +++ b/translations/monero-core_de.ts @@ -10,6 +10,7 @@ </message> <message> <location filename="../pages/AddressBook.qml" line="56"/> + <location filename="../pages/AddressBook.qml" line="173"/> <source>Address</source> <translation type="unfinished"></translation> </message> @@ -29,20 +30,30 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="98"/> + <location filename="../pages/AddressBook.qml" line="99"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="100"/> + <location filename="../pages/AddressBook.qml" line="101"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="125"/> + <location filename="../pages/AddressBook.qml" line="126"/> <source>ADD</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/AddressBook.qml" line="174"/> + <source>Payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/AddressBook.qml" line="175"/> + <source>Description</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>AddressBookTable</name> @@ -160,11 +171,11 @@ </message> <message> <location filename="../pages/History.qml" line="58"/> - <location filename="../pages/History.qml" line="122"/> - <location filename="../pages/History.qml" line="142"/> - <location filename="../pages/History.qml" line="190"/> - <location filename="../pages/History.qml" line="224"/> - <location filename="../pages/History.qml" line="245"/> + <location filename="../pages/History.qml" line="123"/> + <location filename="../pages/History.qml" line="143"/> + <location filename="../pages/History.qml" line="191"/> + <location filename="../pages/History.qml" line="225"/> + <location filename="../pages/History.qml" line="246"/> <source><b>Tip tekst test</b></source> <translation type="unfinished"></translation> </message> @@ -179,43 +190,43 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="98"/> + <location filename="../pages/History.qml" line="99"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="100"/> + <location filename="../pages/History.qml" line="101"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="120"/> + <location filename="../pages/History.qml" line="121"/> <source>Date from</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="140"/> - <location filename="../pages/History.qml" line="243"/> + <location filename="../pages/History.qml" line="141"/> + <location filename="../pages/History.qml" line="244"/> <source>To</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="160"/> + <location filename="../pages/History.qml" line="161"/> <source>FILTER</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="169"/> + <location filename="../pages/History.qml" line="170"/> <source>Advance filtering</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="188"/> + <location filename="../pages/History.qml" line="189"/> <source>Type of transation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="222"/> + <location filename="../pages/History.qml" line="223"/> <source>Amount from</source> <translation type="unfinished"></translation> </message> @@ -334,16 +345,31 @@ <source>Address</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="86"/> + <source>ReadOnly wallet address displayed here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="106"/> <source>Integrated address</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="115"/> + <source>ReadOnly wallet integrated address displayed here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="136"/> <source>Payment ID</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="144"/> + <source>PaymentID here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="168"/> <source>Generate</source> @@ -357,6 +383,21 @@ <source>Twitter</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../RightPanel.qml" line="59"/> + <source>News</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../RightPanel.qml" line="60"/> + <source>Help</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../RightPanel.qml" line="61"/> + <source>About</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>SearchInput</name> @@ -389,6 +430,14 @@ <translation type="unfinished"></translation> </message> </context> +<context> + <name>TitleBar</name> + <message> + <location filename="../components/TitleBar.qml" line="38"/> + <source>Monero - Donations</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>Transfer</name> <message> @@ -406,6 +455,21 @@ <source>Amount...</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Transfer.qml" line="96"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="97"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="98"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Transfer.qml" line="127"/> <source>Privacy Level</source> @@ -422,17 +486,17 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="193"/> + <location filename="../pages/Transfer.qml" line="194"/> <source>Payment ID <font size='2'>( Optional )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="217"/> + <location filename="../pages/Transfer.qml" line="218"/> <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="237"/> + <location filename="../pages/Transfer.qml" line="239"/> <source>SEND</source> <translation type="unfinished"></translation> </message> @@ -455,22 +519,22 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="126"/> + <location filename="../wizard/WizardConfigure.qml" line="127"/> <source>Enable disk conservation mode?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="144"/> + <location filename="../wizard/WizardConfigure.qml" line="145"/> <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="156"/> + <location filename="../wizard/WizardConfigure.qml" line="158"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="174"/> + <location filename="../wizard/WizardConfigure.qml" line="176"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -511,12 +575,12 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardDonation.qml" line="175"/> + <location filename="../wizard/WizardDonation.qml" line="176"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardDonation.qml" line="193"/> + <location filename="../wizard/WizardDonation.qml" line="194"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -559,12 +623,12 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="51"/> + <location filename="../wizard/WizardFinish.qml" line="52"/> <source>An overview of your Monero configuration is below:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="102"/> + <location filename="../wizard/WizardFinish.qml" line="103"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -604,6 +668,11 @@ <source>Your wallet is stored in</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../wizard/WizardManageWalletUI.qml" line="187"/> + <source>Please choose a directory</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>WizardMemoTextInput</name> @@ -681,7 +750,7 @@ <message> <location filename="../main.qml" line="148"/> <location filename="../main.qml" line="203"/> - <location filename="../main.qml" line="232"/> + <location filename="../main.qml" line="233"/> <source>Error</source> <translation type="unfinished"></translation> </message> @@ -732,24 +801,39 @@ Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="233"/> + <location filename="../main.qml" line="234"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="236"/> + <location filename="../main.qml" line="237"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="237"/> + <location filename="../main.qml" line="238"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="309"/> + <location filename="../main.qml" line="310"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../main.qml" line="336"/> + <source>Program setup wizard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="350"/> + <source>Monero - Donations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="389"/> + <source>send to the same destination</source> + <translation type="unfinished"></translation> + </message> </context> </TS> diff --git a/translations/monero-core_en.ts b/translations/monero-core_en.ts index f8f7b3ea..dca4c577 100644 --- a/translations/monero-core_en.ts +++ b/translations/monero-core_en.ts @@ -10,6 +10,7 @@ </message> <message> <location filename="../pages/AddressBook.qml" line="56"/> + <location filename="../pages/AddressBook.qml" line="173"/> <source>Address</source> <translation type="unfinished"></translation> </message> @@ -29,20 +30,30 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="98"/> + <location filename="../pages/AddressBook.qml" line="99"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="100"/> + <location filename="../pages/AddressBook.qml" line="101"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="125"/> + <location filename="../pages/AddressBook.qml" line="126"/> <source>ADD</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/AddressBook.qml" line="174"/> + <source>Payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/AddressBook.qml" line="175"/> + <source>Description</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>AddressBookTable</name> @@ -160,11 +171,11 @@ </message> <message> <location filename="../pages/History.qml" line="58"/> - <location filename="../pages/History.qml" line="122"/> - <location filename="../pages/History.qml" line="142"/> - <location filename="../pages/History.qml" line="190"/> - <location filename="../pages/History.qml" line="224"/> - <location filename="../pages/History.qml" line="245"/> + <location filename="../pages/History.qml" line="123"/> + <location filename="../pages/History.qml" line="143"/> + <location filename="../pages/History.qml" line="191"/> + <location filename="../pages/History.qml" line="225"/> + <location filename="../pages/History.qml" line="246"/> <source><b>Tip tekst test</b></source> <translation type="unfinished"></translation> </message> @@ -179,43 +190,43 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="98"/> + <location filename="../pages/History.qml" line="99"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="100"/> + <location filename="../pages/History.qml" line="101"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="120"/> + <location filename="../pages/History.qml" line="121"/> <source>Date from</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="140"/> - <location filename="../pages/History.qml" line="243"/> + <location filename="../pages/History.qml" line="141"/> + <location filename="../pages/History.qml" line="244"/> <source>To</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="160"/> + <location filename="../pages/History.qml" line="161"/> <source>FILTER</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="169"/> + <location filename="../pages/History.qml" line="170"/> <source>Advance filtering</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="188"/> + <location filename="../pages/History.qml" line="189"/> <source>Type of transation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="222"/> + <location filename="../pages/History.qml" line="223"/> <source>Amount from</source> <translation type="unfinished"></translation> </message> @@ -334,16 +345,31 @@ <source>Address</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="86"/> + <source>ReadOnly wallet address displayed here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="106"/> <source>Integrated address</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="115"/> + <source>ReadOnly wallet integrated address displayed here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="136"/> <source>Payment ID</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="144"/> + <source>PaymentID here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="168"/> <source>Generate</source> @@ -357,6 +383,21 @@ <source>Twitter</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../RightPanel.qml" line="59"/> + <source>News</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../RightPanel.qml" line="60"/> + <source>Help</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../RightPanel.qml" line="61"/> + <source>About</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>SearchInput</name> @@ -389,6 +430,14 @@ <translation type="unfinished"></translation> </message> </context> +<context> + <name>TitleBar</name> + <message> + <location filename="../components/TitleBar.qml" line="38"/> + <source>Monero - Donations</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>Transfer</name> <message> @@ -406,6 +455,21 @@ <source>Amount...</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Transfer.qml" line="96"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="97"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="98"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Transfer.qml" line="127"/> <source>Privacy Level</source> @@ -422,17 +486,17 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="193"/> + <location filename="../pages/Transfer.qml" line="194"/> <source>Payment ID <font size='2'>( Optional )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="217"/> + <location filename="../pages/Transfer.qml" line="218"/> <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="237"/> + <location filename="../pages/Transfer.qml" line="239"/> <source>SEND</source> <translation type="unfinished"></translation> </message> @@ -455,22 +519,22 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="126"/> + <location filename="../wizard/WizardConfigure.qml" line="127"/> <source>Enable disk conservation mode?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="144"/> + <location filename="../wizard/WizardConfigure.qml" line="145"/> <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="156"/> + <location filename="../wizard/WizardConfigure.qml" line="158"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="174"/> + <location filename="../wizard/WizardConfigure.qml" line="176"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -511,12 +575,12 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardDonation.qml" line="175"/> + <location filename="../wizard/WizardDonation.qml" line="176"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardDonation.qml" line="193"/> + <location filename="../wizard/WizardDonation.qml" line="194"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -559,12 +623,12 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="51"/> + <location filename="../wizard/WizardFinish.qml" line="52"/> <source>An overview of your Monero configuration is below:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="102"/> + <location filename="../wizard/WizardFinish.qml" line="103"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -604,6 +668,11 @@ <source>Your wallet is stored in</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../wizard/WizardManageWalletUI.qml" line="187"/> + <source>Please choose a directory</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>WizardMemoTextInput</name> @@ -681,7 +750,7 @@ <message> <location filename="../main.qml" line="148"/> <location filename="../main.qml" line="203"/> - <location filename="../main.qml" line="232"/> + <location filename="../main.qml" line="233"/> <source>Error</source> <translation type="unfinished"></translation> </message> @@ -732,24 +801,39 @@ Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="233"/> + <location filename="../main.qml" line="234"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="236"/> + <location filename="../main.qml" line="237"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="237"/> + <location filename="../main.qml" line="238"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="309"/> + <location filename="../main.qml" line="310"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../main.qml" line="336"/> + <source>Program setup wizard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="350"/> + <source>Monero - Donations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="389"/> + <source>send to the same destination</source> + <translation type="unfinished"></translation> + </message> </context> </TS> diff --git a/translations/monero-core_it.ts b/translations/monero-core_it.ts index 3b4e2760..2c9c4b78 100644 --- a/translations/monero-core_it.ts +++ b/translations/monero-core_it.ts @@ -10,6 +10,7 @@ </message> <message> <location filename="../pages/AddressBook.qml" line="56"/> + <location filename="../pages/AddressBook.qml" line="173"/> <source>Address</source> <translation type="unfinished"></translation> </message> @@ -29,20 +30,30 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="98"/> + <location filename="../pages/AddressBook.qml" line="99"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="100"/> + <location filename="../pages/AddressBook.qml" line="101"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="125"/> + <location filename="../pages/AddressBook.qml" line="126"/> <source>ADD</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/AddressBook.qml" line="174"/> + <source>Payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/AddressBook.qml" line="175"/> + <source>Description</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>AddressBookTable</name> @@ -160,11 +171,11 @@ </message> <message> <location filename="../pages/History.qml" line="58"/> - <location filename="../pages/History.qml" line="122"/> - <location filename="../pages/History.qml" line="142"/> - <location filename="../pages/History.qml" line="190"/> - <location filename="../pages/History.qml" line="224"/> - <location filename="../pages/History.qml" line="245"/> + <location filename="../pages/History.qml" line="123"/> + <location filename="../pages/History.qml" line="143"/> + <location filename="../pages/History.qml" line="191"/> + <location filename="../pages/History.qml" line="225"/> + <location filename="../pages/History.qml" line="246"/> <source><b>Tip tekst test</b></source> <translation type="unfinished"></translation> </message> @@ -179,43 +190,43 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="98"/> + <location filename="../pages/History.qml" line="99"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="100"/> + <location filename="../pages/History.qml" line="101"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="120"/> + <location filename="../pages/History.qml" line="121"/> <source>Date from</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="140"/> - <location filename="../pages/History.qml" line="243"/> + <location filename="../pages/History.qml" line="141"/> + <location filename="../pages/History.qml" line="244"/> <source>To</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="160"/> + <location filename="../pages/History.qml" line="161"/> <source>FILTER</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="169"/> + <location filename="../pages/History.qml" line="170"/> <source>Advance filtering</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="188"/> + <location filename="../pages/History.qml" line="189"/> <source>Type of transation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="222"/> + <location filename="../pages/History.qml" line="223"/> <source>Amount from</source> <translation type="unfinished"></translation> </message> @@ -334,16 +345,31 @@ <source>Address</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="86"/> + <source>ReadOnly wallet address displayed here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="106"/> <source>Integrated address</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="115"/> + <source>ReadOnly wallet integrated address displayed here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="136"/> <source>Payment ID</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="144"/> + <source>PaymentID here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="168"/> <source>Generate</source> @@ -357,6 +383,21 @@ <source>Twitter</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../RightPanel.qml" line="59"/> + <source>News</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../RightPanel.qml" line="60"/> + <source>Help</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../RightPanel.qml" line="61"/> + <source>About</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>SearchInput</name> @@ -389,6 +430,14 @@ <translation type="unfinished"></translation> </message> </context> +<context> + <name>TitleBar</name> + <message> + <location filename="../components/TitleBar.qml" line="38"/> + <source>Monero - Donations</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>Transfer</name> <message> @@ -406,6 +455,21 @@ <source>Amount...</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Transfer.qml" line="96"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="97"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="98"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Transfer.qml" line="127"/> <source>Privacy Level</source> @@ -422,17 +486,17 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="193"/> + <location filename="../pages/Transfer.qml" line="194"/> <source>Payment ID <font size='2'>( Optional )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="217"/> + <location filename="../pages/Transfer.qml" line="218"/> <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="237"/> + <location filename="../pages/Transfer.qml" line="239"/> <source>SEND</source> <translation type="unfinished"></translation> </message> @@ -455,22 +519,22 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="126"/> + <location filename="../wizard/WizardConfigure.qml" line="127"/> <source>Enable disk conservation mode?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="144"/> + <location filename="../wizard/WizardConfigure.qml" line="145"/> <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="156"/> + <location filename="../wizard/WizardConfigure.qml" line="158"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="174"/> + <location filename="../wizard/WizardConfigure.qml" line="176"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -511,12 +575,12 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardDonation.qml" line="175"/> + <location filename="../wizard/WizardDonation.qml" line="176"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardDonation.qml" line="193"/> + <location filename="../wizard/WizardDonation.qml" line="194"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -559,12 +623,12 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="51"/> + <location filename="../wizard/WizardFinish.qml" line="52"/> <source>An overview of your Monero configuration is below:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="102"/> + <location filename="../wizard/WizardFinish.qml" line="103"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -604,6 +668,11 @@ <source>Your wallet is stored in</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../wizard/WizardManageWalletUI.qml" line="187"/> + <source>Please choose a directory</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>WizardMemoTextInput</name> @@ -681,7 +750,7 @@ <message> <location filename="../main.qml" line="148"/> <location filename="../main.qml" line="203"/> - <location filename="../main.qml" line="232"/> + <location filename="../main.qml" line="233"/> <source>Error</source> <translation type="unfinished"></translation> </message> @@ -732,24 +801,39 @@ Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="233"/> + <location filename="../main.qml" line="234"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="236"/> + <location filename="../main.qml" line="237"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="237"/> + <location filename="../main.qml" line="238"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="309"/> + <location filename="../main.qml" line="310"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../main.qml" line="336"/> + <source>Program setup wizard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="350"/> + <source>Monero - Donations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="389"/> + <source>send to the same destination</source> + <translation type="unfinished"></translation> + </message> </context> </TS> diff --git a/translations/monero-core_pl.ts b/translations/monero-core_pl.ts index 6c15a0b0..a3496ddb 100644 --- a/translations/monero-core_pl.ts +++ b/translations/monero-core_pl.ts @@ -10,6 +10,7 @@ </message> <message> <location filename="../pages/AddressBook.qml" line="56"/> + <location filename="../pages/AddressBook.qml" line="173"/> <source>Address</source> <translation type="unfinished"></translation> </message> @@ -29,20 +30,30 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="98"/> + <location filename="../pages/AddressBook.qml" line="99"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="100"/> + <location filename="../pages/AddressBook.qml" line="101"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="125"/> + <location filename="../pages/AddressBook.qml" line="126"/> <source>ADD</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/AddressBook.qml" line="174"/> + <source>Payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/AddressBook.qml" line="175"/> + <source>Description</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>AddressBookTable</name> @@ -160,11 +171,11 @@ </message> <message> <location filename="../pages/History.qml" line="58"/> - <location filename="../pages/History.qml" line="122"/> - <location filename="../pages/History.qml" line="142"/> - <location filename="../pages/History.qml" line="190"/> - <location filename="../pages/History.qml" line="224"/> - <location filename="../pages/History.qml" line="245"/> + <location filename="../pages/History.qml" line="123"/> + <location filename="../pages/History.qml" line="143"/> + <location filename="../pages/History.qml" line="191"/> + <location filename="../pages/History.qml" line="225"/> + <location filename="../pages/History.qml" line="246"/> <source><b>Tip tekst test</b></source> <translation type="unfinished"></translation> </message> @@ -179,43 +190,43 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="98"/> + <location filename="../pages/History.qml" line="99"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="100"/> + <location filename="../pages/History.qml" line="101"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="120"/> + <location filename="../pages/History.qml" line="121"/> <source>Date from</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="140"/> - <location filename="../pages/History.qml" line="243"/> + <location filename="../pages/History.qml" line="141"/> + <location filename="../pages/History.qml" line="244"/> <source>To</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="160"/> + <location filename="../pages/History.qml" line="161"/> <source>FILTER</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="169"/> + <location filename="../pages/History.qml" line="170"/> <source>Advance filtering</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="188"/> + <location filename="../pages/History.qml" line="189"/> <source>Type of transation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="222"/> + <location filename="../pages/History.qml" line="223"/> <source>Amount from</source> <translation type="unfinished"></translation> </message> @@ -334,16 +345,31 @@ <source>Address</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="86"/> + <source>ReadOnly wallet address displayed here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="106"/> <source>Integrated address</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="115"/> + <source>ReadOnly wallet integrated address displayed here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="136"/> <source>Payment ID</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="144"/> + <source>PaymentID here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="168"/> <source>Generate</source> @@ -357,6 +383,21 @@ <source>Twitter</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../RightPanel.qml" line="59"/> + <source>News</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../RightPanel.qml" line="60"/> + <source>Help</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../RightPanel.qml" line="61"/> + <source>About</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>SearchInput</name> @@ -389,6 +430,14 @@ <translation type="unfinished"></translation> </message> </context> +<context> + <name>TitleBar</name> + <message> + <location filename="../components/TitleBar.qml" line="38"/> + <source>Monero - Donations</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>Transfer</name> <message> @@ -406,6 +455,21 @@ <source>Amount...</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Transfer.qml" line="96"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="97"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="98"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Transfer.qml" line="127"/> <source>Privacy Level</source> @@ -422,17 +486,17 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="193"/> + <location filename="../pages/Transfer.qml" line="194"/> <source>Payment ID <font size='2'>( Optional )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="217"/> + <location filename="../pages/Transfer.qml" line="218"/> <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="237"/> + <location filename="../pages/Transfer.qml" line="239"/> <source>SEND</source> <translation type="unfinished"></translation> </message> @@ -455,22 +519,22 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="126"/> + <location filename="../wizard/WizardConfigure.qml" line="127"/> <source>Enable disk conservation mode?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="144"/> + <location filename="../wizard/WizardConfigure.qml" line="145"/> <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="156"/> + <location filename="../wizard/WizardConfigure.qml" line="158"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="174"/> + <location filename="../wizard/WizardConfigure.qml" line="176"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -511,12 +575,12 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardDonation.qml" line="175"/> + <location filename="../wizard/WizardDonation.qml" line="176"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardDonation.qml" line="193"/> + <location filename="../wizard/WizardDonation.qml" line="194"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -559,12 +623,12 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="51"/> + <location filename="../wizard/WizardFinish.qml" line="52"/> <source>An overview of your Monero configuration is below:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="102"/> + <location filename="../wizard/WizardFinish.qml" line="103"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -604,6 +668,11 @@ <source>Your wallet is stored in</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../wizard/WizardManageWalletUI.qml" line="187"/> + <source>Please choose a directory</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>WizardMemoTextInput</name> @@ -681,7 +750,7 @@ <message> <location filename="../main.qml" line="148"/> <location filename="../main.qml" line="203"/> - <location filename="../main.qml" line="232"/> + <location filename="../main.qml" line="233"/> <source>Error</source> <translation type="unfinished"></translation> </message> @@ -732,24 +801,39 @@ Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="233"/> + <location filename="../main.qml" line="234"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="236"/> + <location filename="../main.qml" line="237"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="237"/> + <location filename="../main.qml" line="238"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="309"/> + <location filename="../main.qml" line="310"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../main.qml" line="336"/> + <source>Program setup wizard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="350"/> + <source>Monero - Donations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="389"/> + <source>send to the same destination</source> + <translation type="unfinished"></translation> + </message> </context> </TS> diff --git a/translations/monero-core_ru.ts b/translations/monero-core_ru.ts index 7921567d..29bf9b7f 100644 --- a/translations/monero-core_ru.ts +++ b/translations/monero-core_ru.ts @@ -10,6 +10,7 @@ </message> <message> <location filename="../pages/AddressBook.qml" line="56"/> + <location filename="../pages/AddressBook.qml" line="173"/> <source>Address</source> <translation type="unfinished"></translation> </message> @@ -29,20 +30,30 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="98"/> + <location filename="../pages/AddressBook.qml" line="99"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="100"/> + <location filename="../pages/AddressBook.qml" line="101"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="125"/> + <location filename="../pages/AddressBook.qml" line="126"/> <source>ADD</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/AddressBook.qml" line="174"/> + <source>Payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/AddressBook.qml" line="175"/> + <source>Description</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>AddressBookTable</name> @@ -160,11 +171,11 @@ </message> <message> <location filename="../pages/History.qml" line="58"/> - <location filename="../pages/History.qml" line="122"/> - <location filename="../pages/History.qml" line="142"/> - <location filename="../pages/History.qml" line="190"/> - <location filename="../pages/History.qml" line="224"/> - <location filename="../pages/History.qml" line="245"/> + <location filename="../pages/History.qml" line="123"/> + <location filename="../pages/History.qml" line="143"/> + <location filename="../pages/History.qml" line="191"/> + <location filename="../pages/History.qml" line="225"/> + <location filename="../pages/History.qml" line="246"/> <source><b>Tip tekst test</b></source> <translation type="unfinished"></translation> </message> @@ -179,43 +190,43 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="98"/> + <location filename="../pages/History.qml" line="99"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="100"/> + <location filename="../pages/History.qml" line="101"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="120"/> + <location filename="../pages/History.qml" line="121"/> <source>Date from</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="140"/> - <location filename="../pages/History.qml" line="243"/> + <location filename="../pages/History.qml" line="141"/> + <location filename="../pages/History.qml" line="244"/> <source>To</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="160"/> + <location filename="../pages/History.qml" line="161"/> <source>FILTER</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="169"/> + <location filename="../pages/History.qml" line="170"/> <source>Advance filtering</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="188"/> + <location filename="../pages/History.qml" line="189"/> <source>Type of transation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="222"/> + <location filename="../pages/History.qml" line="223"/> <source>Amount from</source> <translation type="unfinished"></translation> </message> @@ -334,16 +345,31 @@ <source>Address</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="86"/> + <source>ReadOnly wallet address displayed here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="106"/> <source>Integrated address</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="115"/> + <source>ReadOnly wallet integrated address displayed here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="136"/> <source>Payment ID</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="144"/> + <source>PaymentID here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="168"/> <source>Generate</source> @@ -357,6 +383,21 @@ <source>Twitter</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../RightPanel.qml" line="59"/> + <source>News</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../RightPanel.qml" line="60"/> + <source>Help</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../RightPanel.qml" line="61"/> + <source>About</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>SearchInput</name> @@ -389,6 +430,14 @@ <translation type="unfinished"></translation> </message> </context> +<context> + <name>TitleBar</name> + <message> + <location filename="../components/TitleBar.qml" line="38"/> + <source>Monero - Donations</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>Transfer</name> <message> @@ -406,6 +455,21 @@ <source>Amount...</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Transfer.qml" line="96"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="97"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="98"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Transfer.qml" line="127"/> <source>Privacy Level</source> @@ -422,17 +486,17 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="193"/> + <location filename="../pages/Transfer.qml" line="194"/> <source>Payment ID <font size='2'>( Optional )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="217"/> + <location filename="../pages/Transfer.qml" line="218"/> <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="237"/> + <location filename="../pages/Transfer.qml" line="239"/> <source>SEND</source> <translation type="unfinished"></translation> </message> @@ -455,22 +519,22 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="126"/> + <location filename="../wizard/WizardConfigure.qml" line="127"/> <source>Enable disk conservation mode?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="144"/> + <location filename="../wizard/WizardConfigure.qml" line="145"/> <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="156"/> + <location filename="../wizard/WizardConfigure.qml" line="158"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="174"/> + <location filename="../wizard/WizardConfigure.qml" line="176"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -511,12 +575,12 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardDonation.qml" line="175"/> + <location filename="../wizard/WizardDonation.qml" line="176"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardDonation.qml" line="193"/> + <location filename="../wizard/WizardDonation.qml" line="194"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -559,12 +623,12 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="51"/> + <location filename="../wizard/WizardFinish.qml" line="52"/> <source>An overview of your Monero configuration is below:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="102"/> + <location filename="../wizard/WizardFinish.qml" line="103"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -604,6 +668,11 @@ <source>Your wallet is stored in</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../wizard/WizardManageWalletUI.qml" line="187"/> + <source>Please choose a directory</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>WizardMemoTextInput</name> @@ -681,7 +750,7 @@ <message> <location filename="../main.qml" line="148"/> <location filename="../main.qml" line="203"/> - <location filename="../main.qml" line="232"/> + <location filename="../main.qml" line="233"/> <source>Error</source> <translation type="unfinished"></translation> </message> @@ -732,24 +801,39 @@ Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="233"/> + <location filename="../main.qml" line="234"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="236"/> + <location filename="../main.qml" line="237"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="237"/> + <location filename="../main.qml" line="238"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="309"/> + <location filename="../main.qml" line="310"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../main.qml" line="336"/> + <source>Program setup wizard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="350"/> + <source>Monero - Donations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="389"/> + <source>send to the same destination</source> + <translation type="unfinished"></translation> + </message> </context> </TS> diff --git a/translations/monero-core_zh.ts b/translations/monero-core_zh.ts index 0a2faf01..e5e60dab 100644 --- a/translations/monero-core_zh.ts +++ b/translations/monero-core_zh.ts @@ -10,6 +10,7 @@ </message> <message> <location filename="../pages/AddressBook.qml" line="56"/> + <location filename="../pages/AddressBook.qml" line="173"/> <source>Address</source> <translation type="unfinished"></translation> </message> @@ -29,20 +30,30 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="98"/> + <location filename="../pages/AddressBook.qml" line="99"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="100"/> + <location filename="../pages/AddressBook.qml" line="101"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/AddressBook.qml" line="125"/> + <location filename="../pages/AddressBook.qml" line="126"/> <source>ADD</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/AddressBook.qml" line="174"/> + <source>Payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/AddressBook.qml" line="175"/> + <source>Description</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>AddressBookTable</name> @@ -160,11 +171,11 @@ </message> <message> <location filename="../pages/History.qml" line="58"/> - <location filename="../pages/History.qml" line="122"/> - <location filename="../pages/History.qml" line="142"/> - <location filename="../pages/History.qml" line="190"/> - <location filename="../pages/History.qml" line="224"/> - <location filename="../pages/History.qml" line="245"/> + <location filename="../pages/History.qml" line="123"/> + <location filename="../pages/History.qml" line="143"/> + <location filename="../pages/History.qml" line="191"/> + <location filename="../pages/History.qml" line="225"/> + <location filename="../pages/History.qml" line="246"/> <source><b>Tip tekst test</b></source> <translation type="unfinished"></translation> </message> @@ -179,43 +190,43 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="98"/> + <location filename="../pages/History.qml" line="99"/> <source>Description <font size='2'>(Local database)</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="100"/> + <location filename="../pages/History.qml" line="101"/> <source><b>Tip tekst test</b><br/><br/>test line 2</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="120"/> + <location filename="../pages/History.qml" line="121"/> <source>Date from</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="140"/> - <location filename="../pages/History.qml" line="243"/> + <location filename="../pages/History.qml" line="141"/> + <location filename="../pages/History.qml" line="244"/> <source>To</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="160"/> + <location filename="../pages/History.qml" line="161"/> <source>FILTER</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="169"/> + <location filename="../pages/History.qml" line="170"/> <source>Advance filtering</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="188"/> + <location filename="../pages/History.qml" line="189"/> <source>Type of transation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/History.qml" line="222"/> + <location filename="../pages/History.qml" line="223"/> <source>Amount from</source> <translation type="unfinished"></translation> </message> @@ -334,16 +345,31 @@ <source>Address</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="86"/> + <source>ReadOnly wallet address displayed here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="106"/> <source>Integrated address</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="115"/> + <source>ReadOnly wallet integrated address displayed here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="136"/> <source>Payment ID</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Receive.qml" line="144"/> + <source>PaymentID here</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Receive.qml" line="168"/> <source>Generate</source> @@ -357,6 +383,21 @@ <source>Twitter</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../RightPanel.qml" line="59"/> + <source>News</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../RightPanel.qml" line="60"/> + <source>Help</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../RightPanel.qml" line="61"/> + <source>About</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>SearchInput</name> @@ -389,6 +430,14 @@ <translation type="unfinished"></translation> </message> </context> +<context> + <name>TitleBar</name> + <message> + <location filename="../components/TitleBar.qml" line="38"/> + <source>Monero - Donations</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>Transfer</name> <message> @@ -406,6 +455,21 @@ <source>Amount...</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../pages/Transfer.qml" line="96"/> + <source>LOW</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="97"/> + <source>MEDIUM</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../pages/Transfer.qml" line="98"/> + <source>HIGH</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../pages/Transfer.qml" line="127"/> <source>Privacy Level</source> @@ -422,17 +486,17 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="193"/> + <location filename="../pages/Transfer.qml" line="194"/> <source>Payment ID <font size='2'>( Optional )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="217"/> + <location filename="../pages/Transfer.qml" line="218"/> <source>Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../pages/Transfer.qml" line="237"/> + <location filename="../pages/Transfer.qml" line="239"/> <source>SEND</source> <translation type="unfinished"></translation> </message> @@ -455,22 +519,22 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="126"/> + <location filename="../wizard/WizardConfigure.qml" line="127"/> <source>Enable disk conservation mode?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="144"/> + <location filename="../wizard/WizardConfigure.qml" line="145"/> <source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="156"/> + <location filename="../wizard/WizardConfigure.qml" line="158"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardConfigure.qml" line="174"/> + <location filename="../wizard/WizardConfigure.qml" line="176"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -511,12 +575,12 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardDonation.qml" line="175"/> + <location filename="../wizard/WizardDonation.qml" line="176"/> <source>Allow background mining?</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardDonation.qml" line="193"/> + <location filename="../wizard/WizardDonation.qml" line="194"/> <source>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.</source> <translation type="unfinished"></translation> </message> @@ -559,12 +623,12 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="51"/> + <location filename="../wizard/WizardFinish.qml" line="52"/> <source>An overview of your Monero configuration is below:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="102"/> + <location filename="../wizard/WizardFinish.qml" line="103"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -604,6 +668,11 @@ <source>Your wallet is stored in</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../wizard/WizardManageWalletUI.qml" line="187"/> + <source>Please choose a directory</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>WizardMemoTextInput</name> @@ -681,7 +750,7 @@ <message> <location filename="../main.qml" line="148"/> <location filename="../main.qml" line="203"/> - <location filename="../main.qml" line="232"/> + <location filename="../main.qml" line="233"/> <source>Error</source> <translation type="unfinished"></translation> </message> @@ -732,24 +801,39 @@ Fee: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="233"/> + <location filename="../main.qml" line="234"/> <source>Couldn't send the money: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="236"/> + <location filename="../main.qml" line="237"/> <source>Information</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="237"/> + <location filename="../main.qml" line="238"/> <source>Money sent successfully</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.qml" line="309"/> + <location filename="../main.qml" line="310"/> <source>Initializing Wallet...</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../main.qml" line="336"/> + <source>Program setup wizard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="350"/> + <source>Monero - Donations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../main.qml" line="389"/> + <source>send to the same destination</source> + <translation type="unfinished"></translation> + </message> </context> </TS> diff --git a/wizard/WizardConfigure.qml b/wizard/WizardConfigure.qml index acfae0bd..343f9c88 100644 --- a/wizard/WizardConfigure.qml +++ b/wizard/WizardConfigure.qml @@ -76,7 +76,7 @@ Item { wrapMode: Text.Wrap //renderType: Text.NativeRendering color: "#3F3F3F" - text: qsTr("We’re almost there - let’s just configure some Monero preferences") + text: qsTr("We’re almost there - let’s just configure some Monero preferences") + translationManager.emptyString } Column { @@ -94,7 +94,7 @@ Item { spacing: 12 CheckBox { - text: qsTr("Kickstart the Monero blockchain?") + text: qsTr("Kickstart the Monero blockchain?") + translationManager.emptyString anchors.left: parent.left anchors.right: parent.right background: "#F0EEEE" @@ -114,6 +114,7 @@ Item { wrapMode: Text.Wrap text: qsTr("It is very important to write it down as this is the only backup you will need for your wallet. " + "You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.") + + translationManager.emptyString } } @@ -123,7 +124,7 @@ Item { spacing: 12 CheckBox { - text: qsTr("Enable disk conservation mode?") + text: qsTr("Enable disk conservation mode?") + translationManager.emptyString anchors.left: parent.left anchors.right: parent.right background: "#F0EEEE" @@ -144,6 +145,7 @@ Item { text: qsTr("Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as " + "a regular Monero instance. However, storing the full blockchain is beneficial to the security " + "of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.") + + translationManager.emptyString } } @@ -153,7 +155,7 @@ Item { spacing: 12 CheckBox { - text: qsTr("Allow background mining?") + text: qsTr("Allow background mining?") + translationManager.emptyString anchors.left: parent.left anchors.right: parent.right background: "#F0EEEE" @@ -173,6 +175,7 @@ Item { 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.") + + translationManager.emptyString } } } diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml index d39d52d2..2181a359 100644 --- a/wizard/WizardCreateWallet.qml +++ b/wizard/WizardCreateWallet.qml @@ -78,8 +78,8 @@ Item { WizardManageWalletUI { id: uiItem - titleText: qsTr("A new wallet has been created for you") - wordsTextTitle: qsTr("This is the 25 word mnemonic for your wallet") + titleText: qsTr("A new wallet has been created for you") + translationManager.emptyString + wordsTextTitle: qsTr("This is the 25 word mnemonic for your wallet") + translationManager.emptyString wordsTextItem.clipboardButtonVisible: true wordsTextItem.tipTextVisible: true wordsTextItem.memoTextReadOnly: true diff --git a/wizard/WizardDonation.qml b/wizard/WizardDonation.qml index 80ebd78b..57e03524 100644 --- a/wizard/WizardDonation.qml +++ b/wizard/WizardDonation.qml @@ -90,7 +90,7 @@ Item { wrapMode: Text.Wrap //renderType: Text.NativeRendering color: "#3F3F3F" - text: qsTr("Monero development is solely supported by donations") + text: qsTr("Monero development is solely supported by donations") + translationManager.emptyString } Column { @@ -110,7 +110,7 @@ Item { CheckBox { id: enableAutoDonationCheckBox anchors.verticalCenter: parent.verticalCenter - text: qsTr("Enable auto-donations of?") + text: qsTr("Enable auto-donations of?") + translationManager.emptyString background: "#F0EEEE" fontColor: "#4A4646" fontSize: 18 @@ -150,7 +150,7 @@ Item { font.family: "Arial" font.pixelSize: 18 color: "#4A4646" - text: qsTr("% of my fee added to each transaction") + text: qsTr("% of my fee added to each transaction") + translationManager.emptyString } } @@ -164,6 +164,7 @@ Item { text: qsTr("For every transaction, a small transaction fee is charged. This option lets you add an additional amount, " + "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.") + + translationManager.emptyString } Column { anchors.left: parent.left @@ -172,7 +173,7 @@ Item { CheckBox { id: allowBackgroundMiningCheckBox - text: qsTr("Allow background mining?") + text: qsTr("Allow background mining?") + translationManager.emptyString anchors.left: parent.left anchors.right: parent.right background: "#F0EEEE" @@ -192,6 +193,7 @@ Item { 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.") + + translationManager.emptyString } } } diff --git a/wizard/WizardFinish.qml b/wizard/WizardFinish.qml index 427a2340..7c9c89e7 100644 --- a/wizard/WizardFinish.qml +++ b/wizard/WizardFinish.qml @@ -45,10 +45,11 @@ Item { + 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>" + + translationManager.emptyString return str; } function updateSettingsSummary() { - settingsText.text = qsTr("An overview of your Monero configuration is below:") + settingsText.text = qsTr("An overview of your Monero configuration is below:") + translationManager.emptyString + "<br>" + buildSettingsString(); } @@ -99,7 +100,7 @@ Item { horizontalAlignment: Text.AlignHCenter //renderType: Text.NativeRendering color: "#3F3F3F" - text: qsTr("You’re all setup!") + text: qsTr("You’re all setup!") + translationManager.emptyString } Text { diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index 987ac897..1103c2ff 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -82,9 +82,9 @@ Rectangle { // disable "next" button until passwords match nextButton.enabled = passwordPage.passwordValid; if (currentPath === "create_wallet") { - passwordPage.titleText = qsTr("Now that your wallet has been created, please set a password for the wallet") + passwordPage.titleText = qsTr("Now that your wallet has been created, please set a password for the wallet") + translationManager.emptyString } else { - passwordPage.titleText = qsTr("Now that your wallet has been restored, please set a password for the wallet") + passwordPage.titleText = qsTr("Now that your wallet has been restored, please set a password for the wallet") + translationManager.emptyString } break; case finishPage: @@ -306,7 +306,7 @@ Rectangle { anchors.bottom: parent.bottom anchors.margins: 50 width: 110 - text: qsTr("USE MONERO") + text: qsTr("USE MONERO") + translationManager.emptyString shadowReleasedColor: "#FF4304" shadowPressedColor: "#B32D00" releasedColor: "#FF6C3C" diff --git a/wizard/WizardManageWalletUI.qml b/wizard/WizardManageWalletUI.qml index 58f4e59a..a11ee094 100644 --- a/wizard/WizardManageWalletUI.qml +++ b/wizard/WizardManageWalletUI.qml @@ -100,7 +100,7 @@ Item { horizontalAlignment: Text.AlignHCenter //renderType: Text.NativeRendering color: "#4A4646" - text: qsTr("This is the name of your wallet. You can change it to a different name if you’d like:") + text: qsTr("This is the name of your wallet. You can change it to a different name if you’d like:") + translationManager.emptyString } } @@ -122,7 +122,7 @@ Item { renderType: Text.NativeRendering color: "#FF6C3C" focus: true - text: qsTr("My account name") + text: qsTr("My account name") + translationManager.emptyString } Rectangle { @@ -172,7 +172,7 @@ Item { font.pixelSize: 18 //renderType: Text.NativeRendering color: "#4A4646" - text: qsTr("Your wallet is stored in") + text: qsTr("Your wallet is stored in") + translationManager.emptyString } Item { @@ -184,7 +184,7 @@ Item { id: fileDialog selectMultiple: false selectFolder: true - title: "Please choose a directory" + title: qsTr("Please choose a directory") + translationManager.emptyString onAccepted: { fileUrlInput.text = fileDialog.folder fileDialog.visible = false diff --git a/wizard/WizardMemoTextInput.qml b/wizard/WizardMemoTextInput.qml index 39f9211b..9497d9e5 100644 --- a/wizard/WizardMemoTextInput.qml +++ b/wizard/WizardMemoTextInput.qml @@ -74,6 +74,7 @@ Column { color: "#4A4646" wrapMode: Text.Wrap text: qsTr("It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.") + + translationManager.emptyString } } } diff --git a/wizard/WizardOptions.qml b/wizard/WizardOptions.qml index 621cac78..7aa3be2f 100644 --- a/wizard/WizardOptions.qml +++ b/wizard/WizardOptions.qml @@ -59,7 +59,7 @@ Item { color: "#3F3F3F" wrapMode: Text.Wrap horizontalAlignment: Text.AlignHCenter - text: qsTr("Welcome to Monero!") + text: qsTr("Welcome to Monero!") + translationManager.emptyString } Text { @@ -71,7 +71,7 @@ Item { color: "#4A4646" wrapMode: Text.Wrap horizontalAlignment: Text.AlignHCenter - text: qsTr("Please select one of the following options:") + text: qsTr("Please select one of the following options:") + translationManager.emptyString } } @@ -107,7 +107,7 @@ Item { font.pixelSize: 16 color: "#4A4949" horizontalAlignment: Text.AlignHCenter - text: qsTr("This is my first time, I want to<br/>create a new account") + text: qsTr("This is my first time, I want to<br/>create a new account") + translationManager.emptyString } } @@ -138,7 +138,7 @@ Item { font.pixelSize: 16 color: "#4A4949" horizontalAlignment: Text.AlignHCenter - 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") + translationManager.emptyString } } } diff --git a/wizard/WizardPassword.qml b/wizard/WizardPassword.qml index 4825c02d..0e79d57c 100644 --- a/wizard/WizardPassword.qml +++ b/wizard/WizardPassword.qml @@ -120,6 +120,7 @@ Item { horizontalAlignment: Text.AlignHCenter text: qsTr("Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.") + + translationManager.emptyString } } diff --git a/wizard/WizardRecoveryWallet.qml b/wizard/WizardRecoveryWallet.qml index aded7661..972ee6a1 100644 --- a/wizard/WizardRecoveryWallet.qml +++ b/wizard/WizardRecoveryWallet.qml @@ -66,9 +66,9 @@ Item { WizardManageWalletUI { id: uiItem - accountNameText: qsTr("My account name") - titleText: qsTr("We're ready to recover your account") - wordsTextTitle: qsTr("Please enter your 25 word private key") + accountNameText: qsTr("My account name") + translationManager.emptyString + titleText: qsTr("We're ready to recover your account") + translationManager.emptyString + wordsTextTitle: qsTr("Please enter your 25 word private key") + translationManager.emptyString wordsTextItem.clipboardButtonVisible: false wordsTextItem.tipTextVisible: false wordsTextItem.memoTextReadOnly: false diff --git a/wizard/utils.js b/wizard/utils.js index 6d16951d..0cc910c6 100644 --- a/wizard/utils.js +++ b/wizard/utils.js @@ -37,3 +37,8 @@ function mapScope (inputScopeFrom, inputScopeTo, outputScopeFrom, outputScopeTo, var result = outputScopeFrom + ((outputScopeTo - outputScopeFrom) * x); return result; } + + +function tr(text) { + return qsTr(text) + translationManager.emptyString +} From ecf844120b62e688e0527316d8f1322bfea06fe0 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Thu, 21 Jul 2016 12:47:53 +0300 Subject: [PATCH 55/87] cleaning "auto-generated" bitmonero directory on "make clean". closes #22 --- monero-core.pro | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/monero-core.pro b/monero-core.pro index a5b170e5..877019d0 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -6,10 +6,14 @@ WALLET_ROOT=$$PWD/bitmonero CONFIG += c++11 +# cleaning "auto-generated" bitmonero directory on "make clean" +QMAKE_CLEAN += -r $$WALLET_ROOT + INCLUDEPATH += $$WALLET_ROOT/include \ $$PWD/src/libwalletqt + HEADERS += \ filter.h \ clipboardAdapter.h \ From e5d5a6082fdcacfd9f1de1b2144101e705f2d322 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Thu, 21 Jul 2016 13:56:17 +0300 Subject: [PATCH 56/87] Wizard refactoring --- translations/monero-core_de.ts | 36 ++++++++++----------- translations/monero-core_en.ts | 36 ++++++++++----------- translations/monero-core_it.ts | 36 ++++++++++----------- translations/monero-core_pl.ts | 36 ++++++++++----------- translations/monero-core_ru.ts | 36 ++++++++++----------- translations/monero-core_zh.ts | 36 ++++++++++----------- wizard/WizardCreateWallet.qml | 9 ++++++ wizard/WizardFinish.qml | 4 +++ wizard/WizardMain.qml | 57 ++++++++++++++++----------------- wizard/WizardPassword.qml | 22 +++++++++++-- wizard/WizardRecoveryWallet.qml | 12 +++++-- 11 files changed, 179 insertions(+), 141 deletions(-) diff --git a/translations/monero-core_de.ts b/translations/monero-core_de.ts index ea08d710..24e76b60 100644 --- a/translations/monero-core_de.ts +++ b/translations/monero-core_de.ts @@ -542,12 +542,12 @@ <context> <name>WizardCreateWallet</name> <message> - <location filename="../wizard/WizardCreateWallet.qml" line="81"/> + <location filename="../wizard/WizardCreateWallet.qml" line="90"/> <source>A new wallet has been created for you</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardCreateWallet.qml" line="82"/> + <location filename="../wizard/WizardCreateWallet.qml" line="91"/> <source>This is the 25 word mnemonic for your wallet</source> <translation type="unfinished"></translation> </message> @@ -628,7 +628,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="103"/> + <location filename="../wizard/WizardFinish.qml" line="107"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -636,17 +636,7 @@ <context> <name>WizardMain</name> <message> - <location filename="../wizard/WizardMain.qml" line="85"/> - <source>Now that your wallet has been created, please set a password for the wallet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../wizard/WizardMain.qml" line="87"/> - <source>Now that your wallet has been restored, please set a password for the wallet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../wizard/WizardMain.qml" line="309"/> + <location filename="../wizard/WizardMain.qml" line="308"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -708,7 +698,17 @@ <context> <name>WizardPassword</name> <message> - <location filename="../wizard/WizardPassword.qml" line="121"/> + <location filename="../wizard/WizardPassword.qml" line="51"/> + <source>Now that your wallet has been created, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardPassword.qml" line="53"/> + <source>Now that your wallet has been restored, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardPassword.qml" line="135"/> <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> <translation type="unfinished"></translation> @@ -717,17 +717,17 @@ <context> <name>WizardRecoveryWallet</name> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="69"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="78"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="70"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="79"/> <source>We're ready to recover your account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="71"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="80"/> <source>Please enter your 25 word private key</source> <translation type="unfinished"></translation> </message> diff --git a/translations/monero-core_en.ts b/translations/monero-core_en.ts index dca4c577..6e8d5bcc 100644 --- a/translations/monero-core_en.ts +++ b/translations/monero-core_en.ts @@ -542,12 +542,12 @@ <context> <name>WizardCreateWallet</name> <message> - <location filename="../wizard/WizardCreateWallet.qml" line="81"/> + <location filename="../wizard/WizardCreateWallet.qml" line="90"/> <source>A new wallet has been created for you</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardCreateWallet.qml" line="82"/> + <location filename="../wizard/WizardCreateWallet.qml" line="91"/> <source>This is the 25 word mnemonic for your wallet</source> <translation type="unfinished"></translation> </message> @@ -628,7 +628,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="103"/> + <location filename="../wizard/WizardFinish.qml" line="107"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -636,17 +636,7 @@ <context> <name>WizardMain</name> <message> - <location filename="../wizard/WizardMain.qml" line="85"/> - <source>Now that your wallet has been created, please set a password for the wallet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../wizard/WizardMain.qml" line="87"/> - <source>Now that your wallet has been restored, please set a password for the wallet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../wizard/WizardMain.qml" line="309"/> + <location filename="../wizard/WizardMain.qml" line="308"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -708,7 +698,17 @@ <context> <name>WizardPassword</name> <message> - <location filename="../wizard/WizardPassword.qml" line="121"/> + <location filename="../wizard/WizardPassword.qml" line="51"/> + <source>Now that your wallet has been created, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardPassword.qml" line="53"/> + <source>Now that your wallet has been restored, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardPassword.qml" line="135"/> <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> <translation type="unfinished"></translation> @@ -717,17 +717,17 @@ <context> <name>WizardRecoveryWallet</name> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="69"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="78"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="70"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="79"/> <source>We're ready to recover your account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="71"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="80"/> <source>Please enter your 25 word private key</source> <translation type="unfinished"></translation> </message> diff --git a/translations/monero-core_it.ts b/translations/monero-core_it.ts index 2c9c4b78..403d3859 100644 --- a/translations/monero-core_it.ts +++ b/translations/monero-core_it.ts @@ -542,12 +542,12 @@ <context> <name>WizardCreateWallet</name> <message> - <location filename="../wizard/WizardCreateWallet.qml" line="81"/> + <location filename="../wizard/WizardCreateWallet.qml" line="90"/> <source>A new wallet has been created for you</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardCreateWallet.qml" line="82"/> + <location filename="../wizard/WizardCreateWallet.qml" line="91"/> <source>This is the 25 word mnemonic for your wallet</source> <translation type="unfinished"></translation> </message> @@ -628,7 +628,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="103"/> + <location filename="../wizard/WizardFinish.qml" line="107"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -636,17 +636,7 @@ <context> <name>WizardMain</name> <message> - <location filename="../wizard/WizardMain.qml" line="85"/> - <source>Now that your wallet has been created, please set a password for the wallet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../wizard/WizardMain.qml" line="87"/> - <source>Now that your wallet has been restored, please set a password for the wallet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../wizard/WizardMain.qml" line="309"/> + <location filename="../wizard/WizardMain.qml" line="308"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -708,7 +698,17 @@ <context> <name>WizardPassword</name> <message> - <location filename="../wizard/WizardPassword.qml" line="121"/> + <location filename="../wizard/WizardPassword.qml" line="51"/> + <source>Now that your wallet has been created, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardPassword.qml" line="53"/> + <source>Now that your wallet has been restored, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardPassword.qml" line="135"/> <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> <translation type="unfinished"></translation> @@ -717,17 +717,17 @@ <context> <name>WizardRecoveryWallet</name> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="69"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="78"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="70"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="79"/> <source>We're ready to recover your account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="71"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="80"/> <source>Please enter your 25 word private key</source> <translation type="unfinished"></translation> </message> diff --git a/translations/monero-core_pl.ts b/translations/monero-core_pl.ts index a3496ddb..bb152986 100644 --- a/translations/monero-core_pl.ts +++ b/translations/monero-core_pl.ts @@ -542,12 +542,12 @@ <context> <name>WizardCreateWallet</name> <message> - <location filename="../wizard/WizardCreateWallet.qml" line="81"/> + <location filename="../wizard/WizardCreateWallet.qml" line="90"/> <source>A new wallet has been created for you</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardCreateWallet.qml" line="82"/> + <location filename="../wizard/WizardCreateWallet.qml" line="91"/> <source>This is the 25 word mnemonic for your wallet</source> <translation type="unfinished"></translation> </message> @@ -628,7 +628,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="103"/> + <location filename="../wizard/WizardFinish.qml" line="107"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -636,17 +636,7 @@ <context> <name>WizardMain</name> <message> - <location filename="../wizard/WizardMain.qml" line="85"/> - <source>Now that your wallet has been created, please set a password for the wallet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../wizard/WizardMain.qml" line="87"/> - <source>Now that your wallet has been restored, please set a password for the wallet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../wizard/WizardMain.qml" line="309"/> + <location filename="../wizard/WizardMain.qml" line="308"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -708,7 +698,17 @@ <context> <name>WizardPassword</name> <message> - <location filename="../wizard/WizardPassword.qml" line="121"/> + <location filename="../wizard/WizardPassword.qml" line="51"/> + <source>Now that your wallet has been created, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardPassword.qml" line="53"/> + <source>Now that your wallet has been restored, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardPassword.qml" line="135"/> <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> <translation type="unfinished"></translation> @@ -717,17 +717,17 @@ <context> <name>WizardRecoveryWallet</name> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="69"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="78"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="70"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="79"/> <source>We're ready to recover your account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="71"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="80"/> <source>Please enter your 25 word private key</source> <translation type="unfinished"></translation> </message> diff --git a/translations/monero-core_ru.ts b/translations/monero-core_ru.ts index 29bf9b7f..5ca9c499 100644 --- a/translations/monero-core_ru.ts +++ b/translations/monero-core_ru.ts @@ -542,12 +542,12 @@ <context> <name>WizardCreateWallet</name> <message> - <location filename="../wizard/WizardCreateWallet.qml" line="81"/> + <location filename="../wizard/WizardCreateWallet.qml" line="90"/> <source>A new wallet has been created for you</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardCreateWallet.qml" line="82"/> + <location filename="../wizard/WizardCreateWallet.qml" line="91"/> <source>This is the 25 word mnemonic for your wallet</source> <translation type="unfinished"></translation> </message> @@ -628,7 +628,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="103"/> + <location filename="../wizard/WizardFinish.qml" line="107"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -636,17 +636,7 @@ <context> <name>WizardMain</name> <message> - <location filename="../wizard/WizardMain.qml" line="85"/> - <source>Now that your wallet has been created, please set a password for the wallet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../wizard/WizardMain.qml" line="87"/> - <source>Now that your wallet has been restored, please set a password for the wallet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../wizard/WizardMain.qml" line="309"/> + <location filename="../wizard/WizardMain.qml" line="308"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -708,7 +698,17 @@ <context> <name>WizardPassword</name> <message> - <location filename="../wizard/WizardPassword.qml" line="121"/> + <location filename="../wizard/WizardPassword.qml" line="51"/> + <source>Now that your wallet has been created, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardPassword.qml" line="53"/> + <source>Now that your wallet has been restored, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardPassword.qml" line="135"/> <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> <translation type="unfinished"></translation> @@ -717,17 +717,17 @@ <context> <name>WizardRecoveryWallet</name> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="69"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="78"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="70"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="79"/> <source>We're ready to recover your account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="71"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="80"/> <source>Please enter your 25 word private key</source> <translation type="unfinished"></translation> </message> diff --git a/translations/monero-core_zh.ts b/translations/monero-core_zh.ts index e5e60dab..14f60021 100644 --- a/translations/monero-core_zh.ts +++ b/translations/monero-core_zh.ts @@ -542,12 +542,12 @@ <context> <name>WizardCreateWallet</name> <message> - <location filename="../wizard/WizardCreateWallet.qml" line="81"/> + <location filename="../wizard/WizardCreateWallet.qml" line="90"/> <source>A new wallet has been created for you</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardCreateWallet.qml" line="82"/> + <location filename="../wizard/WizardCreateWallet.qml" line="91"/> <source>This is the 25 word mnemonic for your wallet</source> <translation type="unfinished"></translation> </message> @@ -628,7 +628,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardFinish.qml" line="103"/> + <location filename="../wizard/WizardFinish.qml" line="107"/> <source>You’re all setup!</source> <translation type="unfinished"></translation> </message> @@ -636,17 +636,7 @@ <context> <name>WizardMain</name> <message> - <location filename="../wizard/WizardMain.qml" line="85"/> - <source>Now that your wallet has been created, please set a password for the wallet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../wizard/WizardMain.qml" line="87"/> - <source>Now that your wallet has been restored, please set a password for the wallet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../wizard/WizardMain.qml" line="309"/> + <location filename="../wizard/WizardMain.qml" line="308"/> <source>USE MONERO</source> <translation type="unfinished"></translation> </message> @@ -708,7 +698,17 @@ <context> <name>WizardPassword</name> <message> - <location filename="../wizard/WizardPassword.qml" line="121"/> + <location filename="../wizard/WizardPassword.qml" line="51"/> + <source>Now that your wallet has been created, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardPassword.qml" line="53"/> + <source>Now that your wallet has been restored, please set a password for the wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../wizard/WizardPassword.qml" line="135"/> <source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given<br/><br/> Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source> <translation type="unfinished"></translation> @@ -717,17 +717,17 @@ <context> <name>WizardRecoveryWallet</name> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="69"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="78"/> <source>My account name</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="70"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="79"/> <source>We're ready to recover your account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../wizard/WizardRecoveryWallet.qml" line="71"/> + <location filename="../wizard/WizardRecoveryWallet.qml" line="80"/> <source>Please enter your 25 word private key</source> <translation type="unfinished"></translation> </message> diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml index 2181a359..771a13ec 100644 --- a/wizard/WizardCreateWallet.qml +++ b/wizard/WizardCreateWallet.qml @@ -42,6 +42,10 @@ Item { //! function called each time we display this page + function onPageOpened(settingsOblect) { + checkNextButton() + } + function onPageClosed(settingsObject) { settingsObject['account_name'] = uiItem.accountNameText settingsObject['words'] = uiItem.wordsTexttext @@ -49,6 +53,11 @@ Item { return true; } + function checkNextButton() { + var wordsArray = cleanWordsInput(uiItem.wordsTextItem.memoText).split(" "); + wizard.nextButton.enabled = wordsArray.length === 25; + } + //! function called each time we hide this page // diff --git a/wizard/WizardFinish.qml b/wizard/WizardFinish.qml index 7c9c89e7..431b5a89 100644 --- a/wizard/WizardFinish.qml +++ b/wizard/WizardFinish.qml @@ -54,6 +54,10 @@ Item { + buildSettingsString(); } + function onPageOpened(settings) { + updateSettingsSummary(); + wizard.nextButton.visible = false; + } Row { diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index 1103c2ff..f0556efc 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -58,7 +58,7 @@ Rectangle { }; } - print ("switchpage: start: currentPage: ", currentPage); + print ("switchpage: currentPage: ", currentPage); if (currentPage > 0 || currentPage < pages.length - 1) { pages[currentPage].opacity = 0 @@ -66,40 +66,35 @@ Rectangle { currentPage += step_value pages[currentPage].opacity = 1; + var nextButtonVisible = pages[currentPage] !== optionsPage; + nextButton.visible = nextButtonVisible; + if (next && typeof pages[currentPage].onPageOpened !== 'undefined') { pages[currentPage].onPageOpened(settings) } - handlePageChanged(); + + + } } + // TODO: remove it function handlePageChanged() { - var nextButtonVisible = pages[currentPage] !== optionsPage; - nextButton.visible = nextButtonVisible; - print ("next button visible: " + nextButtonVisible); - switch (pages[currentPage]) { - case passwordPage: - // disable "next" button until passwords match - nextButton.enabled = passwordPage.passwordValid; - if (currentPath === "create_wallet") { - passwordPage.titleText = qsTr("Now that your wallet has been created, please set a password for the wallet") + translationManager.emptyString - } else { - passwordPage.titleText = qsTr("Now that your wallet has been restored, please set a password for the wallet") + translationManager.emptyString - } - break; - case finishPage: - // display settings summary - finishPage.updateSettingsSummary(); - nextButton.visible = false; - break; - case recoveryWalletPage: - // TODO: disable "next button" until 25 words private key entered - nextButton.enabled = false - break - default: - nextButton.enabled = true - } +// switch (pages[currentPage]) { +//// case finishPage: +//// // display settings summary +//// finishPage.updateSettingsSummary(); +//// nextButton.visible = false; +//// break; +// case recoveryWalletPage: +// // disable "next button" until 25 words private key entered +// nextButton.enabled = false +// break +// default: +// nextButton.enabled = true + +// } } @@ -111,7 +106,9 @@ Rectangle { pages = paths[currentPath] currentPage = pages.indexOf(createWalletPage) createWalletPage.createWallet(settings) - handlePageChanged() + wizard.nextButton.visible = true + createWalletPage.onPageOpened(settings); + } @@ -122,7 +119,9 @@ Rectangle { currentPath = "recovery_wallet" pages = paths[currentPath] currentPage = pages.indexOf(recoveryWalletPage) - handlePageChanged() + wizard.nextButton.visible = true + recoveryWalletPage.onPageOpened(settings); + } //! actually writes the wallet diff --git a/wizard/WizardPassword.qml b/wizard/WizardPassword.qml index 0e79d57c..8318a785 100644 --- a/wizard/WizardPassword.qml +++ b/wizard/WizardPassword.qml @@ -31,10 +31,10 @@ import "../components" import "utils.js" as Utils Item { + + id: passwordPage opacity: 0 visible: false - property bool passwordValid : passwordItem.password != '' - && passwordItem.password === retypePasswordItem.password property alias titleText: titleText.text Behavior on opacity { @@ -43,6 +43,17 @@ Item { onOpacityChanged: visible = opacity !== 0 + + function onPageOpened(settingsObject) { + wizard.nextButton.enabled = true + + if (wizard.currentPath === "create_wallet") { + passwordPage.titleText = qsTr("Now that your wallet has been created, please set a password for the wallet") + translationManager.emptyString + } else { + passwordPage.titleText = qsTr("Now that your wallet has been restored, please set a password for the wallet") + translationManager.emptyString + } + } + function onPageClosed(settingsObject) { // TODO: set password on the final page // settingsObject.wallet.setPassword(passwordItem.password) @@ -52,11 +63,14 @@ Item { function handlePassword() { // allow to forward step only if passwords match + wizard.nextButton.enabled = passwordItem.password === retypePasswordItem.password + // scorePassword returns value from 1..100 var strength = Utils.scorePassword(passwordItem.password) // privacyLevel component uses 1..13 scale privacyLevel.fillLevel = Utils.mapScope(1, 100, 1, 13, strength) + } @@ -155,4 +169,8 @@ Item { height: 62 onChanged: handlePassword() } + + Component.onCompleted: { + console.log + } } diff --git a/wizard/WizardRecoveryWallet.qml b/wizard/WizardRecoveryWallet.qml index 972ee6a1..2e6fe5f6 100644 --- a/wizard/WizardRecoveryWallet.qml +++ b/wizard/WizardRecoveryWallet.qml @@ -41,6 +41,15 @@ Item { onOpacityChanged: visible = opacity !== 0 + function onPageOpened(settingsObject) { + checkNextButton(); + } + + function checkNextButton() { + var wordsArray = cleanWordsInput(uiItem.wordsTextItem.memoText).split(" "); + wizard.nextButton.enabled = wordsArray.length === 25; + } + function onPageClosed(settingsObject) { settingsObject['account_name'] = uiItem.accountNameText settingsObject['words'] = cleanWordsInput(uiItem.wordsTextItem.memoText) @@ -74,8 +83,7 @@ Item { wordsTextItem.memoTextReadOnly: false wordsTextItem.memoText: "" wordsTextItem.onMemoTextChanged: { - var wordsArray = cleanWordsInput(wordsTextItem.memoText).split(" "); - wizard.nextButton.enabled = wordsArray.length === 25 + checkNextButton(); } } } From aa0ea18356ca2435aac7fd0d2ae8f9e638bdaa46 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.comm> Date: Thu, 21 Jul 2016 16:29:37 +0300 Subject: [PATCH 57/87] translation files moved to resources --- TranslationManager.cpp | 4 ++-- monero-core.pro | 7 ++++--- qml.qrc | 6 ++++++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/TranslationManager.cpp b/TranslationManager.cpp index 69448ce2..afd04ef6 100644 --- a/TranslationManager.cpp +++ b/TranslationManager.cpp @@ -25,8 +25,8 @@ bool TranslationManager::setLanguage(const QString &language) return true; } - // we expecting to have translation files in "i18n" directory - QString dir = qApp->applicationDirPath() + QDir::separator() + "i18n"; + // translations are compiled into app binary + QString dir = ":/translations"; QString filename = "monero-core_" + language; diff --git a/monero-core.pro b/monero-core.pro index 877019d0..0c24ea0d 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -90,8 +90,9 @@ linux { macx { LIBS+= \ - -lboost_serialization \ - -lboost_thread \ + -L/usr/local/lib \ + -lboost_serialization \ + -lboost_thread-mt \ -lboost_system \ -lboost_date_time \ -lboost_filesystem \ @@ -123,7 +124,7 @@ trans_update.depends = $$_PRO_FILE_ trans_release.commands = lrelease $$_PRO_FILE_ trans_release.depends = trans_update $$TRANSLATIONS -translate.commands = $(MKDIR) ${DESTDIR}/i18n && $(COPY) $$PWD/translations/*.qm ${DESTDIR}/i18n +#translate.commands = $(MKDIR) ${DESTDIR}/i18n && $(COPY) $$PWD/translations/*.qm ${DESTDIR}/i18n translate.depends = trans_release QMAKE_EXTRA_TARGETS += trans_update trans_release translate diff --git a/qml.qrc b/qml.qrc index eca9f561..152ea8f2 100644 --- a/qml.qrc +++ b/qml.qrc @@ -114,5 +114,11 @@ <file>pages/Receive.qml</file> <file>components/IconButton.qml</file> <file>lang/flags/italy.png</file> + <file>translations/monero-core_de.qm</file> + <file>translations/monero-core_en.qm</file> + <file>translations/monero-core_it.qm</file> + <file>translations/monero-core_pl.qm</file> + <file>translations/monero-core_ru.qm</file> + <file>translations/monero-core_zh.qm</file> </qresource> </RCC> From c7c06a5893f008e1118444297d2a331849444385 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.comm> Date: Fri, 22 Jul 2016 15:50:51 +0300 Subject: [PATCH 58/87] removing "bitmonero" directory in "distclean" target --- monero-core.pro | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/monero-core.pro b/monero-core.pro index 0c24ea0d..db5a618f 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -6,8 +6,8 @@ WALLET_ROOT=$$PWD/bitmonero CONFIG += c++11 -# cleaning "auto-generated" bitmonero directory on "make clean" -QMAKE_CLEAN += -r $$WALLET_ROOT +# cleaning "auto-generated" bitmonero directory on "make distclean" +QMAKE_DISTCLEAN += -r $$WALLET_ROOT INCLUDEPATH += $$WALLET_ROOT/include \ $$PWD/src/libwalletqt @@ -127,6 +127,8 @@ trans_release.depends = trans_update $$TRANSLATIONS #translate.commands = $(MKDIR) ${DESTDIR}/i18n && $(COPY) $$PWD/translations/*.qm ${DESTDIR}/i18n translate.depends = trans_release +deploy.commands = pushd $QMAKE_ + QMAKE_EXTRA_TARGETS += trans_update trans_release translate # updating transations only in release mode as this is requires to re-link project From 1b35a1ae4b01c05224fdc3b1acf70b7afdd6328c Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.comm> Date: Mon, 25 Jul 2016 16:24:07 +0300 Subject: [PATCH 59/87] build automation script. tested on macos --- build.sh | 28 ++++++++++++++++++++++++++++ monero-core.pro | 8 ++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100755 build.sh diff --git a/build.sh b/build.sh new file mode 100755 index 00000000..5cfea74d --- /dev/null +++ b/build.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +pushd $(pwd) +ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +#$SHELL get_libwallet_api.sh + +if [ ! -d build ]; then mkdir build; fi +cd build +echo $(pwd) +qmake ../monero-core.pro "CONFIG += release" +make release +make deploy +popd + + + + + + + + + + + + + + diff --git a/monero-core.pro b/monero-core.pro index db5a618f..0997d2bd 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -5,6 +5,7 @@ QT += qml quick widgets WALLET_ROOT=$$PWD/bitmonero CONFIG += c++11 +CONFIG += debug_and_release # cleaning "auto-generated" bitmonero directory on "make distclean" QMAKE_DISTCLEAN += -r $$WALLET_ROOT @@ -102,9 +103,12 @@ macx { -lssl \ -lcrypto \ -ldl + + deploy.commands += macdeployqt $$sprintf("%1/release/%2.app", $$OUT_PWD,$$TARGET) } +deploy.commands += # translations files; TRANSLATIONS = $$PWD/translations/monero-core_en.ts \ # English (could be untranslated) @@ -127,9 +131,9 @@ trans_release.depends = trans_update $$TRANSLATIONS #translate.commands = $(MKDIR) ${DESTDIR}/i18n && $(COPY) $$PWD/translations/*.qm ${DESTDIR}/i18n translate.depends = trans_release -deploy.commands = pushd $QMAKE_ -QMAKE_EXTRA_TARGETS += trans_update trans_release translate + +QMAKE_EXTRA_TARGETS += trans_update trans_release translate deploy # updating transations only in release mode as this is requires to re-link project # even if no changes were made. From 9cd73dfbbed6e200852ca9e1c1494ea3e5eae6c3 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 27 Jul 2016 22:32:33 +0300 Subject: [PATCH 60/87] Translations are separate qm files --- .gitignore | 1 + TranslationManager.cpp | 6 ++- build.sh | 9 +++-- main.cpp | 3 ++ monero-core.pro | 92 ++++++++++++++++++++++++------------------ qml.qrc | 6 --- 6 files changed, 68 insertions(+), 49 deletions(-) diff --git a/.gitignore b/.gitignore index a2ce1444..f2bec9c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.user *.user.* +translations/*.qm diff --git a/TranslationManager.cpp b/TranslationManager.cpp index afd04ef6..fa39d35a 100644 --- a/TranslationManager.cpp +++ b/TranslationManager.cpp @@ -26,7 +26,11 @@ bool TranslationManager::setLanguage(const QString &language) } // translations are compiled into app binary - QString dir = ":/translations"; +#ifdef Q_OS_MACX + QString dir = qApp->applicationDirPath() + "/../Resources/translations"; +#else + QString dir = qApp->applicationDirPath() + "/translations"; +#endif QString filename = "monero-core_" + language; diff --git a/build.sh b/build.sh index 5cfea74d..3c3260f5 100755 --- a/build.sh +++ b/build.sh @@ -2,14 +2,17 @@ pushd $(pwd) ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +BITMOMERO_DIR=bitmonero -#$SHELL get_libwallet_api.sh +if [ ! -d $BITMOMERO_DIR ]; then + $SHELL get_libwallet_api.sh +fi if [ ! -d build ]; then mkdir build; fi cd build echo $(pwd) -qmake ../monero-core.pro "CONFIG += release" -make release +qmake ../monero-core.pro "CONFIG+=release" +make make deploy popd diff --git a/main.cpp b/main.cpp index 030a21c3..9f109e01 100644 --- a/main.cpp +++ b/main.cpp @@ -30,6 +30,7 @@ #include <QQmlApplicationEngine> #include <QtQml> #include <QStandardPaths> +#include <QDebug> #include "clipboardAdapter.h" #include "filter.h" #include "oscursor.h" @@ -46,6 +47,8 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); + qDebug() << "app startd"; + app.setApplicationName("monero-core"); app.setOrganizationDomain("getmonero.org"); app.setOrganizationName("The Monero Project"); diff --git a/monero-core.pro b/monero-core.pro index 0997d2bd..668cecdb 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -5,7 +5,6 @@ QT += qml quick widgets WALLET_ROOT=$$PWD/bitmonero CONFIG += c++11 -CONFIG += debug_and_release # cleaning "auto-generated" bitmonero directory on "make distclean" QMAKE_DISTCLEAN += -r $$WALLET_ROOT @@ -13,8 +12,6 @@ QMAKE_DISTCLEAN += -r $$WALLET_ROOT INCLUDEPATH += $$WALLET_ROOT/include \ $$PWD/src/libwalletqt - - HEADERS += \ filter.h \ clipboardAdapter.h \ @@ -104,51 +101,59 @@ macx { -lcrypto \ -ldl - deploy.commands += macdeployqt $$sprintf("%1/release/%2.app", $$OUT_PWD,$$TARGET) } -deploy.commands += - -# translations files; -TRANSLATIONS = $$PWD/translations/monero-core_en.ts \ # English (could be untranslated) - $$PWD/translations/monero-core_de.ts \ # Deutsch - $$PWD/translations/monero-core_zh.ts \ # Chineese - $$PWD/translations/monero-core_ru.ts \ # Russian - $$PWD/translations/monero-core_it.ts \ # Italian - $$PWD/translations/monero-core_pl.ts \ # Polish - - - -# extra make targets for lupdate and lrelease invocation -# use "make lupdate" to update *.ts files and "make lrelease" to generate *.qm files -trans_update.commands = lupdate $$_PRO_FILE_ -trans_update.depends = $$_PRO_FILE_ - -trans_release.commands = lrelease $$_PRO_FILE_ -trans_release.depends = trans_update $$TRANSLATIONS - -#translate.commands = $(MKDIR) ${DESTDIR}/i18n && $(COPY) $$PWD/translations/*.qm ${DESTDIR}/i18n -translate.depends = trans_release - - - -QMAKE_EXTRA_TARGETS += trans_update trans_release translate deploy - -# updating transations only in release mode as this is requires to re-link project -# even if no changes were made. - -#PRE_TARGETDEPS += translate +# translation stuff +TRANSLATIONS = \ # English is default language, no explicit translation file + $$PWD/translations/monero-core_de.ts \ # Deutsch + $$PWD/translations/monero-core_zh.ts \ # Chineese + $$PWD/translations/monero-core_ru.ts \ # Russian + $$PWD/translations/monero-core_it.ts \ # Italian + $$PWD/translations/monero-core_pl.ts \ # Polish CONFIG(release, debug|release) { - DESTDIR=release - PRE_TARGETDEPS += translate + DESTDIR = release + LANGUPD_OPTIONS = -locations relative -no-ui-lines + LANGREL_OPTIONS = -compress -nounfinished -removeidentical + +} else { + DESTDIR = debug + LANGUPD_OPTIONS = + LANGREL_OPTIONS = -markuntranslated "MISS_TR " } -CONFIG(debug, debug|release) { - DESTDIR=debug +TARGET_FULL_PATH = $$OUT_PWD/$$DESTDIR + +macx { + TARGET_FULL_PATH = $$sprintf("%1/%2/%3.app", $$OUT_PWD, $$DESTDIR, $$TARGET) } +TRANSLATION_TARGET_DIR = $$TARGET_FULL_PATH/Contents/Resources/translations + +isEmpty(QMAKE_LUPDATE) { + win32:LANGUPD = $$[QT_INSTALL_BINS]\lupdate.exe + else:LANGUPD = $$[QT_INSTALL_BINS]/lupdate +} + +isEmpty(QMAKE_LRELEASE) { + win32:LANGREL = $$[QT_INSTALL_BINS]\lrelease.exe + else:LANGREL = $$[QT_INSTALL_BINS]/lrelease +} + +langupd.command = \ + $$LANGUPD $$LANGUPD_OPTIONS $$shell_path($$_PRO_FILE) -ts $$_PRO_FILE_PWD/$$TRANSLATIONS + +langrel.depends = langupd +langrel.input = TRANSLATIONS +langrel.output = $$TRANSLATION_TARGET_DIR/${QMAKE_FILE_BASE}.qm +langrel.commands = \ + $$LANGREL $$LANGREL_OPTIONS ${QMAKE_FILE_IN} -qm $$TRANSLATION_TARGET_DIR/${QMAKE_FILE_BASE}.qm +langrel.CONFIG += no_link + +QMAKE_EXTRA_TARGETS += langupd deploy +QMAKE_EXTRA_COMPILERS += langrel +PRE_TARGETDEPS += langupd compiler_langrel_make_all RESOURCES += qml.qrc @@ -157,6 +162,14 @@ QML_IMPORT_PATH = # Default rules for deployment. include(deployment.pri) +macx { + deploy.commands += macdeployqt $$sprintf("%1/%2/%3.app", $$OUT_PWD, $$DESTDIR, $$TARGET) +} + +win32 { + deploy.commands += windeployqt $$sprintf("%1/%2/%3", $$OUT_PWD, $$DESTDIR, $$TARGET) +} + @@ -167,3 +180,4 @@ OTHER_FILES += \ DISTFILES += \ notes.txt + diff --git a/qml.qrc b/qml.qrc index 152ea8f2..eca9f561 100644 --- a/qml.qrc +++ b/qml.qrc @@ -114,11 +114,5 @@ <file>pages/Receive.qml</file> <file>components/IconButton.qml</file> <file>lang/flags/italy.png</file> - <file>translations/monero-core_de.qm</file> - <file>translations/monero-core_en.qm</file> - <file>translations/monero-core_it.qm</file> - <file>translations/monero-core_pl.qm</file> - <file>translations/monero-core_ru.qm</file> - <file>translations/monero-core_zh.qm</file> </qresource> </RCC> From f640809d2574a19ff8ba97a0922669765e201367 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 27 Jul 2016 23:17:21 +0300 Subject: [PATCH 61/87] macdeployqt app bundle crash fixed. --- monero-core.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monero-core.pro b/monero-core.pro index 668cecdb..b0d72c7e 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -163,7 +163,7 @@ QML_IMPORT_PATH = # Default rules for deployment. include(deployment.pri) macx { - deploy.commands += macdeployqt $$sprintf("%1/%2/%3.app", $$OUT_PWD, $$DESTDIR, $$TARGET) + deploy.commands += macdeployqt $$sprintf("%1/%2/%3.app", $$OUT_PWD, $$DESTDIR, $$TARGET) -qmldir=$$PWD } win32 { From 7c33ea931a22498a638a380de105a6f295b75101 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 3 Aug 2016 15:59:42 +0300 Subject: [PATCH 62/87] msys64 deploy fix --- build.sh | 2 +- monero-core.pro | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/build.sh b/build.sh index 3c3260f5..7b0024d5 100755 --- a/build.sh +++ b/build.sh @@ -10,7 +10,7 @@ fi if [ ! -d build ]; then mkdir build; fi cd build -echo $(pwd) + qmake ../monero-core.pro "CONFIG+=release" make make deploy diff --git a/monero-core.pro b/monero-core.pro index b0d72c7e..4d3a556a 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -113,23 +113,25 @@ TRANSLATIONS = \ # English is default language, no explicit translation file $$PWD/translations/monero-core_pl.ts \ # Polish CONFIG(release, debug|release) { - DESTDIR = release + DESTDIR = release/bin LANGUPD_OPTIONS = -locations relative -no-ui-lines LANGREL_OPTIONS = -compress -nounfinished -removeidentical } else { - DESTDIR = debug + DESTDIR = debug/bin LANGUPD_OPTIONS = LANGREL_OPTIONS = -markuntranslated "MISS_TR " } TARGET_FULL_PATH = $$OUT_PWD/$$DESTDIR +TRANSLATION_TARGET_DIR = $$TARGET_FULL_PATH/translations macx { TARGET_FULL_PATH = $$sprintf("%1/%2/%3.app", $$OUT_PWD, $$DESTDIR, $$TARGET) + TRANSLATION_TARGET_DIR = $$TARGET_FULL_PATH/Contents/Resources/translations } -TRANSLATION_TARGET_DIR = $$TARGET_FULL_PATH/Contents/Resources/translations + isEmpty(QMAKE_LUPDATE) { win32:LANGUPD = $$[QT_INSTALL_BINS]\lupdate.exe @@ -167,17 +169,14 @@ macx { } win32 { - deploy.commands += windeployqt $$sprintf("%1/%2/%3", $$OUT_PWD, $$DESTDIR, $$TARGET) + deploy.commands += windeployqt $$sprintf("%1/%2/%3.exe", $$OUT_PWD, $$DESTDIR, $$TARGET) -qmldir=$$PWD } - - OTHER_FILES += \ .gitignore \ $$TRANSLATIONS DISTFILES += \ notes.txt - From 4ee5d785c5883ad219336a835a5cf2ed874fad96 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Thu, 4 Aug 2016 13:56:49 +0300 Subject: [PATCH 63/87] Deploy additional mingw dependencies --- monero-core.pro | 3 ++- windeploy_helper.sh | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 windeploy_helper.sh diff --git a/monero-core.pro b/monero-core.pro index 4d3a556a..29fedea8 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -153,7 +153,7 @@ langrel.commands = \ $$LANGREL $$LANGREL_OPTIONS ${QMAKE_FILE_IN} -qm $$TRANSLATION_TARGET_DIR/${QMAKE_FILE_BASE}.qm langrel.CONFIG += no_link -QMAKE_EXTRA_TARGETS += langupd deploy +QMAKE_EXTRA_TARGETS += langupd deploy deploy_win QMAKE_EXTRA_COMPILERS += langrel PRE_TARGETDEPS += langupd compiler_langrel_make_all @@ -170,6 +170,7 @@ macx { win32 { deploy.commands += windeployqt $$sprintf("%1/%2/%3.exe", $$OUT_PWD, $$DESTDIR, $$TARGET) -qmldir=$$PWD + deploy.commands += $$escape_expand(\n\t) $$PWD/windeploy_helper.sh $$DESTDIR } diff --git a/windeploy_helper.sh b/windeploy_helper.sh new file mode 100644 index 00000000..7649db64 --- /dev/null +++ b/windeploy_helper.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +TARGET=$1 + +FILES="zlib1.dll libwinpthread-1.dll libtiff-5.dll libstdc++-6.dll libpng16-16.dll libpcre16-0.dll libpcre-1.dll libmng-2.dll liblzma-5.dll liblcms2-2.dll libjpeg-8.dll libjasper-1.dll libintl-8.dll libicuuc57.dll libicuin57.dll libicudt57.dll libiconv-2.dll libharfbuzz-0.dll libgraphite2.dll libglib-2.0-0.dll libgcc_s_seh-1.dll libfreetype-6.dll libbz2-1.dll" + +for f in $FILES; do cp $MSYSTEM_PREFIX/bin/$f $TARGET; done + + + + + + + + + + + + + From 35d7661f0c56dfba5727984c32ae937a27ffeeca Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Thu, 4 Aug 2016 14:16:38 +0300 Subject: [PATCH 64/87] Windows application icon --- images/appicon.ico | Bin 0 -> 370070 bytes monero-core.pro | 2 ++ monero-core.rc | 1 + 3 files changed, 3 insertions(+) create mode 100644 images/appicon.ico create mode 100644 monero-core.rc diff --git a/images/appicon.ico b/images/appicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..abb4d57ab65209eccfd02a3b3ae33205102c495c GIT binary patch literal 370070 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 literal 0 HcmV?d00001 diff --git a/monero-core.pro b/monero-core.pro index 29fedea8..24ffa8ff 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -181,3 +181,5 @@ OTHER_FILES += \ DISTFILES += \ notes.txt + +RC_FILE = monero-core.rc diff --git a/monero-core.rc b/monero-core.rc new file mode 100644 index 00000000..47a4b532 --- /dev/null +++ b/monero-core.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "images/appicon.ico" From a3fc55e0acab23930219530188c09399a0c22481 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Thu, 4 Aug 2016 14:52:33 +0300 Subject: [PATCH 65/87] mac application icon --- images/appicon.icns | Bin 0 -> 71517 bytes images/appicons/128x128.png | Bin 0 -> 6941 bytes images/appicons/16x16.png | Bin 0 -> 745 bytes images/appicons/24x24.png | Bin 0 -> 1238 bytes images/appicons/256x256.png | Bin 0 -> 10406 bytes images/appicons/32x32.png | Bin 0 -> 1695 bytes images/appicons/48x48.png | Bin 0 -> 2572 bytes images/appicons/64x64.png | Bin 0 -> 3436 bytes images/appicons/96x96.png | Bin 0 -> 5207 bytes monero-core.pro | 4 ++++ 10 files changed, 4 insertions(+) create mode 100755 images/appicon.icns create mode 100755 images/appicons/128x128.png create mode 100755 images/appicons/16x16.png create mode 100755 images/appicons/24x24.png create mode 100755 images/appicons/256x256.png create mode 100755 images/appicons/32x32.png create mode 100755 images/appicons/48x48.png create mode 100755 images/appicons/64x64.png create mode 100755 images/appicons/96x96.png diff --git a/images/appicon.icns b/images/appicon.icns new file mode 100755 index 0000000000000000000000000000000000000000..b87cae95af218e26c4080c1feae4979a465da6be GIT binary patch literal 71517 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 MW<xOC|7-2P0n&Cce*gdg literal 0 HcmV?d00001 diff --git a/images/appicons/128x128.png b/images/appicons/128x128.png new file mode 100755 index 0000000000000000000000000000000000000000..15d5dcf57ccd1062a92c6eaa4778c5d82dc26017 GIT binary patch literal 6941 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 literal 0 HcmV?d00001 diff --git a/images/appicons/16x16.png b/images/appicons/16x16.png new file mode 100755 index 0000000000000000000000000000000000000000..0d8eb3fd751c9824a6c737b414df9c8daff65642 GIT binary patch literal 745 zcmV<F0v7#=P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00088Nkl<Zc-n1I zT}YEr7=HI{`Lk~7qCg0Opss=<s*AP~=EZQRQ}=^d{>?Vi6dDVOj4+rGt}ZNsq)ZCB zi44cUvf84YVssHvO)c_rPy`}Gy7qnN={-k{1s-@lUY?)#yyyK0okfJRRukGt!ztpr zv>azFW9ZO+AVgpYuD>()h&3CU+0#yDbaSSwm<Z>#negr!;nF@UI=74<WRjuH!5VvR zqkn%1NM^U22tx-5mv>tcGEX6-0Uait%@U#@EEK0S4eU)Ky0;i{HxU|%SR6*rRv=iC z!)f9sn@qu+(n6&<^jPIIH{_EEksZg;%-x5a0<#amHP$EjKOEH7w6_lhVkZRGIYf3I zl}o#i78VBWI^>zU1GE%0VaQr>)Axk(L=Wj`C2)3F{)I)^S#{+jKgQHu8Q`#4zE{<T z3~!u)!-nKIJ4d|LmGuTnGjc1ciAaxtc@-AZqe3<Qv%1khNS?FH#Q*Y_9LE?eS6cGr z3(QWZ)opt6CiK)TRnMf~AeBn0+88(@(55C>A_R*w!b8YkIi|!XV~<f$;lO+*^KazL z=TC4r92g%TS6u$$K|}Zm2o}93Jii{p%qaAa6KaW1CnjLC*-%?si?3f6#KQa>+-^7Q zb~`2~pRG;yA)#}I%~$&ghQ8;wfuF1SyxL(r9#^+jR#w92^TFr!!sT))E|Ey6^{nP~ za3%{QUq&wfNeXv&^|dxPA<*8QYiMW?GEh@fqk@GsYepat$hEdKA>7k--rd+nl+9*M z;c%FoPUk2?-fUD=Rp|_)y1H6OaIHA0Ne^S#<MB{Boz|$gx0hnEm_~e<4D)TvYz9LH zQCPFK#GY=8#X`|&REtC+Dnwqd*Te>MU0ogd{r+9Nz&<v=W-KzkF<voufwi*w`g)RH bnUUGQ@&{fxM3+~{00000NkvXXu0mjfaHd(3 literal 0 HcmV?d00001 diff --git a/images/appicons/24x24.png b/images/appicons/24x24.png new file mode 100755 index 0000000000000000000000000000000000000000..1d3d140d4942ecc775a131f037c9c0bfbef76466 GIT binary patch literal 1238 zcmV;{1S$K8P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv000D?Nkl<Zc-oCq zOKg-?6h7@tADAd88WtvsQ5Td{8+2u2U+EL*0~)5SR{Efw8QN)VK_Tj<i95o>g}5+k z0)aLyD_v*^=>lcfNRenT<sof{nrK2OnYMKP|G%H#xxHyg3D}c-Gk5Mi-}l{f&K=Rf zf#(GSn+2c0Dv0HTP$wBE=l+N5x1l@d1mfYVh-J<pDzJ!$QrsKo*-`X8`zGp{8zD!z z-xUdt7g$XvzEN=a1;Hnq1ktQ861f!Kum$_GzDF#>SHUNNIUaM*q3^lZkXR>(XNU3G zOM*{d6nwOa27ut`8-g|op+y9Vr{cVA+6fp!O@h_JZqIi)AZLNxHndY?AGN-%6uc$Q zpo1H&T=%RSU?LpRBd|tz)-X<PPwpXfIFq+&K*12p6qXl5Gy~X|;W5!T;+jF7fWn?? zu#yj`A)Hl+{eDK+zb!nNV=sY2F9&F~gIv3~-n>nK!<&8b)a)MmH@<?t4I;Mh-Pwca zas#_@2{=&&yeGi^@c)ZzPO|`CH5mLkYL==HQ1csYyYQLi({bKzb`r^}uyM2$c>l>J zTCvSJR%XE9<qRt^yr@<&%cuIf@GTFpJ$A6Rim7qfSWJ;v{&*Aa*|QUs28(mBF>%qL z-OYoVd^8_(5aElC6j+1gZ?ItkAUzKpUom-9yvo3P00cg4T)(tz;41u4C;hi08f!4^ z3<3{<F*I3t*kncg3oE{q<9p8F7iZvJVLW_O4Q&4v&cNx@!1qDAGpPVtgi!HnD{hR@ z9OkAUV-UKl2C0V)%+wWV+`4fcgM)*{ng#sw7J(!0a`;6Cei{K=sBz}Z8FTyAO`B&X zeqL?xFAcK(VksaD50(w4rzTNcTx<ov@bz>4o<i3)PMtc1l9CcLlbm)2tYDwEGTW#o zwf_)wW&fZ(B?5i>=JsW1Bxz7rSBIjaBAh*YcFDx|Ei_J_K8?b{Le$sSuNYk8D~f0v zIb_w0W)BL!j&xz<0Ehs?{V;cvu7WAl)YPE1wpLACB`Y`AJ$G*I+(|AO{KHla^#bP( z8VvUVU)D4Vd%GUMO~*BiC4=c{E3k9tP8G4Y9T^!hLqkKlw$-^aGcz+|Nsb#htt+@Y zlO?GDvN(7DVEVy4jGy)x(3qT@Q~`w=S(KNTE0%xn*s;SJB$G=OcwX9SsMca?wqwpf zWO#U3#>U2;P9zc&ot>SCMx%Z#7DIb`yE9mUYsn+~9UUDY$8uGpx3~9dDwWC^A0HRl zzI}TrKR;i}%F5oUtgKw9sHgzpbFJhxfw{`@2wmT&*0!x%w@PVgX{L;hj!I8YPl%h+ z)YMeX-p;uecq9jFFbFi40J*cx&CMmM)!p44x^UrwNL5vp=mrnN4Gj&_*w|RW_3w^s z9DEg81^=OQ6~9bwUL+Dxtq^BrwS~Qwyu3UqC@7F!yLN?6o;)e>csytK?%loY_k?>% zipS058gpa){ry=0tOoylqS(84uh?j9Z54H74~2i6%<Agu%(k{RHOk$yXHOML$9Svr z#IFuNaqkGv%Gin=4q0!Tsa(!f_`0N}rA0LU14m?1dVh#>D*ylh07*qoM6N<$g3gUf A*Z=?k literal 0 HcmV?d00001 diff --git a/images/appicons/256x256.png b/images/appicons/256x256.png new file mode 100755 index 0000000000000000000000000000000000000000..9293a3d60569bbbd02a0cdff1f7806393b62dd52 GIT binary patch literal 10406 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 E2Ma4dDgXcg literal 0 HcmV?d00001 diff --git a/images/appicons/32x32.png b/images/appicons/32x32.png new file mode 100755 index 0000000000000000000000000000000000000000..d547a46908d9e166effac3de4896c8366325f06d GIT binary patch literal 1695 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 literal 0 HcmV?d00001 diff --git a/images/appicons/48x48.png b/images/appicons/48x48.png new file mode 100755 index 0000000000000000000000000000000000000000..17a5d04091d7e83c673c2fc6bd87a7a504b2f6a2 GIT binary patch literal 2572 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 literal 0 HcmV?d00001 diff --git a/images/appicons/64x64.png b/images/appicons/64x64.png new file mode 100755 index 0000000000000000000000000000000000000000..c504f89ebc5a9aec118f03e36577417c4a265e67 GIT binary patch literal 3436 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 O0000<MNUMnLSTY%>3E|6 literal 0 HcmV?d00001 diff --git a/images/appicons/96x96.png b/images/appicons/96x96.png new file mode 100755 index 0000000000000000000000000000000000000000..f01ea8c440973dba00c967163314e375aa98d7a6 GIT binary patch literal 5207 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 RE*k&<002ovPDHLkV1mjg(tH2_ literal 0 HcmV?d00001 diff --git a/monero-core.pro b/monero-core.pro index 24ffa8ff..c247a802 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -182,4 +182,8 @@ OTHER_FILES += \ DISTFILES += \ notes.txt +# windows application icon RC_FILE = monero-core.rc + +# mac application icon +ICON = $$PWD/images/appicon.icns From b199c5fe0a6d7998bd7d263f98ee2a36c78e6552 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Tue, 9 Aug 2016 15:05:53 +0300 Subject: [PATCH 66/87] bugfix: empty transfer page --- pages/Transfer.qml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pages/Transfer.qml b/pages/Transfer.qml index 342e73cb..70fde050 100644 --- a/pages/Transfer.qml +++ b/pages/Transfer.qml @@ -93,9 +93,13 @@ Rectangle { ListModel { id: priorityModel - ListElement { column1: qsTr("LOW") + translationManager.emptyString; column2: ""; priority: PendingTransaction.Priority_Low } - ListElement { column1: qsTr("MEDIUM") + translationManager.emptyString; column2: ""; priority: PendingTransaction.Priority_Medium } - ListElement { column1: qsTr("HIGH") + translationManager.emptyString; column2: ""; priority: PendingTransaction.Priority_High } + // ListElement: cannot use script for property value, so + // code like this wont work: + // ListElement { column1: qsTr("LOW") + translationManager.emptyString ; column2: ""; priority: PendingTransaction.Priority_Low } + + ListElement { column1: qsTr("LOW") ; column2: ""; priority: PendingTransaction.Priority_Low } + ListElement { column1: qsTr("MEDIUM") ; column2: ""; priority: PendingTransaction.Priority_Medium } + ListElement { column1: qsTr("HIGH") ; column2: ""; priority: PendingTransaction.Priority_High } } StandardDropdown { From d0a5339289e6465c5ead8b73973b0840cfbb279b Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 10 Aug 2016 15:09:05 +0300 Subject: [PATCH 67/87] Removed: hardcoded "Monero - Donations" --- components/TitleBar.qml | 2 +- main.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/TitleBar.qml b/components/TitleBar.qml index e0baf8f1..8e1c9e32 100644 --- a/components/TitleBar.qml +++ b/components/TitleBar.qml @@ -35,7 +35,7 @@ Rectangle { color: "#000000" y: -height property int mouseX: 0 - property string title: qsTr("Monero - Donations") + translationManager.emptyString + property string title property bool containsMouse: false property alias maximizeButtonVisible: maximizeButton.visible property alias basicButtonVisible: goToBasicVersionButton.visible diff --git a/main.qml b/main.qml index da8545af..a7f2deb9 100644 --- a/main.qml +++ b/main.qml @@ -347,7 +347,7 @@ ApplicationWindow { PropertyChanges { target: titleBar; maximizeButtonVisible: true } PropertyChanges { target: frameArea; blocked: false } PropertyChanges { target: titleBar; y: -titleBar.height } - PropertyChanges { target: titleBar; title: qsTr("Monero - Donations") + translationManager.emptyString } + PropertyChanges { target: titleBar; title: qsTr("Monero") + translationManager.emptyString } } ] From 983317b4496eddf1083461b9c0ddf07261a6e9b2 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 10 Aug 2016 15:18:56 +0300 Subject: [PATCH 68/87] Basic view: real wallet's balance --- main.qml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/main.qml b/main.qml index a7f2deb9..46506b87 100644 --- a/main.qml +++ b/main.qml @@ -143,6 +143,8 @@ ApplicationWindow { console.log("opening wallet at: ", wallet_path); // TODO: wallet password dialog wallet = walletManager.openWallet(wallet_path, "", persistentSettings.testnet); + + if (wallet.status !== Wallet.Status_Ok) { console.log("Error opening wallet: ", wallet.errorString); informationPopup.title = qsTr("Error") + translationManager.emptyString; @@ -164,8 +166,9 @@ ApplicationWindow { function onWalletUpdate() { console.log(">>> wallet updated") - leftPanel.unlockedBalanceText = walletManager.displayAmount(wallet.unlockedBalance); - leftPanel.balanceText = walletManager.displayAmount(wallet.balance); + basicPanel.unlockedBalanceText = leftPanel.unlockedBalanceText = walletManager.displayAmount(wallet.unlockedBalance); + basicPanel.balanceText = leftPanel.balanceText = walletManager.displayAmount(wallet.balance); + } function onWalletRefresh() { From fc7a7ddf25d0a3cd7c7e6b7d07897435e1a2a43e Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 10 Aug 2016 16:21:58 +0300 Subject: [PATCH 69/87] BasicPanel: embedding/reusing "Transfer" page --- BasicPanel.qml | 93 ++++++++++++++------------------------------------ main.qml | 4 +++ 2 files changed, 29 insertions(+), 68 deletions(-) diff --git a/BasicPanel.qml b/BasicPanel.qml index 3c8de955..481fe8c4 100644 --- a/BasicPanel.qml +++ b/BasicPanel.qml @@ -28,15 +28,32 @@ import QtQuick 2.0 import "components" +import "pages" Rectangle { + id: root width: 470 - height: paymentId.y + paymentId.height + 12 + // height: paymentId.y + paymentId.height + 12 + height: header.height + header.anchors.topMargin + transferBasic.height color: "#F0EEEE" + border.width: 1 border.color: "#DBDBDB" + property alias balanceText : balanceText.text; property alias unlockedBalanceText : availableBalanceText.text; + // repeating signal to the outside world + signal paymentClicked(string address, string paymentId, double amount, int mixinCount, + int priority) + + Connections { + target: transferBasic + onPaymentClicked: { + console.log("BasicPanel: paymentClicked") + root.paymentClicked(address, paymentId, amount, mixinCount, priority) + } + } + Rectangle { id: header @@ -139,76 +156,16 @@ Rectangle { color: "#DBDBDB" } } - - Row { - id: row - anchors.left: parent.left - anchors.right: parent.right + Item { anchors.top: header.bottom - anchors.margins: 12 - spacing: 12 - - LineEdit { - height: 32 - fontSize: 15 - width: parent.width - sendButton.width - row.spacing - placeholderText: qsTr("amount...") + translationManager.emptyString - } - - StandardButton { - id: sendButton - width: 60 - height: 32 - fontSize: 11 - text: qsTr("SEND") - shadowReleasedColor: "#FF4304" - shadowPressedColor: "#B32D00" - releasedColor: "#FF6C3C" - pressedColor: "#FF4304" + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + Transfer { + id : transferBasic + anchors.fill: parent } } - LineEdit { - id: destinationLine - anchors.left: parent.left - anchors.right: parent.right - anchors.top: row.bottom - anchors.margins: 12 - fontSize: 15 - height: 32 - placeholderText: qsTr("destination...") + translationManager.emptyString - } - Text { - id: privacyLevelText - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: destinationLine.bottom - anchors.topMargin: 12 - - font.family: "Arial" - font.pixelSize: 12 - color: "#535353" - text: qsTr("Privacy level") + translationManager.emptyString - } - - PrivacyLevelSmall { - id: privacyLevel - anchors.left: parent.left - anchors.right: parent.right - anchors.top: privacyLevelText.bottom - anchors.leftMargin: 12 - anchors.rightMargin: 12 - anchors.topMargin: 12 - } - - LineEdit { - id: paymentId - anchors.left: parent.left - anchors.right: parent.right - anchors.top: privacyLevel.bottom - anchors.margins: 12 - fontSize: 15 - height: 32 - placeholderText: qsTr("payment ID (optional)...") + translationManager.emptyString - } } diff --git a/main.qml b/main.qml index 46506b87..919d0a8b 100644 --- a/main.qml +++ b/main.qml @@ -133,6 +133,7 @@ ApplicationWindow { } middlePanel.paymentClicked.connect(handlePayment); + basicPanel.paymentClicked.connect(handlePayment); if (typeof wizard.settings['wallet'] !== 'undefined') { @@ -397,6 +398,9 @@ ApplicationWindow { id: basicPanel x: 0 anchors.bottom: parent.bottom + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right visible: false } From 6f1343aaa04bf2e4f959b5d3201239fe7fc85398 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Tue, 16 Aug 2016 23:21:46 +0300 Subject: [PATCH 70/87] ask user for the password if wallet is password-protected --- components/PasswordDialog.qml | 5 +++++ main.qml | 40 +++++++++++++++++++++++++++++------ monero-core.pro | 5 ++++- qml.qrc | 1 + wizard/WizardMain.qml | 39 ++++++---------------------------- 5 files changed, 49 insertions(+), 41 deletions(-) create mode 100644 components/PasswordDialog.qml diff --git a/components/PasswordDialog.qml b/components/PasswordDialog.qml new file mode 100644 index 00000000..9c36e13c --- /dev/null +++ b/components/PasswordDialog.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Item { + +} diff --git a/main.qml b/main.qml index 919d0a8b..7320d3af 100644 --- a/main.qml +++ b/main.qml @@ -139,19 +139,18 @@ ApplicationWindow { if (typeof wizard.settings['wallet'] !== 'undefined') { wallet = wizard.settings['wallet']; } else { - var wallet_path = persistentSettings.wallet_path + "/" + persistentSettings.account_name + "/" - + persistentSettings.account_name; + var wallet_path = walletPath(); + console.log("opening wallet at: ", wallet_path); // TODO: wallet password dialog wallet = walletManager.openWallet(wallet_path, "", persistentSettings.testnet); if (wallet.status !== Wallet.Status_Ok) { - console.log("Error opening wallet: ", wallet.errorString); - informationPopup.title = qsTr("Error") + translationManager.emptyString; - informationPopup.text = qsTr("Couldn't open wallet: ") + wallet.errorString; - informationPopup.icon = StandardIcon.Critical - informationPopup.open() + console.error("Error opening wallet with empty password: ", wallet.errorString); + + // try to open wallet with password; + passwordDialog.open(); return; } console.log("Wallet opened successfully: ", wallet.errorString); @@ -165,6 +164,13 @@ ApplicationWindow { } + function walletPath() { + var wallet_path = persistentSettings.wallet_path + "/" + persistentSettings.account_name + "/" + + persistentSettings.account_name; + return wallet_path; + } + + function onWalletUpdate() { console.log(">>> wallet updated") basicPanel.unlockedBalanceText = leftPanel.unlockedBalanceText = walletManager.displayAmount(wallet.unlockedBalance); @@ -291,6 +297,7 @@ ApplicationWindow { // Information dialog MessageDialog { id: informationPopup + standardButtons: StandardButton.Ok } @@ -303,6 +310,25 @@ ApplicationWindow { } } + PasswordDialog { + id: passwordDialog + standardButtons: StandardButton.Ok + StandardButton.Cancel + onAccepted: { + + var wallet_path = walletPath(); + console.log("opening wallet with password: ", wallet_path); + wallet = walletManager.openWallet(wallet_path, password, persistentSettings.testnet); + if (wallet.status !== Wallet.Status_Ok) { + console.error("Error opening wallet with password: ", wallet.errorString); + informationPopup.title = qsTr("Error") + translationManager.emptyString; + informationPopup.text = qsTr("Couldn't open wallet: ") + wallet.errorString; + informationPopup.icon = StandardIcon.Critical + informationPopup.open() + + } + } + } + Window { id: walletInitializationSplash modality: Qt.ApplicationModal diff --git a/monero-core.pro b/monero-core.pro index c247a802..9520cd37 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -155,6 +155,8 @@ langrel.CONFIG += no_link QMAKE_EXTRA_TARGETS += langupd deploy deploy_win QMAKE_EXTRA_COMPILERS += langrel + + PRE_TARGETDEPS += langupd compiler_langrel_make_all RESOURCES += qml.qrc @@ -180,7 +182,8 @@ OTHER_FILES += \ $$TRANSLATIONS DISTFILES += \ - notes.txt + notes.txt \ + components/PasswordDialog.qml # windows application icon RC_FILE = monero-core.rc diff --git a/qml.qrc b/qml.qrc index eca9f561..dcf4b9b1 100644 --- a/qml.qrc +++ b/qml.qrc @@ -114,5 +114,6 @@ <file>pages/Receive.qml</file> <file>components/IconButton.qml</file> <file>lang/flags/italy.png</file> + <file>components/PasswordDialog.qml</file> </qresource> </RCC> diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index f0556efc..488bd959 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -78,24 +78,6 @@ Rectangle { } } - // TODO: remove it - function handlePageChanged() { - -// switch (pages[currentPage]) { -//// case finishPage: -//// // display settings summary -//// finishPage.updateSettingsSummary(); -//// nextButton.visible = false; -//// break; -// case recoveryWalletPage: -// // disable "next button" until 25 words private key entered -// nextButton.enabled = false -// break -// default: -// nextButton.enabled = true - -// } - } function openCreateWalletPage() { @@ -126,10 +108,9 @@ Rectangle { //! actually writes the wallet function applySettings() { - print ("Here we apply the settings"); + console.log("Here we apply the settings"); // here we need to actually move wallet to the new location - // put wallet files to the subdirectory with the same name as - // wallet name + var new_wallet_filename = settings.wallet_path + "/" + settings.account_name + "/" + settings.account_name; @@ -138,9 +119,12 @@ Rectangle { if (new_wallet_filename !== settings.wallet_filename) { // using previously saved wallet; settings.wallet.store(new_wallet_filename); - //walletManager.moveWallet(settingsObject.wallet_filename, new_wallet_filename); } + // protecting wallet with password + console.log("Protecting wallet with password: " + settings.wallet_password) + settings.wallet.setPassword(settings.wallet_password); + // saving wallet_filename; settings['wallet_filename'] = new_wallet_filename; @@ -163,17 +147,6 @@ Rectangle { } -// Settings { -// id: persistentSettings - -// property string language -// property string account_name -// property string wallet_path -// property bool auto_donations_enabled : true -// property int auto_donations_amount : 50 -// property bool allow_background_mining : true -// } - Rectangle { id: nextButton anchors.verticalCenter: parent.verticalCenter From c1269301f7c19a849b0fae7ddbe9afd38aaf71d3 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 17 Aug 2016 15:14:43 +0300 Subject: [PATCH 71/87] Ask for password in wallet is password protected. closes #26 --- BasicPanel.qml | 8 ++++ LeftPanel.qml | 9 ++++ MiddlePanel.qml | 9 ++++ RightPanel.qml | 10 +++++ components/PasswordDialog.qml | 37 +++++++++++++++- main.qml | 81 ++++++++++++++++++++++++----------- monero-core.pro | 13 ++++-- 7 files changed, 138 insertions(+), 29 deletions(-) diff --git a/BasicPanel.qml b/BasicPanel.qml index 481fe8c4..abeb135c 100644 --- a/BasicPanel.qml +++ b/BasicPanel.qml @@ -27,6 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 +import QtGraphicalEffects 1.0 import "components" import "pages" @@ -167,5 +168,12 @@ Rectangle { } } + // indicate disabled state + Desaturate { + anchors.fill: parent + source: parent + desaturation: root.enabled ? 0.0 : 1.0 + } + } diff --git a/LeftPanel.qml b/LeftPanel.qml index 604f2d6e..851db047 100644 --- a/LeftPanel.qml +++ b/LeftPanel.qml @@ -27,6 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.2 +import QtGraphicalEffects 1.0 import "components" Rectangle { @@ -355,4 +356,12 @@ Rectangle { connected: false } } + // indicate disabled state + Desaturate { + anchors.fill: parent + source: parent + desaturation: panel.enabled ? 0.0 : 1.0 + } + + } diff --git a/MiddlePanel.qml b/MiddlePanel.qml index cb1c74d6..a2cabc1c 100644 --- a/MiddlePanel.qml +++ b/MiddlePanel.qml @@ -27,8 +27,10 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.2 +import QtGraphicalEffects 1.0 Rectangle { + id: root color: "#F0EEEE" signal paymentClicked(string address, string paymentId, double amount, int mixinCount, int priority) signal generatePaymentIdInvoked() @@ -116,4 +118,11 @@ Rectangle { height: 1 color: "#DBDBDB" } + + // indicate disabled state + Desaturate { + anchors.fill: parent + source: parent + desaturation: root.enabled ? 0.0 : 1.0 + } } diff --git a/RightPanel.qml b/RightPanel.qml index 932b3916..d27b8b73 100644 --- a/RightPanel.qml +++ b/RightPanel.qml @@ -29,10 +29,13 @@ import QtQuick 2.2 import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 +import QtGraphicalEffects 1.0 + import "tabs" import "components" Rectangle { + id: root width: 330 color: "#FFFFFF" @@ -145,4 +148,11 @@ Rectangle { width: 1 color: "#DBDBDB" } + + // indicate disabled state + Desaturate { + anchors.fill: parent + source: parent + desaturation: root.enabled ? 0.0 : 1.0 + } } diff --git a/components/PasswordDialog.qml b/components/PasswordDialog.qml index 9c36e13c..cd66d461 100644 --- a/components/PasswordDialog.qml +++ b/components/PasswordDialog.qml @@ -1,5 +1,40 @@ import QtQuick 2.0 +import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.2 +import QtQuick.Layouts 1.1 +import QtQuick.Controls.Styles 1.4 -Item { +// import "../components" +Dialog { + id: root + readonly property alias password: passwordInput.text + standardButtons: StandardButton.Ok + StandardButton.Cancel + ColumnLayout { + id: column + height: 40 + anchors.fill: parent + + Label { + text: qsTr("Please enter wallet password") + Layout.columnSpan: 2 + Layout.fillWidth: true + font.family: "Arial" + font.pixelSize: 32 + } + + TextField { + id : passwordInput + + echoMode: TextInput.Password + focus: true + Layout.fillWidth: true + font.family: "Arial" + font.pixelSize: 24 + style: TextFieldStyle { + passwordCharacter: "•" + } + } + } } + diff --git a/main.qml b/main.qml index 7320d3af..faeaf123 100644 --- a/main.qml +++ b/main.qml @@ -41,7 +41,8 @@ import "wizard" ApplicationWindow { id: appWindow - objectName: "appWindow" + + property var currentItem property bool whatIsEnable: false property bool ctrlPressed: false @@ -50,6 +51,8 @@ ApplicationWindow { property alias persistentSettings : persistentSettings property var wallet; property var transaction; + property alias password : passwordDialog.password + function altKeyReleased() { ctrlPressed = false; } @@ -98,24 +101,24 @@ ApplicationWindow { } function mousePressed(obj, mouseX, mouseY) { - if(obj.objectName === "appWindow") - obj = rootItem +// if(obj.objectName === "appWindow") +// obj = rootItem - var tmp = rootItem.mapFromItem(obj, mouseX, mouseY) - if(tmp !== undefined) { - mouseX = tmp.x - mouseY = tmp.y - } +// var tmp = rootItem.mapFromItem(obj, mouseX, mouseY) +// if(tmp !== undefined) { +// mouseX = tmp.x +// mouseY = tmp.y +// } - if(currentItem !== undefined) { - var tmp_x = rootItem.mapToItem(currentItem, mouseX, mouseY).x - var tmp_y = rootItem.mapToItem(currentItem, mouseX, mouseY).y +// if(currentItem !== undefined) { +// var tmp_x = rootItem.mapToItem(currentItem, mouseX, mouseY).x +// var tmp_y = rootItem.mapToItem(currentItem, mouseX, mouseY).y - if(!currentItem.containsPoint(tmp_x, tmp_y)) { - currentItem.hide() - currentItem = undefined - } - } +// if(!currentItem.containsPoint(tmp_x, tmp_y)) { +// currentItem.hide() +// currentItem = undefined +// } +// } } function mouseReleased(obj, mouseX, mouseY) { @@ -142,17 +145,18 @@ ApplicationWindow { var wallet_path = walletPath(); console.log("opening wallet at: ", wallet_path); - // TODO: wallet password dialog - wallet = walletManager.openWallet(wallet_path, "", persistentSettings.testnet); - - + wallet = walletManager.openWallet(wallet_path, appWindow.password, + persistentSettings.testnet); if (wallet.status !== Wallet.Status_Ok) { console.error("Error opening wallet with empty password: ", wallet.errorString); - + console.log("closing wallet...") + walletManager.closeWallet(wallet) + console.log("wallet closed") // try to open wallet with password; passwordDialog.open(); return; } + console.log("Wallet opened successfully: ", wallet.errorString); } // subscribing for wallet updates @@ -195,6 +199,8 @@ ApplicationWindow { } + + // called on "transfer" function handlePayment(address, paymentId, amount, mixinCount, priority) { console.log("Creating transaction: ") @@ -213,6 +219,7 @@ ApplicationWindow { informationPopup.title = qsTr("Error") + translationManager.emptyString; informationPopup.text = qsTr("Can't create transaction: ") + transaction.errorString informationPopup.icon = StandardIcon.Critical + informationPopup.onCloseCallback = null informationPopup.open(); // deleting transaction object, we don't want memleaks wallet.disposeTransaction(transaction); @@ -248,13 +255,22 @@ ApplicationWindow { informationPopup.text = qsTr("Money sent successfully") + translationManager.emptyString informationPopup.icon = StandardIcon.Information } - + informationPopup.onCloseCallback = null informationPopup.open() wallet.refresh() wallet.disposeTransaction(transaction) } + // blocks UI if wallet can't be opened or no connection to the daemon + function enableUI(enable) { + middlePanel.enabled = enable; + leftPanel.enabled = enable; + rightPanel.enabled = enable; + basicPanel.enabled = enable; + } + + objectName: "appWindow" visible: true width: rightPanelExpanded ? 1269 : 1269 - 300 height: 800 @@ -262,6 +278,7 @@ ApplicationWindow { flags: Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.Window | Qt.WindowMinimizeButtonHint onWidthChanged: x -= 0 + Component.onCompleted: { x = (Screen.width - width) / 2 y = (Screen.height - height) / 2 @@ -278,6 +295,7 @@ ApplicationWindow { } } + Settings { id: persistentSettings property string language @@ -296,9 +314,15 @@ ApplicationWindow { // Information dialog MessageDialog { + // dynamically change onclose handler + property var onCloseCallback id: informationPopup - standardButtons: StandardButton.Ok + onAccepted: { + if (onCloseCallback) { + onCloseCallback() + } + } } // Confrirmation aka question dialog @@ -317,6 +341,7 @@ ApplicationWindow { var wallet_path = walletPath(); console.log("opening wallet with password: ", wallet_path); + wallet = walletManager.openWallet(wallet_path, password, persistentSettings.testnet); if (wallet.status !== Wallet.Status_Ok) { console.error("Error opening wallet with password: ", wallet.errorString); @@ -324,9 +349,16 @@ ApplicationWindow { informationPopup.text = qsTr("Couldn't open wallet: ") + wallet.errorString; informationPopup.icon = StandardIcon.Critical informationPopup.open() - + informationPopup.onCloseCallback = appWindow.initialize + walletManager.closeWallet(wallet); } } + onRejected: { + appWindow.enableUI(false) + } + onDiscard: { + appWindow.enableUI(false) + } } Window { @@ -339,7 +371,6 @@ ApplicationWindow { anchors.fill: parent text: qsTr("Initializing Wallet..."); } - } diff --git a/monero-core.pro b/monero-core.pro index 9520cd37..2dde61fe 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -146,6 +146,8 @@ isEmpty(QMAKE_LRELEASE) { langupd.command = \ $$LANGUPD $$LANGUPD_OPTIONS $$shell_path($$_PRO_FILE) -ts $$_PRO_FILE_PWD/$$TRANSLATIONS + + langrel.depends = langupd langrel.input = TRANSLATIONS langrel.output = $$TRANSLATION_TARGET_DIR/${QMAKE_FILE_BASE}.qm @@ -157,7 +159,12 @@ QMAKE_EXTRA_TARGETS += langupd deploy deploy_win QMAKE_EXTRA_COMPILERS += langrel -PRE_TARGETDEPS += langupd compiler_langrel_make_all + +# temporary: do not update/release translations for "Debug" build, +# as we have an issue with linking +CONFIG(release, debug|release) { + PRE_TARGETDEPS += langupd compiler_langrel_make_all +} RESOURCES += qml.qrc @@ -182,8 +189,8 @@ OTHER_FILES += \ $$TRANSLATIONS DISTFILES += \ - notes.txt \ - components/PasswordDialog.qml + notes.txt + # windows application icon RC_FILE = monero-core.rc From d3234bb91564ee8327b111e0acf2a83153929c25 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Thu, 18 Aug 2016 21:55:34 +0300 Subject: [PATCH 72/87] WalletManager::openWalletAsync in progress --- main.qml | 81 ++++++++++++++++++++----------- src/libwalletqt/WalletManager.cpp | 34 ++++++++++++- src/libwalletqt/WalletManager.h | 33 +++++++++++-- 3 files changed, 114 insertions(+), 34 deletions(-) diff --git a/main.qml b/main.qml index faeaf123..bf30266d 100644 --- a/main.qml +++ b/main.qml @@ -49,9 +49,10 @@ ApplicationWindow { property bool rightPanelExpanded: false property bool osx: false property alias persistentSettings : persistentSettings - property var wallet; + property var currentWallet; property var transaction; property alias password : passwordDialog.password + property bool walletOpeningWithPassword: false @@ -145,26 +146,9 @@ ApplicationWindow { var wallet_path = walletPath(); console.log("opening wallet at: ", wallet_path); - wallet = walletManager.openWallet(wallet_path, appWindow.password, + walletManager.openWalletAsync(wallet_path, appWindow.password, persistentSettings.testnet); - if (wallet.status !== Wallet.Status_Ok) { - console.error("Error opening wallet with empty password: ", wallet.errorString); - console.log("closing wallet...") - walletManager.closeWallet(wallet) - console.log("wallet closed") - // try to open wallet with password; - passwordDialog.open(); - return; - } - - console.log("Wallet opened successfully: ", wallet.errorString); } - // subscribing for wallet updates - wallet.updated.connect(onWalletUpdate); - wallet.refreshed.connect(onWalletRefresh); - - console.log("initializing with daemon address..") - wallet.initAsync(persistentSettings.daemon_address, 0); } @@ -174,6 +158,50 @@ ApplicationWindow { return wallet_path; } + function onWalletOpened(wallet) { + console.log(">>> wallet opened: " + wallet) + + if (wallet.status !== Wallet.Status_Ok) { + if (!appWindow.walletOpeningWithPassword) { + console.error("Error opening wallet with empty password: ", wallet.errorString); + console.log("closing wallet async...") + walletManager.closeWalletAsync(wallet) + // try to open wallet with password; + appWindow.walletOpeningWithPassword = true + passwordDialog.open(); + } else { + // opening with password but password doesn't match + console.error("Error opening wallet with password: ", wallet.errorString); + informationPopup.title = qsTr("Error") + translationManager.emptyString; + informationPopup.text = qsTr("Couldn't open wallet: ") + wallet.errorString; + informationPopup.icon = StandardIcon.Critical + informationPopup.open() + informationPopup.onCloseCallback = appWindow.initialize + walletManager.closeWallet(wallet); + } + return; + } + + // wallet opened successfully, subscribing for wallet updates + currentWallet = wallet +// wallet.updated.connect(appWindow.onWalletUpdate) +// wallet.refreshed.connect(appWindow.onWalletRefresh) + // currentWallet.refreshed.connect(onWalletRefresh) + var connectResult = currentWallet.refreshed.connect(function() { + console.log("QML: refreshed") + }) + + console.log("connected to refreshed: " + connectResult); + currentWallet.updated.connect(onWalletUpdate) + console.log("initializing with daemon address: ", persistentSettings.daemon_address) + currentWallet.initAsync(persistentSettings.daemon_address, 0); + + } + + + function onWalletClosed(walletAddress) { + console.log(">>> wallet closed: " + walletAddress) + } function onWalletUpdate() { console.log(">>> wallet updated") @@ -283,6 +311,9 @@ ApplicationWindow { x = (Screen.width - width) / 2 y = (Screen.height - height) / 2 // + walletManager.walletOpened.connect(onWalletOpened); + walletManager.walletClosed.connect(onWalletClosed); + rootItem.state = walletsFound() ? "normal" : "wizard"; if (rootItem.state === "normal") { initialize(persistentSettings) @@ -342,16 +373,8 @@ ApplicationWindow { var wallet_path = walletPath(); console.log("opening wallet with password: ", wallet_path); - wallet = walletManager.openWallet(wallet_path, password, persistentSettings.testnet); - if (wallet.status !== Wallet.Status_Ok) { - console.error("Error opening wallet with password: ", wallet.errorString); - informationPopup.title = qsTr("Error") + translationManager.emptyString; - informationPopup.text = qsTr("Couldn't open wallet: ") + wallet.errorString; - informationPopup.icon = StandardIcon.Critical - informationPopup.open() - informationPopup.onCloseCallback = appWindow.initialize - walletManager.closeWallet(wallet); - } + walletManager.openWalletAsync(wallet_path, password, persistentSettings.testnet); + } onRejected: { appWindow.enableUI(false) diff --git a/src/libwalletqt/WalletManager.cpp b/src/libwalletqt/WalletManager.cpp index a7742bca..50a61553 100644 --- a/src/libwalletqt/WalletManager.cpp +++ b/src/libwalletqt/WalletManager.cpp @@ -6,6 +6,7 @@ #include <QDir> #include <QDebug> #include <QUrl> +#include <QtConcurrent/QtConcurrent> @@ -42,6 +43,20 @@ Wallet *WalletManager::openWallet(const QString &path, const QString &password, return wallet; } +void WalletManager::openWalletAsync(const QString &path, const QString &password, bool testnet) +{ + QFuture<Wallet*> future = QtConcurrent::run(this, &WalletManager::openWallet, + path, password, testnet); + QFutureWatcher<Wallet*> * watcher = new QFutureWatcher<Wallet*>(); + watcher->setFuture(future); + connect(watcher, &QFutureWatcher<Wallet*>::finished, + this, [this, watcher]() { + QFuture<Wallet*> future = watcher->future(); + watcher->deleteLater(); + emit walletOpened(future.result()); + }); +} + Wallet *WalletManager::recoveryWallet(const QString &path, const QString &memo, bool testnet) { @@ -51,9 +66,26 @@ Wallet *WalletManager::recoveryWallet(const QString &path, const QString &memo, } -void WalletManager::closeWallet(Wallet *wallet) +QString WalletManager::closeWallet(Wallet *wallet) { + QString result = wallet->address(); delete wallet; + return result; +} + +void WalletManager::closeWalletAsync(Wallet *wallet) +{ + QFuture<QString> future = QtConcurrent::run(this, &WalletManager::closeWallet, + wallet); + QFutureWatcher<QString> * watcher = new QFutureWatcher<QString>(); + watcher->setFuture(future); + + connect(watcher, &QFutureWatcher<QString>::finished, + this, [this, watcher]() { + QFuture<QString> future = watcher->future(); + watcher->deleteLater(); + emit future.result(); + }); } bool WalletManager::walletExists(const QString &path) const diff --git a/src/libwalletqt/WalletManager.h b/src/libwalletqt/WalletManager.h index 29df9048..27224b5f 100644 --- a/src/libwalletqt/WalletManager.h +++ b/src/libwalletqt/WalletManager.h @@ -16,15 +16,38 @@ public: // wizard: createWallet path; Q_INVOKABLE Wallet * createWallet(const QString &path, const QString &password, const QString &language, bool testnet = false); - // just for future use + + /*! + * \brief openWallet - opens wallet by given path + * \param path - wallet filename + * \param password - wallet password. Empty string in wallet isn't password protected + * \param testnet - determines if we running testnet + * \return wallet object pointer + */ Q_INVOKABLE Wallet * openWallet(const QString &path, const QString &password, bool testnet = false); + /*! + * \brief openWalletAsync - asynchronous version of "openWallet". Returns immediately. "walletOpened" signal + * emitted when wallet opened; + */ + Q_INVOKABLE void openWalletAsync(const QString &path, const QString &password, bool testnet = false); + // wizard: recoveryWallet path; hint: internally it recorvers wallet and set password = "" Q_INVOKABLE Wallet * recoveryWallet(const QString &path, const QString &memo, bool testnet = false); - //! utils: close wallet to free memory - Q_INVOKABLE void closeWallet(Wallet * wallet); + /*! + * \brief closeWallet - closes wallet and frees memory + * \param wallet + * \return wallet address + */ + Q_INVOKABLE QString closeWallet(Wallet * wallet); + + /*! + * \brief closeWalletAsync - asynchronous version of "closeWallet" + * \param wallet - wallet pointer; + */ + Q_INVOKABLE void closeWalletAsync(Wallet * wallet); //! checks is given filename is a wallet; Q_INVOKABLE bool walletExists(const QString &path) const; @@ -50,8 +73,10 @@ public: signals: -public slots: + void walletOpened(Wallet * wallet); + void walletClosed(const QString &walletAddress); +public slots: private: explicit WalletManager(QObject *parent = 0); From 8d93f01db434ffd873e095d55abeeae7d8021f6f Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Fri, 19 Aug 2016 14:44:44 +0300 Subject: [PATCH 73/87] WalletManager::openWalletAsync integrating with UI --- main.qml | 62 +++++++++++++++---------------- src/libwalletqt/WalletManager.cpp | 9 ++++- wizard/WizardCreateWallet.qml | 3 +- wizard/WizardRecoveryWallet.qml | 9 ++--- wizard/utils.js | 5 +++ 5 files changed, 50 insertions(+), 38 deletions(-) diff --git a/main.qml b/main.qml index bf30266d..f589c666 100644 --- a/main.qml +++ b/main.qml @@ -52,8 +52,6 @@ ApplicationWindow { property var currentWallet; property var transaction; property alias password : passwordDialog.password - property bool walletOpeningWithPassword: false - function altKeyReleased() { ctrlPressed = false; } @@ -140,18 +138,27 @@ ApplicationWindow { basicPanel.paymentClicked.connect(handlePayment); + // wallet already opened with wizard, we just need to initialize it if (typeof wizard.settings['wallet'] !== 'undefined') { - wallet = wizard.settings['wallet']; + connectWallet(wizard.settings['wallet']) } else { var wallet_path = walletPath(); - - console.log("opening wallet at: ", wallet_path); + console.log("opening wallet at: ", wallet_path, "with password: ", appWindow.password); walletManager.openWalletAsync(wallet_path, appWindow.password, persistentSettings.testnet); } } + + function connectWallet(wallet) { + currentWallet = wallet + currentWallet.refreshed.connect(onWalletRefresh) + currentWallet.updated.connect(onWalletUpdate) + console.log("initializing with daemon address: ", persistentSettings.daemon_address) + currentWallet.initAsync(persistentSettings.daemon_address, 0); + } + function walletPath() { var wallet_path = persistentSettings.wallet_path + "/" + persistentSettings.account_name + "/" + persistentSettings.account_name; @@ -162,39 +169,32 @@ ApplicationWindow { console.log(">>> wallet opened: " + wallet) if (wallet.status !== Wallet.Status_Ok) { - if (!appWindow.walletOpeningWithPassword) { + if (appWindow.password === '') { console.error("Error opening wallet with empty password: ", wallet.errorString); - console.log("closing wallet async...") + console.log("closing wallet async : " + wallet.address) walletManager.closeWalletAsync(wallet) // try to open wallet with password; - appWindow.walletOpeningWithPassword = true passwordDialog.open(); } else { // opening with password but password doesn't match console.error("Error opening wallet with password: ", wallet.errorString); + informationPopup.title = qsTr("Error") + translationManager.emptyString; informationPopup.text = qsTr("Couldn't open wallet: ") + wallet.errorString; informationPopup.icon = StandardIcon.Critical + console.log("closing wallet async : " + wallet.address) + walletManager.closeWalletAsync(wallet); informationPopup.open() - informationPopup.onCloseCallback = appWindow.initialize - walletManager.closeWallet(wallet); + informationPopup.onCloseCallback = function() { + passwordDialog.open() + } + } return; } // wallet opened successfully, subscribing for wallet updates - currentWallet = wallet -// wallet.updated.connect(appWindow.onWalletUpdate) -// wallet.refreshed.connect(appWindow.onWalletRefresh) - // currentWallet.refreshed.connect(onWalletRefresh) - var connectResult = currentWallet.refreshed.connect(function() { - console.log("QML: refreshed") - }) - - console.log("connected to refreshed: " + connectResult); - currentWallet.updated.connect(onWalletUpdate) - console.log("initializing with daemon address: ", persistentSettings.daemon_address) - currentWallet.initAsync(persistentSettings.daemon_address, 0); + connectWallet(wallet) } @@ -205,14 +205,14 @@ ApplicationWindow { function onWalletUpdate() { console.log(">>> wallet updated") - basicPanel.unlockedBalanceText = leftPanel.unlockedBalanceText = walletManager.displayAmount(wallet.unlockedBalance); - basicPanel.balanceText = leftPanel.balanceText = walletManager.displayAmount(wallet.balance); - + basicPanel.unlockedBalanceText = leftPanel.unlockedBalanceText = + walletManager.displayAmount(currentWallet.unlockedBalance); + basicPanel.balanceText = leftPanel.balanceText = walletManager.displayAmount(currentWallet.balance); } function onWalletRefresh() { console.log(">>> wallet refreshed") - leftPanel.networkStatus.connected = wallet.connected + leftPanel.networkStatus.connected = currentWallet.connected onWalletUpdate(); } @@ -369,12 +369,12 @@ ApplicationWindow { id: passwordDialog standardButtons: StandardButton.Ok + StandardButton.Cancel onAccepted: { + appWindow.currentWallet = null + appWindow.initialize(); - var wallet_path = walletPath(); - console.log("opening wallet with password: ", wallet_path); - - walletManager.openWalletAsync(wallet_path, password, persistentSettings.testnet); - +// var wallet_path = walletPath(); +// console.log("opening wallet with password: ", wallet_path); +// walletManager.openWalletAsync(wallet_path, password, persistentSettings.testnet); } onRejected: { appWindow.enableUI(false) diff --git a/src/libwalletqt/WalletManager.cpp b/src/libwalletqt/WalletManager.cpp index 50a61553..da5c4cd7 100644 --- a/src/libwalletqt/WalletManager.cpp +++ b/src/libwalletqt/WalletManager.cpp @@ -40,6 +40,13 @@ Wallet *WalletManager::openWallet(const QString &path, const QString &password, Bitmonero::Wallet * w = m_pimpl->openWallet(path.toStdString(), password.toStdString(), testnet); Wallet * wallet = new Wallet(w); + + // move wallet to the GUI thread. Otherwise it wont be emitting signals + if (wallet->thread() != qApp->thread()) { + wallet->moveToThread(qApp->thread()); + } + + return wallet; } @@ -84,7 +91,7 @@ void WalletManager::closeWalletAsync(Wallet *wallet) this, [this, watcher]() { QFuture<QString> future = watcher->future(); watcher->deleteLater(); - emit future.result(); + emit walletClosed(future.result()); }); } diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml index 771a13ec..43b8158f 100644 --- a/wizard/WizardCreateWallet.qml +++ b/wizard/WizardCreateWallet.qml @@ -29,6 +29,7 @@ import QtQuick 2.2 import moneroComponents 1.0 import QtQuick.Dialogs 1.2 +import 'utils.js' as Utils Item { opacity: 0 @@ -54,7 +55,7 @@ Item { } function checkNextButton() { - var wordsArray = cleanWordsInput(uiItem.wordsTextItem.memoText).split(" "); + var wordsArray = Utils.lineBreaksToSpaces(uiItem.wordsTextItem.memoText).split(" "); wizard.nextButton.enabled = wordsArray.length === 25; } diff --git a/wizard/WizardRecoveryWallet.qml b/wizard/WizardRecoveryWallet.qml index 2e6fe5f6..505bc239 100644 --- a/wizard/WizardRecoveryWallet.qml +++ b/wizard/WizardRecoveryWallet.qml @@ -30,6 +30,7 @@ import QtQuick 2.2 import moneroComponents 1.0 import QtQuick.Dialogs 1.2 import Bitmonero.Wallet 1.0 +import 'utils.js' as Utils Item { opacity: 0 @@ -46,13 +47,13 @@ Item { } function checkNextButton() { - var wordsArray = cleanWordsInput(uiItem.wordsTextItem.memoText).split(" "); + var wordsArray = Utils.lineBreaksToSpaces(uiItem.wordsTextItem.memoText).split(" "); wizard.nextButton.enabled = wordsArray.length === 25; } function onPageClosed(settingsObject) { settingsObject['account_name'] = uiItem.accountNameText - settingsObject['words'] = cleanWordsInput(uiItem.wordsTextItem.memoText) + settingsObject['words'] = Utils.lineBreaksToSpaces(uiItem.wordsTextItem.memoText) settingsObject['wallet_path'] = uiItem.walletPath return recoveryWallet(settingsObject) } @@ -69,9 +70,7 @@ Item { return success; } - function cleanWordsInput(text) { - return text.trim().replace(/(\r\n|\n|\r)/gm, " "); - } + WizardManageWalletUI { id: uiItem diff --git a/wizard/utils.js b/wizard/utils.js index 0cc910c6..be066598 100644 --- a/wizard/utils.js +++ b/wizard/utils.js @@ -42,3 +42,8 @@ function mapScope (inputScopeFrom, inputScopeTo, outputScopeFrom, outputScopeTo, function tr(text) { return qsTr(text) + translationManager.emptyString } + + +function lineBreaksToSpaces(text) { + return text.trim().replace(/(\r\n|\n|\r)/gm, " "); +} From 57ad0927085df2a9ffe7d59174bb9baf9b36430c Mon Sep 17 00:00:00 2001 From: ferretinjapan <ferretinjapan@gmail.com> Date: Sun, 21 Aug 2016 03:29:52 +0930 Subject: [PATCH 74/87] Update README.md with linux build instructions Tested and confirmed to work on Ubuntu 16.04 i386 on virtual machine. x64 version has build dependency issues however, an issue has been filed, see https://github.com/mbg033/monero-core/issues/40 --- README.md | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 25caa911..7546a521 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,42 @@ Process: TODO ### On Linux: -TODO + +(Tested on Ubuntu 16.04 i386) + +1. Install Bitmonero dependencies. + +`sudo apt install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev` + +2. Go to the repository where the most recent version is. + +`git clone https://github.com/mbg033/monero-core.git` + +3. Go into the repository. + +`cd monero-core` + +4. Use the script to compile the bitmonero libs necessary to run the GUI. + +`./get_libwallet_api.sh` + +5. Install the GUI dependencies. + +`sudo apt-get install qtbase5-dev qt5-default qtdeclarative5-dev qml-module-qtquick-controls qml-module-qtquick-xmllistmodel qttools5-dev-tools qml-module-qtquick-dialogs` + +6. Build the GUI. + +`qmake` + +`make` + +7. Before running the GUI, it's recommended you have a copy of bitmonero running in the background. + +`./bitmonerod --rpc-bind-port 38081` + +8. Run the GUI client. + +`./release/bin/monero-core` ### On OS X: 1. install homebrew From 23c4c9550f10c438c6f3719c6872012cb6898726 Mon Sep 17 00:00:00 2001 From: ferretinjapan <ferretinjapan@gmail.com> Date: Mon, 22 Aug 2016 04:33:26 +0930 Subject: [PATCH 75/87] Update README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7546a521..29f6df9c 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ Process: TODO ### On Linux: -(Tested on Ubuntu 16.04 i386) +(Tested on Ubuntu 16.04 i386 and Linux Mint 18 "Sarah" - Cinnamon (64-bit)) 1. Install Bitmonero dependencies. @@ -94,8 +94,14 @@ Process: TODO 5. Install the GUI dependencies. + a) For Ubuntu 16.04 i386 + `sudo apt-get install qtbase5-dev qt5-default qtdeclarative5-dev qml-module-qtquick-controls qml-module-qtquick-xmllistmodel qttools5-dev-tools qml-module-qtquick-dialogs` + b) For Linux Mint 18 "Sarah" - Cinnamon (64-bit) + +`sudo apt install qml-module-qt-labs-settings qml-module-qtgraphicaleffects` + 6. Build the GUI. `qmake` From 6b9afcf291cb5ab5db78f358a6213b1afc6081af Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Tue, 23 Aug 2016 10:32:01 +0300 Subject: [PATCH 76/87] extra debug logging --- main.cpp | 2 ++ src/libwalletqt/WalletManager.cpp | 17 ++++++++--------- src/libwalletqt/WalletManager.h | 14 ++++++++++++++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/main.cpp b/main.cpp index 9f109e01..d0e9e085 100644 --- a/main.cpp +++ b/main.cpp @@ -111,5 +111,7 @@ int main(int argc, char *argv[]) QObject::connect(eventFilter, SIGNAL(mousePressed(QVariant,QVariant,QVariant)), rootObject, SLOT(mousePressed(QVariant,QVariant,QVariant))); QObject::connect(eventFilter, SIGNAL(mouseReleased(QVariant,QVariant,QVariant)), rootObject, SLOT(mouseReleased(QVariant,QVariant,QVariant))); + WalletManager::instance()->setLogLevel(WalletManager::LogLevel_Max); + return app.exec(); } diff --git a/src/libwalletqt/WalletManager.cpp b/src/libwalletqt/WalletManager.cpp index da5c4cd7..947ccbfb 100644 --- a/src/libwalletqt/WalletManager.cpp +++ b/src/libwalletqt/WalletManager.cpp @@ -8,14 +8,9 @@ #include <QUrl> #include <QtConcurrent/QtConcurrent> - - WalletManager * WalletManager::m_instance = nullptr; - - - WalletManager *WalletManager::instance() { if (!m_instance) { @@ -36,9 +31,11 @@ Wallet *WalletManager::createWallet(const QString &path, const QString &password Wallet *WalletManager::openWallet(const QString &path, const QString &password, bool testnet) { - // TODO: call the libwallet api here; + qDebug("%s: opening wallet at %s, testnet = %d ", + __PRETTY_FUNCTION__, qPrintable(path), testnet); Bitmonero::Wallet * w = m_pimpl->openWallet(path.toStdString(), password.toStdString(), testnet); + qDebug("%s: opened wallet: %s, status: %d", __PRETTY_FUNCTION__, w->address().c_str(), w->status()); Wallet * wallet = new Wallet(w); // move wallet to the GUI thread. Otherwise it wont be emitting signals @@ -46,7 +43,6 @@ Wallet *WalletManager::openWallet(const QString &path, const QString &password, wallet->moveToThread(qApp->thread()); } - return wallet; } @@ -141,9 +137,12 @@ quint64 WalletManager::amountFromDouble(double amount) return Bitmonero::Wallet::amountFromDouble(amount); } +void WalletManager::setLogLevel(int logLevel) +{ + Bitmonero::WalletManagerFactory::setLogLevel(logLevel); +} + WalletManager::WalletManager(QObject *parent) : QObject(parent) { m_pimpl = Bitmonero::WalletManagerFactory::getWalletManager(); } - - diff --git a/src/libwalletqt/WalletManager.h b/src/libwalletqt/WalletManager.h index 27224b5f..1866b7cd 100644 --- a/src/libwalletqt/WalletManager.h +++ b/src/libwalletqt/WalletManager.h @@ -2,6 +2,7 @@ #define WALLETMANAGER_H #include <QObject> +#include <wallet/wallet2_api.h> class Wallet; namespace Bitmonero { @@ -12,6 +13,17 @@ class WalletManager : public QObject { Q_OBJECT public: + enum LogLevel { + LogLevel_Silent = Bitmonero::WalletManagerFactory::LogLevel_Silent, + LogLevel_0 = Bitmonero::WalletManagerFactory::LogLevel_0, + LogLevel_1 = Bitmonero::WalletManagerFactory::LogLevel_1, + LogLevel_2 = Bitmonero::WalletManagerFactory::LogLevel_2, + LogLevel_3 = Bitmonero::WalletManagerFactory::LogLevel_3, + LogLevel_4 = Bitmonero::WalletManagerFactory::LogLevel_4, + LogLevel_Min = Bitmonero::WalletManagerFactory::LogLevel_Min, + LogLevel_Max = Bitmonero::WalletManagerFactory::LogLevel_Max, + }; + static WalletManager * instance(); // wizard: createWallet path; Q_INVOKABLE Wallet * createWallet(const QString &path, const QString &password, @@ -71,6 +83,8 @@ public: Q_INVOKABLE quint64 amountFromString(const QString &amount); Q_INVOKABLE quint64 amountFromDouble(double amount); + void setLogLevel(int logLevel); + signals: void walletOpened(Wallet * wallet); From 376db6cf16910b0facf10c90afcdfe2a50fc1045 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Tue, 23 Aug 2016 11:55:51 +0300 Subject: [PATCH 77/87] Display "processing.." splashscreen while wallet initializing --- components/PasswordDialog.qml | 28 +++++++++++++++ components/ProcessingSplash.qml | 63 +++++++++++++++++++++++++++++++++ main.cpp | 3 ++ main.qml | 44 ++++++++++++++--------- qml.qrc | 1 + 5 files changed, 122 insertions(+), 17 deletions(-) create mode 100644 components/ProcessingSplash.qml diff --git a/components/PasswordDialog.qml b/components/PasswordDialog.qml index cd66d461..a8ff294a 100644 --- a/components/PasswordDialog.qml +++ b/components/PasswordDialog.qml @@ -1,3 +1,31 @@ +// Copyright (c) 2014-2015, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + import QtQuick 2.0 import QtQuick.Controls 1.4 import QtQuick.Dialogs 1.2 diff --git a/components/ProcessingSplash.qml b/components/ProcessingSplash.qml new file mode 100644 index 00000000..f98feb3b --- /dev/null +++ b/components/ProcessingSplash.qml @@ -0,0 +1,63 @@ +// Copyright (c) 2014-2015, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import QtQuick 2.0 +import QtQuick.Window 2.1 +import QtQuick.Controls 1.4 +import QtQuick.Layouts 1.1 + +Window { + id: splash + modality: Qt.ApplicationModal + flags: Qt.SplashScreen + property alias message: message.text + width: 200 + height: 100 + opacity: 0.5 + + ColumnLayout { + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + + BusyIndicator { + running: parent.visible + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + } + + Text { + id: message + text: "Please wait..." + font { + pointSize: 22 + } + horizontalAlignment: Text.AlignHCenter + } + } + + +} diff --git a/main.cpp b/main.cpp index d0e9e085..387c4b13 100644 --- a/main.cpp +++ b/main.cpp @@ -72,6 +72,8 @@ int main(int argc, char *argv[]) qRegisterMetaType<PendingTransaction::Priority>(); + + QQmlApplicationEngine engine; OSCursor cursor; @@ -83,6 +85,7 @@ int main(int argc, char *argv[]) engine.rootContext()->setContextProperty("translationManager", TranslationManager::instance()); + // export to QML monero accounts root directory // wizard is talking about where // to save the wallet file (.keys, .bin), they have to be user-accessible for diff --git a/main.qml b/main.qml index f589c666..636945e8 100644 --- a/main.qml +++ b/main.qml @@ -147,11 +147,11 @@ ApplicationWindow { walletManager.openWalletAsync(wallet_path, appWindow.password, persistentSettings.testnet); } - } function connectWallet(wallet) { + showProcessingSplash() currentWallet = wallet currentWallet.refreshed.connect(onWalletRefresh) currentWallet.updated.connect(onWalletUpdate) @@ -167,7 +167,6 @@ ApplicationWindow { function onWalletOpened(wallet) { console.log(">>> wallet opened: " + wallet) - if (wallet.status !== Wallet.Status_Ok) { if (appWindow.password === '') { console.error("Error opening wallet with empty password: ", wallet.errorString); @@ -188,7 +187,6 @@ ApplicationWindow { informationPopup.onCloseCallback = function() { passwordDialog.open() } - } return; } @@ -212,6 +210,10 @@ ApplicationWindow { function onWalletRefresh() { console.log(">>> wallet refreshed") + if (splash.visible) { + hideProcessingSplash() + } + leftPanel.networkStatus.connected = currentWallet.connected onWalletUpdate(); } @@ -297,6 +299,19 @@ ApplicationWindow { basicPanel.enabled = enable; } + function showProcessingSplash(message) { + console.log("Displaying processing splash") + if (typeof message != 'undefined') { + splash.message = message + } + splash.show() + } + + function hideProcessingSplash() { + console.log("Hiding processing splash") + splash.hide() + } + objectName: "appWindow" visible: true @@ -371,10 +386,6 @@ ApplicationWindow { onAccepted: { appWindow.currentWallet = null appWindow.initialize(); - -// var wallet_path = walletPath(); -// console.log("opening wallet with password: ", wallet_path); -// walletManager.openWalletAsync(wallet_path, password, persistentSettings.testnet); } onRejected: { appWindow.enableUI(false) @@ -384,19 +395,18 @@ ApplicationWindow { } } - Window { - id: walletInitializationSplash - modality: Qt.ApplicationModal - flags: Qt.SplashScreen - height: 100 - width: 250 - Text { - anchors.fill: parent - text: qsTr("Initializing Wallet..."); - } + + ProcessingSplash { + id: splash + width: appWindow.width / 2 + height: appWindow.height / 2 + x: (appWindow.width - width) / 2 + appWindow.x + y: (appWindow.height - height) / 2 + appWindow.y + message: qsTr("Please wait...") } + Item { id: rootItem anchors.fill: parent diff --git a/qml.qrc b/qml.qrc index dcf4b9b1..a44266b9 100644 --- a/qml.qrc +++ b/qml.qrc @@ -115,5 +115,6 @@ <file>components/IconButton.qml</file> <file>lang/flags/italy.png</file> <file>components/PasswordDialog.qml</file> + <file>components/ProcessingSplash.qml</file> </qresource> </RCC> From 4fa8ad3b199483094cf9988f33da1ab6343d7c8a Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Tue, 23 Aug 2016 16:07:52 +0300 Subject: [PATCH 78/87] Transfer page: validate amount --- components/StandardButton.qml | 11 +++++++++-- main.cpp | 2 +- main.qml | 27 +++++++++++++++++++++------ pages/Transfer.qml | 27 ++++++++++++++++----------- src/libwalletqt/WalletManager.cpp | 16 +++++++++++++--- src/libwalletqt/WalletManager.h | 11 ++++++++--- 6 files changed, 68 insertions(+), 26 deletions(-) diff --git a/components/StandardButton.qml b/components/StandardButton.qml index 208d90d3..5a088fbf 100644 --- a/components/StandardButton.qml +++ b/components/StandardButton.qml @@ -47,7 +47,10 @@ Item { height: parent.height - 1 y: buttonArea.pressed ? 0 : 1 //radius: 4 - color: buttonArea.pressed ? parent.shadowPressedColor : parent.shadowReleasedColor + color: { + parent.enabled ? (buttonArea.pressed ? parent.shadowPressedColor : parent.shadowReleasedColor) + : Qt.lighter(parent.shadowReleasedColor) + } } Rectangle { @@ -55,7 +58,11 @@ Item { anchors.right: parent.right height: parent.height - 1 y: buttonArea.pressed ? 1 : 0 - color: buttonArea.pressed ? parent.pressedColor : parent.releasedColor + color: { + parent.enabled ? (buttonArea.pressed ? parent.pressedColor : parent.releasedColor) + : Qt.lighter(parent.releasedColor) + + } //radius: 4 } diff --git a/main.cpp b/main.cpp index 387c4b13..e356659c 100644 --- a/main.cpp +++ b/main.cpp @@ -114,7 +114,7 @@ int main(int argc, char *argv[]) QObject::connect(eventFilter, SIGNAL(mousePressed(QVariant,QVariant,QVariant)), rootObject, SLOT(mousePressed(QVariant,QVariant,QVariant))); QObject::connect(eventFilter, SIGNAL(mouseReleased(QVariant,QVariant,QVariant)), rootObject, SLOT(mouseReleased(QVariant,QVariant,QVariant))); - WalletManager::instance()->setLogLevel(WalletManager::LogLevel_Max); + WalletManager::instance()->setLogLevel(WalletManager::LogLevel_Silent); return app.exec(); } diff --git a/main.qml b/main.qml index 636945e8..6d57b634 100644 --- a/main.qml +++ b/main.qml @@ -135,7 +135,7 @@ ApplicationWindow { } middlePanel.paymentClicked.connect(handlePayment); - basicPanel.paymentClicked.connect(handlePayment); + // basicPanel.paymentClicked.connect(handlePayment); // wallet already opened with wizard, we just need to initialize it @@ -240,10 +240,25 @@ ApplicationWindow { ", mixins: ", mixinCount, ", priority: ", priority); - var amountxmr = walletManager.amountFromString(amount); + // validate amount; + var amountxmr = walletManager.amountFromString(amount); console.log("integer amount: ", amountxmr); - transaction = wallet.createTransaction(address, paymentId, amountxmr, mixinCount, priority); + if (amountxmr <= 0) { + informationPopup.title = qsTr("Error") + translationManager.emptyString; + informationPopup.text = qsTr("Amount is wrong: expected number from %1 to %2") + .arg(walletManager.displayAmount(0)) + .arg(walletManager.maximumAllowedAmountAsSting()) + + translationManager.emptyString + + informationPopup.icon = StandardIcon.Critical + informationPopup.onCloseCallback = null + informationPopup.open() + return; + } + + // validate address; + transaction = currentWallet.createTransaction(address, paymentId, amountxmr, mixinCount, priority); if (transaction.status !== PendingTransaction.Status_Ok) { console.error("Can't create transaction: ", transaction.errorString); informationPopup.title = qsTr("Error") + translationManager.emptyString; @@ -252,7 +267,7 @@ ApplicationWindow { informationPopup.onCloseCallback = null informationPopup.open(); // deleting transaction object, we don't want memleaks - wallet.disposeTransaction(transaction); + currentWallet.disposeTransaction(transaction); } else { console.log("Transaction created, amount: " + walletManager.displayAmount(transaction.amount) @@ -287,8 +302,8 @@ ApplicationWindow { } informationPopup.onCloseCallback = null informationPopup.open() - wallet.refresh() - wallet.disposeTransaction(transaction) + currentWallet.refresh() + currentWallet.disposeTransaction(transaction) } // blocks UI if wallet can't be opened or no connection to the daemon diff --git a/pages/Transfer.qml b/pages/Transfer.qml index 70fde050..508b32af 100644 --- a/pages/Transfer.qml +++ b/pages/Transfer.qml @@ -32,6 +32,7 @@ import "../components" Rectangle { + id: root signal paymentClicked(string address, string paymentId, double amount, int mixinCount, int priority) @@ -88,6 +89,11 @@ Rectangle { id: amountLine placeholderText: qsTr("Amount...") + translationManager.emptyString width: parent.width - 37 - 17 + validator: DoubleValidator { + bottom: 0.0 + notation: DoubleValidator.StandardNotation + locale: "C" + } } } @@ -170,7 +176,7 @@ Rectangle { textFormat: Text.RichText text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>\ Address <font size='2'> ( Type in or select from </font> <a href='#'>Address</a><font size='2'> book )</font>") - + translationManager.emptyString + + translationManager.emptyString onLinkActivated: appWindow.showPageRequest("AddressBook") } @@ -220,7 +226,7 @@ Rectangle { anchors.topMargin: 17 fontSize: 14 text: qsTr("Description <font size='2'>( An optional description that will be saved to the local address book if entered )</font>") - + translationManager.emptyString + + translationManager.emptyString } LineEdit { @@ -245,16 +251,15 @@ Rectangle { shadowPressedColor: "#B32D00" releasedColor: "#FF6C3C" pressedColor: "#FF4304" + enabled : addressLine.text.length > 0 && amountLine.text.length > 0 onClicked: { - // do more smart validation - - if (addressLine.text.length > 0 && amountLine.text.length > 0) { - console.log("paymentClicked") - var priority = priorityModel.get(priorityDropdown.currentIndex).priority - console.log("priority: " + priority) - paymentClicked(addressLine.text, paymentIdLine.text, amountLine.text, scaleValueToMixinCount(privacyLevelItem.fillLevel), - priority) - } + console.log("Transfer: paymentClicked") + var priority = priorityModel.get(priorityDropdown.currentIndex).priority + console.log("priority: " + priority) + console.log("amount: " + amountLine.text) + root.paymentClicked(addressLine.text, paymentIdLine.text, amountLine.text, scaleValueToMixinCount(privacyLevelItem.fillLevel), + priority) } } } + diff --git a/src/libwalletqt/WalletManager.cpp b/src/libwalletqt/WalletManager.cpp index 947ccbfb..a9f332a3 100644 --- a/src/libwalletqt/WalletManager.cpp +++ b/src/libwalletqt/WalletManager.cpp @@ -122,17 +122,27 @@ QString WalletManager::walletLanguage(const QString &locale) return "English"; } -QString WalletManager::displayAmount(quint64 amount) +quint64 WalletManager::maximumAllowedAmount() const +{ + return Bitmonero::Wallet::maximumAllowedAmount(); +} + +QString WalletManager::maximumAllowedAmountAsSting() const +{ + return WalletManager::displayAmount(WalletManager::maximumAllowedAmount()); +} + +QString WalletManager::displayAmount(quint64 amount) const { return QString::fromStdString(Bitmonero::Wallet::displayAmount(amount)); } -quint64 WalletManager::amountFromString(const QString &amount) +quint64 WalletManager::amountFromString(const QString &amount) const { return Bitmonero::Wallet::amountFromString(amount.toStdString()); } -quint64 WalletManager::amountFromDouble(double amount) +quint64 WalletManager::amountFromDouble(double amount) const { return Bitmonero::Wallet::amountFromDouble(amount); } diff --git a/src/libwalletqt/WalletManager.h b/src/libwalletqt/WalletManager.h index 1866b7cd..3629242a 100644 --- a/src/libwalletqt/WalletManager.h +++ b/src/libwalletqt/WalletManager.h @@ -12,6 +12,7 @@ namespace Bitmonero { class WalletManager : public QObject { Q_OBJECT + public: enum LogLevel { LogLevel_Silent = Bitmonero::WalletManagerFactory::LogLevel_Silent, @@ -79,9 +80,13 @@ public: //! since we can't call static method from QML, move it to this class - Q_INVOKABLE QString displayAmount(quint64 amount); - Q_INVOKABLE quint64 amountFromString(const QString &amount); - Q_INVOKABLE quint64 amountFromDouble(double amount); + Q_INVOKABLE QString displayAmount(quint64 amount) const; + Q_INVOKABLE quint64 amountFromString(const QString &amount) const; + Q_INVOKABLE quint64 amountFromDouble(double amount) const; + Q_INVOKABLE quint64 maximumAllowedAmount() const; + + // QML JS engine doesn't support unsigned integers + Q_INVOKABLE QString maximumAllowedAmountAsSting() const; void setLogLevel(int logLevel); From 497a6b8de3bec6bc266246d0e02bdfbc37d64782 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev <mbg033@gmail.com> Date: Wed, 24 Aug 2016 21:31:43 +0300 Subject: [PATCH 79/87] Restored build by using develop bitmonero wallet_merged2 related issue - temporary reverted bitmonero commit that removes wallet_merged2 target --- get_libwallet_api.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/get_libwallet_api.sh b/get_libwallet_api.sh index 53ae9268..bbfdb04c 100755 --- a/get_libwallet_api.sh +++ b/get_libwallet_api.sh @@ -2,7 +2,7 @@ BITMONERO_URL=https://github.com/mbg033/bitmonero.git -BITMONERO_BRANCH=master +BITMONERO_BRANCH=develop # thanks to SO: http://stackoverflow.com/a/20283965/4118915 CPU_CORE_COUNT=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu) pushd $(pwd) @@ -17,10 +17,15 @@ if [ ! -d $BITMONERO_DIR ]; then git clone --depth=1 $BITMONERO_URL $BITMONERO_DIR --branch $BITMONERO_BRANCH --single-branch else cd $BITMONERO_DIR; + git checkout $BITMONERO_BRANCH git pull; fi +echo "cleaning up existing bitmonero build dir, libs and includes" rm -fr $BITMONERO_DIR/build +rm -fr $BITMONERO_DIR/lib +rm -fr $BITMONERO_DIR/include + mkdir -p $BITMONERO_DIR/build/release pushd $BITMONERO_DIR/build/release From 1cc7d35ab86ddd8baa8475ec1bf4fffc0cd9e004 Mon Sep 17 00:00:00 2001 From: dEBRUYNE-1 <dEBRUYNE-1@users.noreply.github.com> Date: Wed, 31 Aug 2016 18:39:44 +0200 Subject: [PATCH 80/87] Fix typo --- wizard/WizardOptions.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wizard/WizardOptions.qml b/wizard/WizardOptions.qml index 7aa3be2f..b35dbee4 100644 --- a/wizard/WizardOptions.qml +++ b/wizard/WizardOptions.qml @@ -138,7 +138,7 @@ Item { font.pixelSize: 16 color: "#4A4949" horizontalAlignment: Text.AlignHCenter - text: qsTr("I want to recover my account<br/>from my 24 work seed") + translationManager.emptyString + text: qsTr("I want to recover my account<br/>from my 25 word seed") + translationManager.emptyString } } } From efba4706ce81507322b66a5a69315c27ae0d0b27 Mon Sep 17 00:00:00 2001 From: dEBRUYNE-1 <dEBRUYNE-1@users.noreply.github.com> Date: Wed, 31 Aug 2016 18:44:10 +0200 Subject: [PATCH 81/87] Fix typo --- translations/monero-core_de.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/monero-core_de.ts b/translations/monero-core_de.ts index 24e76b60..a5d31baa 100644 --- a/translations/monero-core_de.ts +++ b/translations/monero-core_de.ts @@ -82,7 +82,7 @@ </message> <message> <location filename="../BasicPanel.qml" line="116"/> - <source>Availible Balance:</source> + <source>Available Balance:</source> <translation type="unfinished"></translation> </message> <message> From cb6bcdf507c6cdacce537e8e9fc50cd1a2169fbd Mon Sep 17 00:00:00 2001 From: dEBRUYNE-1 <dEBRUYNE-1@users.noreply.github.com> Date: Wed, 31 Aug 2016 18:44:34 +0200 Subject: [PATCH 82/87] Fix typo --- translations/monero-core_en.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/monero-core_en.ts b/translations/monero-core_en.ts index 6e8d5bcc..88083bef 100644 --- a/translations/monero-core_en.ts +++ b/translations/monero-core_en.ts @@ -82,7 +82,7 @@ </message> <message> <location filename="../BasicPanel.qml" line="116"/> - <source>Availible Balance:</source> + <source>Available Balance:</source> <translation type="unfinished"></translation> </message> <message> From f8f1d28d39f1cb8f0a8b73c7e604e72b309cbcc6 Mon Sep 17 00:00:00 2001 From: dEBRUYNE-1 <dEBRUYNE-1@users.noreply.github.com> Date: Wed, 31 Aug 2016 18:44:50 +0200 Subject: [PATCH 83/87] Fix typo --- translations/monero-core_it.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/monero-core_it.ts b/translations/monero-core_it.ts index 403d3859..b9692f7c 100644 --- a/translations/monero-core_it.ts +++ b/translations/monero-core_it.ts @@ -82,7 +82,7 @@ </message> <message> <location filename="../BasicPanel.qml" line="116"/> - <source>Availible Balance:</source> + <source>Available Balance:</source> <translation type="unfinished"></translation> </message> <message> From f66a7651524ec671e74f785b8011b3b92bf676c7 Mon Sep 17 00:00:00 2001 From: dEBRUYNE-1 <dEBRUYNE-1@users.noreply.github.com> Date: Wed, 31 Aug 2016 18:45:12 +0200 Subject: [PATCH 84/87] Fix typo --- translations/monero-core_pl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/monero-core_pl.ts b/translations/monero-core_pl.ts index bb152986..c7c6c0cd 100644 --- a/translations/monero-core_pl.ts +++ b/translations/monero-core_pl.ts @@ -82,7 +82,7 @@ </message> <message> <location filename="../BasicPanel.qml" line="116"/> - <source>Availible Balance:</source> + <source>Available Balance:</source> <translation type="unfinished"></translation> </message> <message> From 93285c233095d8f4648bb02bac49d86b618f9ec0 Mon Sep 17 00:00:00 2001 From: dEBRUYNE-1 <dEBRUYNE-1@users.noreply.github.com> Date: Wed, 31 Aug 2016 18:45:35 +0200 Subject: [PATCH 85/87] Fix typo --- translations/monero-core_ru.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/monero-core_ru.ts b/translations/monero-core_ru.ts index 5ca9c499..acce20ed 100644 --- a/translations/monero-core_ru.ts +++ b/translations/monero-core_ru.ts @@ -82,7 +82,7 @@ </message> <message> <location filename="../BasicPanel.qml" line="116"/> - <source>Availible Balance:</source> + <source>Available Balance:</source> <translation type="unfinished"></translation> </message> <message> From 5d17513ef29d4ec4ca6c9b3462311a1ec002436e Mon Sep 17 00:00:00 2001 From: dEBRUYNE-1 <dEBRUYNE-1@users.noreply.github.com> Date: Wed, 31 Aug 2016 18:46:58 +0200 Subject: [PATCH 86/87] Fix typo --- translations/monero-core_zh.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/monero-core_zh.ts b/translations/monero-core_zh.ts index 14f60021..9d0645ae 100644 --- a/translations/monero-core_zh.ts +++ b/translations/monero-core_zh.ts @@ -82,7 +82,7 @@ </message> <message> <location filename="../BasicPanel.qml" line="116"/> - <source>Availible Balance:</source> + <source>Available Balance:</source> <translation type="unfinished"></translation> </message> <message> From c519c7efb187be26680588f276cbc6d78814f3d1 Mon Sep 17 00:00:00 2001 From: dEBRUYNE-1 <dEBRUYNE-1@users.noreply.github.com> Date: Wed, 31 Aug 2016 18:47:56 +0200 Subject: [PATCH 87/87] Fix typo --- BasicPanel.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BasicPanel.qml b/BasicPanel.qml index abeb135c..07aeb080 100644 --- a/BasicPanel.qml +++ b/BasicPanel.qml @@ -131,7 +131,7 @@ Rectangle { horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignBottom color: "#535353" - text: qsTr("Availible Balance:") + text: qsTr("Available Balance:") } Text {