Merge pull request #2 from szogun1987/master

Refresh with drop
This commit is contained in:
Wojciech Gomoła 2018-01-28 15:30:37 +01:00 committed by GitHub
commit 5adc39915e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
132 changed files with 28470 additions and 12053 deletions

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
Copyright (c) 2014-2017, The Monero Project
Copyright (c) 2014-2018, The Monero Project
All rights reserved.

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//
@ -112,7 +112,7 @@ Rectangle {
}, State {
name: "Receive"
PropertyChanges { target: root; currentView: receiveView }
PropertyChanges { target: mainFlickable; contentHeight: minHeight }
PropertyChanges { target: mainFlickable; contentHeight: 1000 * scaleRatio }
}, State {
name: "TxKey"
PropertyChanges { target: root; currentView: txkeyView }

View File

@ -1,8 +1,8 @@
# Monero GUI
Copyright (c) 2014-2017, The Monero Project
Copyright (c) 2014-2018, The Monero Project
## Development Resources
## Development resources
- Web: [getmonero.org](https://getmonero.org)
- Forum: [forum.getmonero.org](https://forum.getmonero.org)
@ -33,9 +33,7 @@ As with many development projects, the repository on Github is considered to be
## Supporting the project
Monero development can be supported directly through donations.
Both Monero and Bitcoin donations can be made to **donate.getmonero.org** if using a client that supports the [OpenAlias](https://openalias.org) standard.
Monero is a 100% community-sponsored endeavor. If you want to join our efforts, the easiest thing you can do is support the project financially. Both Monero and Bitcoin donations can be made to **donate.getmonero.org** if using a client that supports the [OpenAlias](https://openalias.org) standard.
The Monero donation address is: `44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A` (viewkey: `f359631075708155cc3d92a32b75a7d02a5dcf27756707b47a2b31b21c389501`)

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
Copyright (c) 2014-2017, The Monero Project
Copyright (c) 2014-2018, The Monero Project
## Current status : ALPHA
@ -22,7 +22,7 @@ Copyright (c) 2014-2017, The Monero Project
# Get the apk
docker cp monero-gui-android:/opt/android/monero-core/build/release/bin/bin/QtApp-debug.apk .
docker cp monero-gui-android:/opt/android/monero-gui/build/release/bin/bin/QtApp-debug.apk .
## Deployment
@ -31,7 +31,7 @@ Copyright (c) 2014-2017, The Monero Project
First, see section [Enable adb debugging on your device](https://developer.android.com/studio/command-line/adb.html#Enabling)
The only place where we are allowed to play is `/data/local/tmp`. So :
adb push /opt/android/monero-core/build/release/bin/bin/QtApp-debug.apk /data/local/tmp
adb push /opt/android/monero-gui/build/release/bin/bin/QtApp-debug.apk /data/local/tmp
adb shell pm install -r /data/local/tmp/QtApp-debug.apk
- Troubleshooting:

View File

@ -88,21 +88,20 @@ APP_CFLAGS += -target armv7-none-linux-androideabi -fexceptions -fstack-protect
&& android update project --path . -t "${ANDROID_API}" \
&& CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ ant -Dndk.dir=${ANDROID_NDK_ROOT} -Diconv.src=${WORKDIR}/libiconv-${ICONV_VERSION} zbar-clean zbar-ndk-build
#Can't directly call build.sh because of env variables
RUN git clone https://github.com/monero-project/monero-core.git \
&& cd monero-core \
&& git submodule update \
&& CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ BOOST_ROOT=/opt/android/boost_1_62_0 BOOST_LIBRARYDIR=${WORKDIR}/boost_${BOOST_VERSION}/android32/lib/ OPENSSL_ROOT_DIR=${WORKDIR}/openssl/ ./get_libwallet_api.sh release-android
RUN cp openssl/lib* ${ANDROID_NDK_ROOT}/platforms/${ANDROID_API}/arch-arm/usr/lib
RUN cp boost_${BOOST_VERSION}/android32/lib/lib* ${ANDROID_NDK_ROOT}/platforms/${ANDROID_API}/arch-arm/usr/lib
RUN cp ZBar/android/obj/local/armeabi-v7a/lib* ${ANDROID_NDK_ROOT}/platforms/${ANDROID_API}/arch-arm/usr/lib
ENV PATH $ANDROID_SDK_ROOT/tools:$ANDROID_SDK_ROOT/platform-tools:${WORKDIR}/Qt-${QT_VERSION}/bin:$CLEAN_PATH
# NB : zxcvbn-c needs to build a local binary and Qt don't care about these environnement variable
RUN cd monero-core \
&& CC="gcc" CXX="g++" ./build.sh release-android \
RUN git clone https://github.com/monero-project/monero-gui.git \
&& cd monero-gui \
&& git submodule update \
&& CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ BOOST_ROOT=/opt/android/boost_1_62_0 \
BOOST_LIBRARYDIR=${WORKDIR}/boost_${BOOST_VERSION}/android32/lib/ \
OPENSSL_ROOT_DIR=${WORKDIR}/openssl/ \
CMAKE_INCLUDE_PATH=${WORKDIR}/cppzmq/ \
CMAKE_LIBRARY_PATH=${WORKDIR}/zeromq4-1/.libs \
CXXFLAGS="-I ${WORKDIR}/zeromq4-1/include/" \
./build.sh release-android \
&& cd build \
&& make deploy

View File

@ -8,6 +8,22 @@ if [ -z $BUILD_TYPE ]; then
BUILD_TYPE=release
fi
# Return 0 if the command exists, 1 if it does not.
exists() {
command -v "$1" &>/dev/null
}
# Return the first value in $@ that's a runnable command.
find_command() {
for arg in "$@"; do
if exists "$arg"; then
echo "$arg"
return 0
fi
done
return 1
}
if [ "$BUILD_TYPE" == "release" ]; then
echo "Building release"
CONFIG="CONFIG+=release";
@ -24,14 +40,16 @@ elif [ "$BUILD_TYPE" == "release-static" ]; then
BIN_PATH=release/bin
elif [ "$BUILD_TYPE" == "release-android" ]; then
echo "Building release for ANDROID"
CONFIG="CONFIG+=release static WITH_SCANNER";
CONFIG="CONFIG+=release static WITH_SCANNER DISABLE_PASS_STRENGTH_METER";
ANDROID=true
BIN_PATH=release/bin
DISABLE_PASS_STRENGTH_METER=true
elif [ "$BUILD_TYPE" == "debug-android" ]; then
echo "Building debug for ANDROID : ultra INSECURE !!"
CONFIG="CONFIG+=debug qml_debug WITH_SCANNER";
CONFIG="CONFIG+=debug qml_debug WITH_SCANNER DISABLE_PASS_STRENGTH_METER";
ANDROID=true
BIN_PATH=debug/bin
DISABLE_PASS_STRENGTH_METER=true
elif [ "$BUILD_TYPE" == "debug" ]; then
echo "Building debug"
CONFIG="CONFIG+=debug"
@ -57,15 +75,17 @@ fi
./get_libwallet_api.sh $BUILD_TYPE
# build zxcvbn
$MAKE -C src/zxcvbn-c || exit
if [ "$DISABLE_PASS_STRENGTH_METER" != true ]; then
$MAKE -C src/zxcvbn-c || exit
fi
if [ ! -d build ]; then mkdir build; fi
# Platform indepenent settings
if [ "$ANDROID" != true ] && ([ "$platform" == "linux32" ] || [ "$platform" == "linux64" ]); then
distro=$(lsb_release -is)
if [ "$distro" == "Ubuntu" ]; then
exists lsb_release && distro="$(lsb_release -is)"
if [ "$distro" = "Ubuntu" ] || [ "$distro" = "Fedora" ] || test -f /etc/fedora-release; then
CONFIG="$CONFIG libunwind_off"
fi
fi
@ -85,7 +105,11 @@ popd
echo "var GUI_MONERO_VERSION = \"$TAGNAME\"" >> version.js
cd build
qmake ../monero-wallet-gui.pro "$CONFIG" || exit
if ! QMAKE=$(find_command qmake qmake-qt5); then
echo "Failed to find suitable qmake command."
exit 1
fi
$QMAKE ../monero-wallet-gui.pro "$CONFIG" || exit
$MAKE || exit
# Copy monerod to bin folder

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//
@ -260,10 +260,51 @@ ListView {
return blockHeight
if (!isOut)
return qsTr("UNCONFIRMED") + translationManager.emptyString
if (isFailed)
return qsTr("FAILED") + translationManager.emptyString
return qsTr("PENDING") + translationManager.emptyString
}
}
Item { //separator
width: 100
height: 14
}
// -- "Received by" title
Text {
anchors.bottom: parent.bottom
font.family: "Arial"
font.pixelSize: 12
color: "#535353"
text: (isOut ? qsTr("Spent from:") : qsTr("Received by:")) + translationManager.emptyString
}
Item { //separator
width: 5
height: 14
}
// -- "Index" value
Text {
anchors.bottom: parent.bottom
font.family: "Arial"
font.pixelSize: 13
font.bold: true
color: "#545454"
text: "#" + subaddrIndex
}
Item { //separator
width: 5
height: 14
}
// -- "Label" value
Text {
anchors.bottom: parent.bottom
font.family: "Arial"
font.pixelSize: 13
color: "#545454"
text: label
elide: Text.ElideRight
width: detailsButton.x - x - 30
}
}
// -- "Date", "Balance" and "Amound" section

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2017, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//
@ -150,6 +150,8 @@ ListView {
return qsTr("(%1/%2 confirmations)").arg(confirmations).arg(confirmationsRequired)
if (!isOut)
return qsTr("UNCONFIRMED") + translationManager.emptyString
if (isFailed)
return qsTr("FAILED") + translationManager.emptyString
return qsTr("PENDING") + translationManager.emptyString
}

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//
@ -30,6 +30,7 @@
import QtQuick 2.0
Item {
property alias image : buttonImage
property alias imageSource : buttonImage.source
signal clicked(var mouse)
@ -53,7 +54,8 @@ Item {
MouseArea {
id: buttonArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: {
buttonImage.x = buttonImage.x + 2

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

181
components/InputDialog.qml Normal file
View File

@ -0,0 +1,181 @@
// Copyright (c) 2014-2018, 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
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.4
import QtQuick.Window 2.0
import "../components" as MoneroComponents
Item {
id: root
visible: false
Rectangle {
id: bg
z: parent.z + 1
anchors.fill: parent
color: "white"
opacity: 0.9
}
property alias labelText: label.text
property alias inputText: input.text
// same signals as Dialog has
signal accepted()
signal rejected()
function open() {
leftPanel.enabled = false
middlePanel.enabled = false
titleBar.enabled = false
show()
root.visible = true;
input.focus = true;
input.text = "";
}
function close() {
leftPanel.enabled = true
middlePanel.enabled = true
titleBar.enabled = true
root.visible = false;
}
ColumnLayout {
z: bg.z + 1
id: mainLayout
spacing: 10
anchors { fill: parent; margins: 35 }
ColumnLayout {
id: column
//anchors {fill: parent; margins: 16 }
Layout.alignment: Qt.AlignHCenter
Label {
id: label
Layout.alignment: Qt.AlignHCenter
// Layout.columnSpan: 2
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 18 * scaleRatio
font.family: "Arial"
color: "#555555"
}
TextField {
id : input
focus: true
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: TextInput.AlignHCenter
verticalAlignment: TextInput.AlignVCenter
font.family: "Arial"
font.pixelSize: 32 * scaleRatio
// echoMode: TextInput.Password
KeyNavigation.tab: okButton
style: TextFieldStyle {
renderType: Text.NativeRendering
textColor: "#35B05A"
// passwordCharacter: ""
// no background
background: Rectangle {
radius: 0
border.width: 0
}
}
Keys.onReturnPressed: {
root.close()
root.accepted()
}
Keys.onEscapePressed: {
root.close()
root.rejected()
}
}
// underline
Rectangle {
height: 1
color: "#DBDBDB"
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
anchors.bottomMargin: 3
}
// padding
Rectangle {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
height: 10
opacity: 0
color: "black"
}
}
// Ok/Cancel buttons
RowLayout {
id: buttons
spacing: 60
Layout.alignment: Qt.AlignHCenter
MoneroComponents.StandardButton {
id: cancelButton
width: 120
fontSize: 14
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("Cancel") + translationManager.emptyString
KeyNavigation.tab: input
onClicked: {
root.close()
root.rejected()
}
}
MoneroComponents.StandardButton {
id: okButton
width: 120
fontSize: 14
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("Ok")
KeyNavigation.tab: cancelButton
onClicked: {
root.close()
root.accepted()
}
}
}
}
}

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//
@ -37,6 +37,7 @@ Item {
property alias cursorPosition: input.cursorPosition
property alias echoMode: input.echoMode
property int fontSize: 18 * scaleRatio
property bool showBorder: true
property bool error: false
signal editingFinished()
signal accepted();
@ -52,6 +53,7 @@ Item {
}
Rectangle {
visible: showBorder
anchors.fill: parent
anchors.bottomMargin: 1 * scaleRatio
color: "#DBDBDB"

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -0,0 +1,254 @@
// Copyright (c) 2017, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.4
import QtQuick.Window 2.0
import "../components" as MoneroComponents
Item {
id: root
visible: false
Rectangle {
id: bg
z: parent.z + 1
anchors.fill: parent
color: "white"
opacity: 0.9
}
property alias password: passwordInput1.text
// same signals as Dialog has
signal accepted()
signal rejected()
signal closeCallback()
function open() {
leftPanel.enabled = false
middlePanel.enabled = false
titleBar.enabled = false
show();
root.visible = true;
passwordInput1.text = "";
passwordInput2.text = "";
passwordInput1.focus = true
}
function close() {
leftPanel.enabled = true
middlePanel.enabled = true
titleBar.enabled = true
root.visible = false;
closeCallback();
}
// TODO: implement without hardcoding sizes
width: 480
height: 360
// Make window draggable
MouseArea {
anchors.fill: parent
property point lastMousePos: Qt.point(0, 0)
onPressed: { lastMousePos = Qt.point(mouseX, mouseY); }
onMouseXChanged: root.x += (mouseX - lastMousePos.x)
onMouseYChanged: root.y += (mouseY - lastMousePos.y)
}
ColumnLayout {
z: bg.z + 1
id: mainLayout
spacing: 10
anchors { fill: parent; margins: 35 * scaleRatio }
ColumnLayout {
id: column
//anchors {fill: parent; margins: 16 }
Layout.alignment: Qt.AlignHCenter
Label {
text: qsTr("Please enter new password")
Layout.alignment: Qt.AlignHCenter
Layout.columnSpan: 2
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 18 * scaleRatio
font.family: "Arial"
color: "#555555"
}
TextField {
id : passwordInput1
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
Layout.maximumWidth: 400 * scaleRatio
horizontalAlignment: TextInput.AlignHCenter
verticalAlignment: TextInput.AlignVCenter
font.family: "Arial"
font.pixelSize: 32 * scaleRatio
echoMode: TextInput.Password
KeyNavigation.tab: passwordInput2
style: TextFieldStyle {
renderType: Text.NativeRendering
textColor: "#35B05A"
passwordCharacter: "•"
// no background
background: Rectangle {
radius: 0
border.width: 0
}
}
Keys.onEscapePressed: {
root.close()
root.rejected()
}
}
// underline
Rectangle {
height: 1
color: "#DBDBDB"
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
anchors.bottomMargin: 3
Layout.maximumWidth: passwordInput1.width
}
// padding
Rectangle {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
height: 10
opacity: 0
color: "black"
}
Label {
text: qsTr("Please confirm new password")
Layout.alignment: Qt.AlignHCenter
Layout.columnSpan: 2
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 18 * scaleRatio
font.family: "Arial"
color: "#555555"
}
TextField {
id : passwordInput2
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
Layout.maximumWidth: 400 * scaleRatio
horizontalAlignment: TextInput.AlignHCenter
verticalAlignment: TextInput.AlignVCenter
font.family: "Arial"
font.pixelSize: 32 * scaleRatio
echoMode: TextInput.Password
KeyNavigation.tab: okButton
style: TextFieldStyle {
renderType: Text.NativeRendering
textColor: "#35B05A"
passwordCharacter: "•"
// no background
background: Rectangle {
radius: 0
border.width: 0
}
}
Keys.onReturnPressed: {
if (passwordInput1.text === passwordInput2.text) {
root.close()
root.accepted()
}
}
Keys.onEscapePressed: {
root.close()
root.rejected()
}
}
// underline
Rectangle {
height: 1
color: "#DBDBDB"
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
anchors.bottomMargin: 3
Layout.maximumWidth: passwordInput1.width
}
// padding
Rectangle {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
height: 10
opacity: 0
color: "black"
}
}
// Ok/Cancel buttons
RowLayout {
id: buttons
spacing: 60 * scaleRatio
Layout.alignment: Qt.AlignHCenter
MoneroComponents.StandardButton {
id: cancelButton
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("Cancel") + translationManager.emptyString
KeyNavigation.tab: passwordInput1
onClicked: {
root.close()
root.rejected()
}
}
MoneroComponents.StandardButton {
id: okButton
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("Continue")
KeyNavigation.tab: cancelButton
enabled: passwordInput1.text === passwordInput2.text
onClicked: {
root.close()
root.accepted()
}
}
}
}
}

View File

@ -1,4 +1,4 @@
// Copyright (c) 2017, The Monero Project
// Copyright (c) 2017-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2017, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2017, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -0,0 +1,109 @@
// Copyright (c) 2014-2018, 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 moneroComponents.Clipboard 1.0
ListView {
id: listView
clip: true
boundsBehavior: ListView.StopAtBounds
highlightMoveDuration: 0
delegate: Rectangle {
id: delegate
height: 64
width: listView.width
LineEdit {
id: addressLine
fontSize: 12
readOnly: true
width: parent.width
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 5
onTextChanged: cursorPosition = 0
text: address
showBorder: false
IconButton {
id: clipboardButton
imageSource: "../images/copyToClipboard.png"
onClicked: {
console.log(addressLine.text + " copied to clipboard");
clipboard.setText(addressLine.text);
appWindow.showStatusMessage(qsTr("Address copied to clipboard"),3);
}
}
}
Text {
id: indexText
anchors.top: addressLine.bottom
anchors.left: parent.left
anchors.leftMargin: 20
font.family: "Arial"
font.bold: true
font.pixelSize: 12
color: "#444444"
text: "#" + index
}
Text {
id: labelText
anchors.top: addressLine.bottom
anchors.left: indexText.right
anchors.right: parent.right
anchors.leftMargin: 10
font.family: "Arial"
font.bold: true
font.pixelSize: 12
color: "#444444"
text: label
}
MouseArea {
z: 5
anchors.top: parent.top
anchors.left: parent.left
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.rightMargin: clipboardButton.width
onClicked: listView.currentIndex = index
}
}
highlight: Rectangle {
height: 64
color: '#FF4304'
opacity: 0.2
z: 2
}
}

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
Copyright (c) 2014-2017, The Monero Project
Copyright (c) 2014-2018, The Monero Project
All rights reserved.

View File

@ -1,5 +1,5 @@
; Monero Helium Hydra GUI Wallet Installer for Windows
; Copyright (c) 2014-2017, The Monero Project
; Copyright (c) 2014-2018, The Monero Project
; See LICENSE
[Setup]
@ -33,173 +33,187 @@ Name: "en"; MessagesFile: "compiler:Default.isl"
[Files]
Source: "ReadMe.htm"; DestDir: "{app}"; Flags: comparetimestamp
; The use of the flag "ignoreversion" for the following entries leads to the following behaviour:
; When updating / upgrading an existing installation ALL existing files are replaced with the files in this
; installer, regardless of file dates, version info within the files, or type of file (textual file or
; .exe/.dll file possibly with version info).
;
; This is far more robust than relying on version info or on file dates (flag "comparetimestamp").
; As of version 0.11.1.0, the Monero .exe files do not carry version info anyway in their .exe headers.
; The only small drawback seems to be somewhat longer update times because each and every file is
; copied again, even if already present with correct file date and identical content.
;
; Note that it would be very dangerous to use "ignoreversion" on files that may be shared with other
; applications somehow. Luckily this is no issue here because ALL files are "private" to Monero.
Source: "ReadMe.htm"; DestDir: "{app}"; Flags: ignoreversion
Source: "FinishImage.bmp"; Flags: dontcopy
; Monero GUI wallet
Source: "bin\monero-wallet-gui.exe"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\monero-wallet-gui.exe"; DestDir: "{app}"; Flags: ignoreversion
; Monero GUI wallet log file
; The GUI wallet does not have the "--log-file" command-line option of the CLI wallet and insists to put the .log beside the .exe
; so pre-create the file and give the necessary permissions to the wallet to write into it
Source: "monero-wallet-gui.log"; DestDir: "{app}"; Flags: comparetimestamp; Permissions: users-modify
; Flag is "onlyifdoesntexist": We do not want to overwrite an already existing log
Source: "monero-wallet-gui.log"; DestDir: "{app}"; Flags: onlyifdoesntexist; Permissions: users-modify
; Monero CLI wallet
Source: "bin\monero-wallet-cli.exe"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\monero-wallet-cli.exe"; DestDir: "{app}"; Flags: ignoreversion
; Monero wallet RPC interface implementation
Source: "bin\monero-wallet-rpc.exe"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\monero-wallet-rpc.exe"; DestDir: "{app}"; Flags: ignoreversion
; Monero daemon
Source: "bin\monerod.exe"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\monerod.exe"; DestDir: "{app}"; Flags: ignoreversion
; Monero daemon wrapped in a batch file that stops before the text window closes, to see any error messages
Source: "monero-daemon.bat"; DestDir: "{app}"; Flags: comparetimestamp;
Source: "monero-daemon.bat"; DestDir: "{app}"; Flags: ignoreversion;
; Monero blockchain utilities
Source: "bin\monero-blockchain-export.exe"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\monero-blockchain-import.exe"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\monero-blockchain-export.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\monero-blockchain-import.exe"; DestDir: "{app}"; Flags: ignoreversion
; was present in 0.10.3.1, not present anymore in 0.11.1.0
; Source: "bin\monero-utils-deserialize.exe"; DestDir: "{app}"; Flags: comparetimestamp
; Source: "bin\monero-utils-deserialize.exe"; DestDir: "{app}"; Flags: ignoreversion
; Various .qm files for translating the wallet UI "on the fly" into all supported languages
Source: "bin\translations\*"; DestDir: "{app}\translations"; Flags: recursesubdirs comparetimestamp
Source: "bin\translations\*"; DestDir: "{app}\translations"; Flags: recursesubdirs ignoreversion
; Core Qt runtime
Source: "bin\Qt5Core.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\Qt5Gui.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\Qt5Multimedia.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\Qt5MultimediaQuick_p.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\Qt5Network.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\Qt5Qml.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\Qt5Quick.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\Qt5Svg.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\Qt5Widgets.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\Qt5XmlPatterns.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\Qt5Core.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\Qt5Gui.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\Qt5Multimedia.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\Qt5MultimediaQuick_p.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\Qt5Network.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\Qt5Qml.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\Qt5Quick.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\Qt5Svg.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\Qt5Widgets.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\Qt5XmlPatterns.dll"; DestDir: "{app}"; Flags: ignoreversion
; Qt QML elements like the local files selector "FolderListModel" and "Settings"
Source: "bin\Qt\*"; DestDir: "{app}\Qt"; Flags: recursesubdirs comparetimestamp
Source: "bin\Qt\*"; DestDir: "{app}\Qt"; Flags: recursesubdirs ignoreversion
; Qt audio support
Source: "bin\audio\*"; DestDir: "{app}\audio"; Flags: recursesubdirs comparetimestamp
Source: "bin\audio\*"; DestDir: "{app}\audio"; Flags: recursesubdirs ignoreversion
; Qt bearer / network connection management
Source: "bin\bearer\*"; DestDir: "{app}\bearer"; Flags: recursesubdirs comparetimestamp
Source: "bin\bearer\*"; DestDir: "{app}\bearer"; Flags: recursesubdirs ignoreversion
; Qt Windows platform plugin
Source: "bin\platforms\qwindows.dll"; DestDir: "{app}\platforms"; Flags: comparetimestamp
Source: "bin\platforms\qwindows.dll"; DestDir: "{app}\platforms"; Flags: ignoreversion
; Qt support for SVG icons
Source: "bin\iconengines\*"; DestDir: "{app}\iconengines"; Flags: recursesubdirs comparetimestamp
Source: "bin\iconengines\*"; DestDir: "{app}\iconengines"; Flags: recursesubdirs ignoreversion
; Qt support for various image formats (JPEG, BMP, SVG etc)
Source: "bin\imageformats\*"; DestDir: "{app}\imageformats"; Flags: recursesubdirs comparetimestamp
Source: "bin\imageformats\*"; DestDir: "{app}\imageformats"; Flags: recursesubdirs ignoreversion
; Qt multimedia support
Source: "bin\QtMultimedia\*"; DestDir: "{app}\QtMultimedia"; Flags: recursesubdirs comparetimestamp
Source: "bin\mediaservice\*"; DestDir: "{app}\mediaservice"; Flags: recursesubdirs comparetimestamp
Source: "bin\QtMultimedia\*"; DestDir: "{app}\QtMultimedia"; Flags: recursesubdirs ignoreversion
Source: "bin\mediaservice\*"; DestDir: "{app}\mediaservice"; Flags: recursesubdirs ignoreversion
; Qt support for "m3u" playlists
; candidate for elimination? Don't think the GUI wallet needs such playlists
Source: "bin\playlistformats\*"; DestDir: "{app}\playlistformats"; Flags: recursesubdirs comparetimestamp
Source: "bin\playlistformats\*"; DestDir: "{app}\playlistformats"; Flags: recursesubdirs ignoreversion
; Qt graphical effects as part of the core runtime, effects like blurring and blending
Source: "bin\QtGraphicalEffects\*"; DestDir: "{app}\QtGraphicalEffects"; Flags: recursesubdirs comparetimestamp
Source: "bin\QtGraphicalEffects\*"; DestDir: "{app}\QtGraphicalEffects"; Flags: recursesubdirs ignoreversion
; Some more Qt graphical effects
; "private" as a name for this directory looks a little strange. Historical reasons?
Source: "bin\private\*"; DestDir: "{app}\private"; Flags: recursesubdirs comparetimestamp
Source: "bin\private\*"; DestDir: "{app}\private"; Flags: recursesubdirs ignoreversion
; Qt QML files
Source: "bin\QtQml\*"; DestDir: "{app}\QtQml"; Flags: recursesubdirs comparetimestamp
Source: "bin\QtQml\*"; DestDir: "{app}\QtQml"; Flags: recursesubdirs ignoreversion
; Qt Quick files
Source: "bin\QtQuick\*"; DestDir: "{app}\QtQuick"; Flags: recursesubdirs comparetimestamp
Source: "bin\QtQuick.2\*"; DestDir: "{app}\QtQuick.2"; Flags: recursesubdirs comparetimestamp
Source: "bin\QtQuick\*"; DestDir: "{app}\QtQuick"; Flags: recursesubdirs ignoreversion
Source: "bin\QtQuick.2\*"; DestDir: "{app}\QtQuick.2"; Flags: recursesubdirs ignoreversion
; Qt Quick 2D Renderer fallback for systems / environments with "low-level graphics" i.e. without 3D support
Source: "bin\scenegraph\*"; DestDir: "{app}\scenegraph"; Flags: recursesubdirs comparetimestamp
Source: "bin\start-low-graphics-mode.bat"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\scenegraph\*"; DestDir: "{app}\scenegraph"; Flags: recursesubdirs ignoreversion
Source: "bin\start-low-graphics-mode.bat"; DestDir: "{app}"; Flags: ignoreversion
; Mesa, open-source OpenGL implementation; part of "low-level graphics" support
Source: "bin\opengl32sw.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\opengl32sw.dll"; DestDir: "{app}"; Flags: ignoreversion
; Left out subdirectory "qmltooling" with the Qt QML debugger: Probably not relevant in an end-user package
; Microsoft Direct3D runtime
Source: "bin\D3Dcompiler_47.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\D3Dcompiler_47.dll"; DestDir: "{app}"; Flags: ignoreversion
; bzip2 support
Source: "bin\libbz2-1.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libbz2-1.dll"; DestDir: "{app}"; Flags: ignoreversion
; ANGLE ("Almost Native Graphics Layer Engine") support, as used by Qt
Source: "bin\libEGL.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libGLESV2.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libEGL.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\libGLESV2.dll"; DestDir: "{app}"; Flags: ignoreversion
; FreeType font engine, as used by Qt
Source: "bin\libfreetype-6.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libfreetype-6.dll"; DestDir: "{app}"; Flags: ignoreversion
; GCC runtime, x64 version
Source: "bin\libgcc_s_seh-1.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libgcc_s_seh-1.dll"; DestDir: "{app}"; Flags: ignoreversion
; GLib, low level core library e.g. for GNOME and GTK+
; Really needed under Windows?
Source: "bin\libglib-2.0-0.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libglib-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion
; Graphite font support
; Really needed?
Source: "bin\libgraphite2.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libgraphite2.dll"; DestDir: "{app}"; Flags: ignoreversion
; HarfBuzz OpenType text shaping engine
; Really needed?
Source: "bin\libharfbuzz-0.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libharfbuzz-0.dll"; DestDir: "{app}"; Flags: ignoreversion
; LibIconv, conversions between character encodings
Source: "bin\libiconv-2.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libiconv-2.dll"; DestDir: "{app}"; Flags: ignoreversion
; Part of cygwin? Needed by Qt somehow?
Source: "bin\libicudt57.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libicuin57.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libicuuc57.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libicudt57.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\libicuin57.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\libicuuc57.dll"; DestDir: "{app}"; Flags: ignoreversion
; Library for native language support, part of GNU gettext
Source: "bin\libintl-8.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libintl-8.dll"; DestDir: "{app}"; Flags: ignoreversion
; JasPer, support for JPEG-2000
; was present in 0.10.3.1, not present anymore in 0.11.1.0
; Source: "bin\libjasper-1.dll"; DestDir: "{app}"; Flags: comparetimestamp
; Source: "bin\libjasper-1.dll"; DestDir: "{app}"; Flags: ignoreversion
; libjpeg, C library for reading and writing JPEG image files
Source: "bin\libjpeg-8.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libjpeg-8.dll"; DestDir: "{app}"; Flags: ignoreversion
; Little CMS, color management system
Source: "bin\liblcms2-2.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\liblcms2-2.dll"; DestDir: "{app}"; Flags: ignoreversion
; XZ Utils, LZMA compression library
Source: "bin\liblzma-5.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\liblzma-5.dll"; DestDir: "{app}"; Flags: ignoreversion
; MNG / Portable Network Graphics ("animated PNG")
Source: "bin\libmng-2.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libmng-2.dll"; DestDir: "{app}"; Flags: ignoreversion
; PCRE, Perl Compatible Regular Expressions
Source: "bin\libpcre-1.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libpcre16-0.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libpcre-1.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\libpcre16-0.dll"; DestDir: "{app}"; Flags: ignoreversion
; libpng, the official PNG reference library
Source: "bin\libpng16-16.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libpng16-16.dll"; DestDir: "{app}"; Flags: ignoreversion
; libstdc++, GNU Standard C++ Library
Source: "bin\libstdc++-6.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libstdc++-6.dll"; DestDir: "{app}"; Flags: ignoreversion
; LibTIFF, TIFF Library and Utilities
Source: "bin\libtiff-5.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libtiff-5.dll"; DestDir: "{app}"; Flags: ignoreversion
; C++ threading support
Source: "bin\libwinpthread-1.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\libwinpthread-1.dll"; DestDir: "{app}"; Flags: ignoreversion
; zlib compression library
Source: "bin\zlib1.dll"; DestDir: "{app}"; Flags: comparetimestamp
Source: "bin\zlib1.dll"; DestDir: "{app}"; Flags: ignoreversion
[Tasks]

View File

@ -1,6 +1,6 @@
# Monero GUI Wallet Windows Installer #
Copyright (c) 2014-2017, The Monero Project
Copyright (c) 2014-2018, The Monero Project
## Introduction ##

View File

@ -6,7 +6,7 @@
<body style="font-family: Arial, Helvetica, sans-serif">
<h1>Monero Helium Hydra GUI Wallet</h1>
<p>Copyright (c) 2014-2017, The Monero Project<br>
<p>Copyright (c) 2014-2018, The Monero Project<br>
Date: September 19, 2017</p>
<h2>Preface</h2>

BIN
lang/flags/czech.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
lang/flags/denmark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
lang/flags/egypt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
lang/flags/slovakia.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -38,4 +38,8 @@ List of available languages for your wallet's seed:
<language display_name="עברית" locale="he_HE" wallet_language="English" flag="/lang/flags/israel.png" qs="none"/>
<language display_name="한국어" locale="ko_KO" wallet_language="English" flag="/lang/flags/south_korea.png" qs="none"/>
<language display_name="Română" locale="ro_RO" wallet_language="English" flag="/lang/flags/romania.png" qs="none"/>
<language display_name="Dansk" locale="da_DK" wallet-language="English" flag="/lang/flags/denmark.png" qs="none"/>
<language display_name="Česky" locale="cs_CZ" wallet_language="English" flag="/lang/flags/czech.png" qs="none"/>
<language display_name="Slovensky" locale="sk_SK" wallet_language="English" flag="/lang/flags/slovakia.png" qs="none"/>
<language display_name="Arabic" locale="ar_AR" wallet_language="English" flag="/lang/flags/egypt.png" qs="none"/>
</languages>

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//
@ -50,6 +50,8 @@
#include "model/TransactionHistorySortFilterModel.h"
#include "AddressBook.h"
#include "model/AddressBookModel.h"
#include "Subaddress.h"
#include "model/SubaddressModel.h"
#include "wallet/api/wallet2_api.h"
#include "MainApp.h"
@ -70,6 +72,7 @@ void messageHandler(QtMsgType type, const QMessageLogContext &context, const QSt
int main(int argc, char *argv[])
{
Monero::Utils::onStartup();
// // Enable high DPI scaling on windows & linux
//#if !defined(Q_OS_ANDROID) && QT_VERSION >= 0x050600
// QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
@ -132,6 +135,12 @@ int main(int argc, char *argv[])
qmlRegisterUncreatableType<AddressBook>("moneroComponents.AddressBook", 1, 0, "AddressBook",
"AddressBook can't be instantiated directly");
qmlRegisterUncreatableType<SubaddressModel>("moneroComponents.SubaddressModel", 1, 0, "SubaddressModel",
"SubaddressModel can't be instantiated directly");
qmlRegisterUncreatableType<Subaddress>("moneroComponents.Subaddress", 1, 0, "Subaddress",
"Subaddress can't be instantiated directly");
qRegisterMetaType<PendingTransaction::Priority>();
qRegisterMetaType<TransactionInfo::Direction>();
qRegisterMetaType<TransactionHistoryModel::TransactionInfoRole>();

242
main.qml
View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//
@ -53,7 +53,7 @@ ApplicationWindow {
property var currentWallet;
property var transaction;
property var transactionDescription;
property alias password : passwordDialog.password
property var walletPassword
property bool isNewWallet: false
property int restoreHeight:0
property bool daemonSynced: false
@ -144,6 +144,8 @@ ApplicationWindow {
else if(middlePanel.state === "Transfer") middlePanel.state = "Settings"
}
if (middlePanel.state !== "Advanced") updateBalance();
leftPanel.selectItem(middlePanel.state)
}
@ -164,7 +166,7 @@ ApplicationWindow {
persistentSettings.restore_height = 0
restoreHeight = 0;
persistentSettings.is_recovering = false
appWindow.password = ""
walletPassword = ""
fileDialog.open();
}
@ -224,7 +226,7 @@ ApplicationWindow {
wallet_path = moneroAccountsDir + wallet_path;
// console.log("opening wallet at: ", wallet_path, "with password: ", appWindow.password);
console.log("opening wallet at: ", wallet_path, ", testnet: ", persistentSettings.testnet);
walletManager.openWalletAsync(wallet_path, appWindow.password,
walletManager.openWalletAsync(wallet_path, walletPassword,
persistentSettings.testnet);
}
@ -307,6 +309,13 @@ ApplicationWindow {
return path.replace(/.*[\/\\]/, '').replace(/\.keys$/, '')
}
function updateBalance() {
if (!currentWallet)
return;
middlePanel.unlockedBalanceText = leftPanel.unlockedBalanceText = middlePanel.state === "Receive" ? qsTr("HIDDEN") : walletManager.displayAmount(currentWallet.unlockedBalance(currentWallet.currentSubaddressAccount));
middlePanel.balanceText = leftPanel.balanceText = middlePanel.state === "Receive" ? qsTr("HIDDEN") : walletManager.displayAmount(currentWallet.balance(currentWallet.currentSubaddressAccount));
}
function onWalletConnectionStatusChanged(status){
console.log("Wallet connection status changed " + status)
middlePanel.updateStatus();
@ -322,7 +331,7 @@ ApplicationWindow {
}
// initialize transaction history once wallet is initialized first time;
if (!walletInitialized) {
currentWallet.history.refresh()
currentWallet.history.refresh(currentWallet.currentSubaddressAccount)
walletInitialized = true
}
}
@ -331,25 +340,25 @@ ApplicationWindow {
walletName = usefulName(wallet.path)
console.log(">>> wallet opened: " + wallet)
if (wallet.status !== Wallet.Status_Ok) {
if (appWindow.password === '') {
console.error("Error opening wallet with empty password: ", wallet.errorString);
console.log("closing wallet async : " + wallet.address)
closeWallet();
// try to open wallet with password;
passwordDialog.open(walletName);
} 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)
closeWallet();
informationPopup.open()
informationPopup.onCloseCallback = function() {
passwordDialog.open(walletName)
}
passwordDialog.onAcceptedCallback = function() {
walletPassword = passwordDialog.password;
appWindow.initialize();
}
passwordDialog.onRejectedCallback = function() {
walletPassword = "";
//appWindow.enableUI(false)
rootItem.state = "wizard";
}
// 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)
closeWallet();
informationPopup.open()
informationPopup.onCloseCallback = function() {
passwordDialog.open(walletName)
}
return;
}
@ -365,13 +374,12 @@ ApplicationWindow {
function onWalletUpdate() {
console.log(">>> wallet updated")
middlePanel.unlockedBalanceText = leftPanel.unlockedBalanceText = walletManager.displayAmount(currentWallet.unlockedBalance);
middlePanel.balanceText = leftPanel.balanceText = walletManager.displayAmount(currentWallet.balance);
updateBalance();
// Update history if new block found since last update
if(foundNewBlock) {
foundNewBlock = false;
console.log("New block found - updating history")
currentWallet.history.refresh()
currentWallet.history.refresh(currentWallet.currentSubaddressAccount)
timeToUnlock = currentWallet.history.minutesToUnlock
leftPanel.minutesToUnlockTxt = (timeToUnlock > 0)? (timeToUnlock == 20)? qsTr("Unlocked balance (waiting for block)") : qsTr("Unlocked balance (~%1 min)").arg(timeToUnlock) : qsTr("Unlocked balance");
}
@ -447,6 +455,9 @@ ApplicationWindow {
console.log("Saving wallet after first refresh");
currentWallet.store()
isNewWallet = false
// Update History
currentWallet.history.refresh(currentWallet.currentSubaddressAccount);
}
// recovering from seed is finished after first refresh
@ -457,7 +468,7 @@ ApplicationWindow {
// Update history on every refresh if it's empty
if(currentWallet.history.count == 0)
currentWallet.history.refresh()
currentWallet.history.refresh(currentWallet.currentSubaddressAccount)
onWalletUpdate();
}
@ -520,19 +531,21 @@ ApplicationWindow {
currentWallet.refresh()
console.log("Confirmed money found")
// history refresh is handled by walletUpdated
currentWallet.history.refresh(currentWallet.currentSubaddressAccount) // this will refresh model
currentWallet.subaddress.refresh(currentWallet.currentSubaddressAccount)
}
function onWalletUnconfirmedMoneyReceived(txId, amount) {
// refresh history
console.log("unconfirmed money found")
currentWallet.history.refresh()
currentWallet.history.refresh(currentWallet.currentSubaddressAccount)
}
function onWalletMoneySent(txId, amount) {
// refresh transaction history here
console.log("money sent found")
currentWallet.refresh()
currentWallet.history.refresh() // this will refresh model
currentWallet.history.refresh(currentWallet.currentSubaddressAccount) // this will refresh model
}
function walletsFound() {
@ -578,8 +591,11 @@ ApplicationWindow {
// here we show confirmation popup;
transactionConfirmationPopup.title = qsTr("Confirmation") + translationManager.emptyString
transactionConfirmationPopup.text = qsTr("Please confirm transaction:\n")
+ (address === "" ? "" : (qsTr("\nAddress: ") + address))
transactionConfirmationPopup.text = qsTr("Please confirm transaction:\n");
for (var i = 0; i < transaction.subaddrIndices.length; ++i)
transactionConfirmationPopup.text += qsTr("\nSpending address index: ") + transaction.subaddrIndices[i]
transactionConfirmationPopup.text +=
(address === "" ? "" : (qsTr("\n\nAddress: ") + address))
+ (paymentId === "" ? "" : (qsTr("\nPayment ID: ") + paymentId))
+ qsTr("\n\nAmount: ") + walletManager.displayAmount(transaction.amount)
+ qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee)
@ -764,7 +780,11 @@ ApplicationWindow {
", address: ", address,
", message: ", message);
var result = currentWallet.getTxProof(txid, address, message);
var result;
if (address.length > 0)
result = currentWallet.getTxProof(txid, address, message);
if (!result || result.startsWith("error|"))
result = currentWallet.getSpendProof(txid, message);
informationPopup.title = qsTr("Payment proof") + translationManager.emptyString;
if (result.startsWith("error|")) {
var errorString = result.split("|")[1];
@ -786,12 +806,16 @@ ApplicationWindow {
", message: ", message,
", signature: ", signature);
var result = currentWallet.checkTxProof(txid, address, message, signature);
var result;
if (address.length > 0)
result = currentWallet.checkTxProof(txid, address, message, signature);
else
result = currentWallet.checkSpendProof(txid, message, signature);
var results = result.split("|");
if (results.length == 5 && results[0] == "true") {
var good = results[1] == "true";
if (address.length > 0 && results.length == 5 && results[0] === "true") {
var good = results[1] === "true";
var received = results[2];
var in_pool = results[3] == "true";
var in_pool = results[3] === "true";
var confirmations = results[4];
informationPopup.title = qsTr("Payment proof check") + translationManager.emptyString;
@ -812,6 +836,12 @@ ApplicationWindow {
informationPopup.text = qsTr("This address received nothing");
}
}
else if (results.length == 2 && results[0] === "true") {
var good = results[1] === "true";
informationPopup.title = qsTr("Payment proof check") + translationManager.emptyString;
informationPopup.icon = good ? StandardIcon.Information : StandardIcon.Critical;
informationPopup.text = good ? qsTr("Good signature") : qsTr("Bad signature");
}
else {
informationPopup.title = qsTr("Error") + translationManager.emptyString;
informationPopup.text = currentWallet.errorString;
@ -931,7 +961,14 @@ ApplicationWindow {
rootItem.state = "wizard"
} else {
rootItem.state = "normal"
passwordDialog.onAcceptedCallback = function() {
walletPassword = passwordDialog.password;
initialize(persistentSettings);
}
passwordDialog.onRejectedCallback = function() {
rootItem.state = "wizard"
}
passwordDialog.open(usefulName(walletPath()))
}
checkUpdates();
@ -993,8 +1030,8 @@ ApplicationWindow {
id: transactionConfirmationPopup
onAccepted: {
close();
transactionConfirmationPasswordDialog.onAcceptedCallback = function() {
if(appWindow.password === transactionConfirmationPasswordDialog.password){
passwordDialog.onAcceptedCallback = function() {
if(walletPassword === passwordDialog.password){
// Save transaction to file if view only wallet
if(viewOnly) {
saveTxDialog.open();
@ -1006,15 +1043,12 @@ ApplicationWindow {
informationPopup.text = qsTr("Wrong password");
informationPopup.open()
informationPopup.onCloseCallback = function() {
transactionConfirmationPasswordDialog.open()
passwordDialog.open()
}
}
transactionConfirmationPasswordDialog.password = ""
}
transactionConfirmationPasswordDialog.onRejectedCallback = function() {
transactionConfirmationPasswordDialog.password = ""
}
transactionConfirmationPasswordDialog.open()
passwordDialog.onRejectedCallback = null;
passwordDialog.open()
}
}
@ -1052,7 +1086,15 @@ ApplicationWindow {
console.log(moneroAccountsDir)
console.log(fileDialog.fileUrl)
console.log(persistentSettings.wallet_path)
initialize();
passwordDialog.onAcceptedCallback = function() {
walletPassword = passwordDialog.password;
initialize();
}
passwordDialog.onRejectedCallback = function() {
console.log("Canceled")
rootItem.state = "wizard";
}
passwordDialog.open(usefulName(walletPath()));
}
onRejected: {
console.log("Canceled")
@ -1118,21 +1160,6 @@ ApplicationWindow {
visible: false
z: parent.z + 1
anchors.fill: parent
onAccepted: {
appWindow.initialize();
}
onRejected: {
//appWindow.enableUI(false)
rootItem.state = "wizard"
}
}
PasswordDialog {
id: transactionConfirmationPasswordDialog
z: parent.z + 1
visible:false
anchors.fill: parent
property var onAcceptedCallback
property var onRejectedCallback
onAccepted: {
@ -1144,35 +1171,44 @@ ApplicationWindow {
onRejectedCallback();
}
}
PasswordDialog {
id: settingsPasswordDialog
NewPasswordDialog {
id: newPasswordDialog
z: parent.z + 1
visible:false
anchors.fill: parent
onAccepted: {
if(appWindow.password === settingsPasswordDialog.password){
if(currentWallet.seedLanguage == "") {
console.log("No seed language set. Using English as default");
currentWallet.setSeedLanguage("English");
}
// Load keys page
middlePanel.state = "Keys"
if (currentWallet.setPassword(newPasswordDialog.password)) {
appWindow.walletPassword = newPasswordDialog.password;
informationPopup.title = qsTr("Information") + translationManager.emptyString;
informationPopup.text = qsTr("Password changed successfully") + translationManager.emptyString;
informationPopup.icon = StandardIcon.Information;
} else {
informationPopup.title = qsTr("Error") + translationManager.emptyString;
informationPopup.text = qsTr("Wrong password");
informationPopup.open()
informationPopup.onCloseCallback = function() {
settingsPasswordDialog.open()
}
informationPopup.text = qsTr("Error: ") + currentWallet.errorString;
informationPopup.icon = StandardIcon.Critical;
}
settingsPasswordDialog.password = ""
informationPopup.onCloseCallback = null;
informationPopup.open();
}
onRejected: {
appWindow.showPageRequest("Settings");
}
}
InputDialog {
id: inputDialog
visible: false
z: parent.z + 1
anchors.fill: parent
property var onAcceptedCallback
property var onRejectedCallback
onAccepted: {
if (onAcceptedCallback)
onAcceptedCallback()
}
onRejected: {
if (onRejectedCallback)
onRejectedCallback()
}
}
@ -1249,16 +1285,40 @@ ApplicationWindow {
anchors.top: mobileHeader.bottom
anchors.left: parent.left
anchors.bottom: parent.bottom
onDashboardClicked: {middlePanel.state = "Dashboard"; if(isMobile) hideMenu()}
onTransferClicked: {middlePanel.state = "Transfer"; if(isMobile) hideMenu()}
onReceiveClicked: {middlePanel.state = "Receive"; if(isMobile) hideMenu()}
onTxkeyClicked: {middlePanel.state = "TxKey"; if(isMobile) hideMenu()}
onHistoryClicked: {middlePanel.state = "History"; if(isMobile) hideMenu()}
onAddressBookClicked: {middlePanel.state = "AddressBook"; if(isMobile) hideMenu()}
onMiningClicked: {middlePanel.state = "Mining"; if(isMobile) hideMenu()}
onSignClicked: {middlePanel.state = "Sign"; if(isMobile) hideMenu()}
onSettingsClicked: {middlePanel.state = "Settings"; if(isMobile) hideMenu()}
onKeysClicked: {settingsPasswordDialog.open(); if(isMobile) hideMenu()}
onDashboardClicked: { middlePanel.state = "Dashboard"; if(isMobile) hideMenu(); updateBalance(); }
onTransferClicked: { middlePanel.state = "Transfer"; if(isMobile) hideMenu(); updateBalance(); }
onReceiveClicked: { middlePanel.state = "Receive"; if(isMobile) hideMenu(); updateBalance(); }
onTxkeyClicked: { middlePanel.state = "TxKey"; if(isMobile) hideMenu(); updateBalance(); }
onHistoryClicked: { middlePanel.state = "History"; if(isMobile) hideMenu(); updateBalance(); }
onAddressBookClicked: { middlePanel.state = "AddressBook"; if(isMobile) hideMenu(); updateBalance(); }
onMiningClicked: { middlePanel.state = "Mining"; if(isMobile) hideMenu(); updateBalance(); }
onSignClicked: { middlePanel.state = "Sign"; if(isMobile) hideMenu(); updateBalance(); }
onSettingsClicked: { middlePanel.state = "Settings"; if(isMobile) hideMenu(); updateBalance(); }
onKeysClicked: {
passwordDialog.onAcceptedCallback = function() {
if(walletPassword === passwordDialog.password){
if(currentWallet.seedLanguage == "") {
console.log("No seed language set. Using English as default");
currentWallet.setSeedLanguage("English");
}
// Load keys page
middlePanel.state = "Keys"
} else {
informationPopup.title = qsTr("Error") + translationManager.emptyString;
informationPopup.text = qsTr("Wrong password");
informationPopup.open()
informationPopup.onCloseCallback = function() {
passwordDialog.open()
}
}
}
passwordDialog.onRejectedCallback = function() {
appWindow.showPageRequest("Settings");
}
passwordDialog.open();
if(isMobile) hideMenu();
updateBalance();
}
}
RightPanel {

View File

@ -35,6 +35,8 @@ HEADERS += \
src/QR-Code-generator/QrSegment.hpp \
src/model/AddressBookModel.h \
src/libwalletqt/AddressBook.h \
src/model/SubaddressModel.h \
src/libwalletqt/Subaddress.h \
src/zxcvbn-c/zxcvbn.h \
src/libwalletqt/UnsignedTransaction.h \
MainApp.h
@ -58,10 +60,18 @@ SOURCES += main.cpp \
src/QR-Code-generator/QrSegment.cpp \
src/model/AddressBookModel.cpp \
src/libwalletqt/AddressBook.cpp \
src/model/SubaddressModel.cpp \
src/libwalletqt/Subaddress.cpp \
src/zxcvbn-c/zxcvbn.c \
src/libwalletqt/UnsignedTransaction.cpp \
MainApp.cpp
CONFIG(DISABLE_PASS_STRENGTH_METER) {
HEADERS -= src/zxcvbn-c/zxcvbn.h
SOURCES -= src/zxcvbn-c/zxcvbn.c
DEFINES += "DISABLE_PASS_STRENGTH_METER"
}
!ios {
HEADERS += src/daemon/DaemonManager.h
SOURCES += src/daemon/DaemonManager.cpp
@ -317,6 +327,10 @@ TRANSLATIONS = \ # English is default language, no explicit translation file
$$PWD/translations/monero-core_he.ts \ # Hebrew
$$PWD/translations/monero-core_ko.ts \ # Korean
$$PWD/translations/monero-core_ro.ts \ # Romanian
$$PWD/translations/monero-core_da.ts \ # Danish
$$PWD/translations/monero-core_cs.ts \ # Czech
$$PWD/translations/monero-core_sk.ts \ # Slovak
$$PWD/translations/monero-core_ar.ts \ # Arabic
CONFIG(release, debug|release) {
DESTDIR = release/bin

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//
@ -546,7 +546,7 @@ Rectangle {
function onPageCompleted() {
if(currentWallet != null && typeof currentWallet.history !== "undefined" ) {
currentWallet.history.refresh()
currentWallet.history.refresh(currentWallet.currentSubaddressAccount)
table.addressBookModel = currentWallet ? currentWallet.addressBookModel : null
transactionTypeDropdown.update()
}

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2017, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//
@ -151,7 +151,7 @@ Rectangle {
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
onClicked: {
var success = walletManager.startMining(appWindow.currentWallet.address, soloMinerThreadsLine.text, persistentSettings.allow_background_mining, persistentSettings.miningIgnoreBattery)
var success = walletManager.startMining(appWindow.currentWallet.address(0, 0), soloMinerThreadsLine.text, persistentSettings.allow_background_mining, persistentSettings.miningIgnoreBattery)
if (success) {
update()
} else {

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//
@ -38,53 +38,26 @@ import moneroComponents.Wallet 1.0
import moneroComponents.WalletManager 1.0
import moneroComponents.TransactionHistory 1.0
import moneroComponents.TransactionHistoryModel 1.0
import moneroComponents.Subaddress 1.0
import moneroComponents.SubaddressModel 1.0
Rectangle {
id: pageReceive
color: "#F0EEEE"
property alias addressText : addressLine.text
property alias paymentIdText : paymentIdLine.text
property alias integratedAddressText : integratedAddressLine.text
property var model
property var current_address
property alias addressText : pageReceive.current_address
property string trackingLineText: ""
function updatePaymentId(payment_id) {
if (typeof appWindow.currentWallet === 'undefined' || appWindow.currentWallet == null)
return
// generate a new one if not given as argument
if (typeof payment_id === 'undefined') {
payment_id = appWindow.currentWallet.generatePaymentId()
paymentIdLine.text = payment_id
}
if (payment_id.length > 0) {
integratedAddressLine.text = appWindow.currentWallet.integratedAddress(payment_id)
if (integratedAddressLine.text === "")
integratedAddressLine.text = qsTr("Invalid payment ID")
}
else {
paymentIdLine.text = ""
integratedAddressLine.text = ""
}
update()
}
function makeQRCodeString() {
var s = "monero:"
var nfields = 0
s += addressLine.text
s += current_address;
var amount = amountLine.text.trim()
if (amount !== "") {
s += (nfields++ ? "&" : "?")
s += "tx_amount=" + amount
}
var pid = paymentIdLine.text.trim()
if (pid !== "") {
s += (nfields++ ? "&" : "?")
s += "tx_payment_id=" + pid
}
return s
}
@ -112,13 +85,14 @@ Rectangle {
var count = model.rowCount()
var totalAmount = 0
var nTransactions = 0
var list = ""
var list = []
var blockchainHeight = 0
for (var i = 0; i < count; ++i) {
var idx = model.index(i, 0)
var isout = model.data(idx, TransactionHistoryModel.TransactionIsOutRole);
var payment_id = model.data(idx, TransactionHistoryModel.TransactionPaymentIdRole);
if (!isout && payment_id == paymentIdLine.text) {
var subaddrAccount = model.data(idx, TransactionHistoryModel.TransactionSubaddrAccountRole);
var subaddrIndex = model.data(idx, TransactionHistoryModel.TransactionSubaddrIndexRole);
if (!isout && subaddrAccount == appWindow.currentWallet.currentSubaddressAccount && subaddrIndex == table.currentIndex) {
var amount = model.data(idx, TransactionHistoryModel.TransactionAtomicAmountRole);
totalAmount = walletManager.addi(totalAmount, amount)
nTransactions += 1
@ -126,21 +100,25 @@ Rectangle {
var txid = model.data(idx, TransactionHistoryModel.TransactionHashRole);
var blockHeight = model.data(idx, TransactionHistoryModel.TransactionBlockHeightRole);
if (blockHeight == 0) {
list += qsTr("in the txpool: %1").arg(txid) + translationManager.emptyString
list.push(qsTr("in the txpool: %1").arg(txid) + translationManager.emptyString)
} else {
if (blockchainHeight == 0)
blockchainHeight = walletManager.blockchainHeight()
var confirmations = blockchainHeight - blockHeight - 1
var displayAmount = model.data(idx, TransactionHistoryModel.TransactionDisplayAmountRole);
if (confirmations > 1) {
list += qsTr("%2 confirmations: %3 (%1)").arg(txid).arg(confirmations).arg(displayAmount) + translationManager.emptyString
list.push(qsTr("%2 confirmations: %3 (%1)").arg(txid).arg(confirmations).arg(displayAmount) + translationManager.emptyString)
} else {
list += qsTr("1 confirmation: %2 (%1)").arg(txid).arg(displayAmount) + translationManager.emptyString
list.push(qsTr("1 confirmation: %2 (%1)").arg(txid).arg(displayAmount) + translationManager.emptyString)
}
}
list += "<br>"
}
}
// if there are too many txes, only show the first 3
if (list.length > 3) {
list.length = 3;
list.push("...");
}
if (nTransactions == 0) {
setTrackingLineText(qsTr("No transaction found yet...") + translationManager.emptyString)
@ -159,7 +137,7 @@ Rectangle {
}
}
setTrackingLineText(text + "<br>" + list)
setTrackingLineText(text + "<br>" + list.join("<br>"))
}
Clipboard { id: clipboard }
@ -186,116 +164,68 @@ Rectangle {
id: addressRow
Label {
id: addressLabel
text: qsTr("Address") + translationManager.emptyString
text: qsTr("Addresses") + translationManager.emptyString
width: mainLayout.labelWidth
}
LineEdit {
id: addressLine
fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("ReadOnly wallet address displayed here") + translationManager.emptyString;
readOnly: true
width: mainLayout.editWidth
Rectangle {
id: tableRect
Layout.fillWidth: true
onTextChanged: cursorPosition = 0
IconButton {
imageSource: "../images/copyToClipboard.png"
onClicked: {
if (addressLine.text.length > 0) {
console.log(addressLine.text + " copied to clipboard")
clipboard.setText(addressLine.text)
appWindow.showStatusMessage(qsTr("Address copied to clipboard"),3)
}
}
Layout.preferredHeight: 200
color: "#FFFFFF"
Scroll {
id: flickableScroll
anchors.right: table.right
anchors.top: table.top
anchors.bottom: table.bottom
flickable: table
}
}
}
GridLayout {
id: paymentIdRow
columns:2
Label {
Layout.columnSpan: 2
id: paymentIdLabel
text: qsTr("Payment ID") + translationManager.emptyString
width: mainLayout.labelWidth
}
LineEdit {
id: paymentIdLine
fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("16 hexadecimal characters") + translationManager.emptyString;
readOnly: false
onTextChanged: updatePaymentId(paymentIdLine.text)
width: mainLayout.editWidth
Layout.fillWidth: true
IconButton {
imageSource: "../images/copyToClipboard.png"
onClicked: {
if (paymentIdLine.text.length > 0) {
clipboard.setText(paymentIdLine.text)
appWindow.showStatusMessage(qsTr("Payment ID copied to clipboard"),3)
}
SubaddressTable {
id: table
anchors.fill: parent
onContentYChanged: flickableScroll.flickableContentYChanged()
onCurrentItemChanged: {
current_address = appWindow.currentWallet.address(appWindow.currentWallet.currentSubaddressAccount, table.currentIndex);
}
}
}
StandardButton {
id: generatePaymentId
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("Generate") + translationManager.emptyString;
onClicked: updatePaymentId()
}
StandardButton {
id: clearPaymentId
enabled: !!paymentIdLine.text
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("Clear") + translationManager.emptyString;
onClicked: updatePaymentId("")
}
}
ColumnLayout {
id: integratedAddressRow
Label {
id: integratedAddressLabel
text: qsTr("Integrated address") + translationManager.emptyString
width: mainLayout.labelWidth
}
LineEdit {
id: integratedAddressLine
fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("Generate payment ID for integrated address") + translationManager.emptyString
readOnly: true
width: mainLayout.editWidth
Layout.fillWidth: true
onTextChanged: cursorPosition = 0
IconButton {
imageSource: "../images/copyToClipboard.png"
RowLayout {
spacing: 20
StandardButton {
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("Create new address") + translationManager.emptyString;
onClicked: {
if (integratedAddressLine.text.length > 0) {
clipboard.setText(integratedAddressLine.text)
appWindow.showStatusMessage(qsTr("Integrated address copied to clipboard"),3)
inputDialog.labelText = qsTr("Set the label of the new address:") + translationManager.emptyString
inputDialog.inputText = qsTr("(Untitled)")
inputDialog.onAcceptedCallback = function() {
appWindow.currentWallet.subaddress.addRow(appWindow.currentWallet.currentSubaddressAccount, inputDialog.inputText)
table.currentIndex = appWindow.currentWallet.numSubaddresses() - 1
}
inputDialog.onRejectedCallback = null;
inputDialog.open()
}
}
StandardButton {
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
enabled: table.currentIndex > 0
text: qsTr("Rename") + translationManager.emptyString;
onClicked: {
inputDialog.labelText = qsTr("Set the label of the selected address:") + translationManager.emptyString
inputDialog.inputText = appWindow.currentWallet.getSubaddressLabel(appWindow.currentWallet.currentSubaddressAccount, table.currentIndex)
inputDialog.onAcceptedCallback = function() {
appWindow.currentWallet.subaddress.setLabel(appWindow.currentWallet.currentSubaddressAccount, table.currentIndex, inputDialog.inputText)
}
inputDialog.onRejectedCallback = null;
inputDialog.open()
}
}
}
}
@ -331,15 +261,17 @@ Rectangle {
Label {
id: trackingLabel
textFormat: Text.RichText
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>\
Tracking <font size='2'> (</font><a href='#'>help</a><font size='2'>)</font>")
+ translationManager.emptyString
text: "<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>" +
qsTr("Tracking") +
"<font size='2'> (</font><a href='#'>" +
qsTr("help") +
"</a><font size='2'>)</font>" +
translationManager.emptyString
width: mainLayout.labelWidth
onLinkActivated: {
trackingHowToUseDialog.title = qsTr("Tracking payments") + translationManager.emptyString;
trackingHowToUseDialog.text = qsTr(
"<p><font size='+2'>This is a simple sales tracker:</font></p>" +
"<p>Click Generate to create a random payment id for a new customer</p> " +
"<p>Let your customer scan that QR code to make a payment (if that customer has software which " +
"supports QR code scanning).</p>" +
"<p>This page will automatically scan the blockchain and the tx pool " +
@ -427,11 +359,12 @@ Rectangle {
function onPageCompleted() {
console.log("Receive page loaded");
table.model = currentWallet.subaddressModel;
if (appWindow.currentWallet) {
if (addressLine.text.length === 0 || addressLine.text !== appWindow.currentWallet.address) {
addressLine.text = appWindow.currentWallet.address
}
current_address = appWindow.currentWallet.address(appWindow.currentWallet.currentSubaddressAccount, 0)
appWindow.currentWallet.subaddress.refresh(appWindow.currentWallet.currentSubaddressAccount)
table.currentIndex = 0
}
update()

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//
@ -164,6 +164,32 @@ Rectangle {
}
}
}
StandardButton {
id: changePasswordButton
text: qsTr("Change password") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
onClicked: {
passwordDialog.onAcceptedCallback = function() {
if(appWindow.walletPassword === passwordDialog.password){
newPasswordDialog.open()
} else {
informationPopup.title = qsTr("Error") + translationManager.emptyString;
informationPopup.text = qsTr("Wrong password");
informationPopup.open()
informationPopup.onCloseCallback = function() {
changePasswordDialog.open()
}
passwordDialog.open()
}
}
passwordDialog.onRejectedCallback = null;
passwordDialog.open()
}
}
}
RowLayout {
@ -565,6 +591,10 @@ Rectangle {
Layout.fillWidth: true
text: (typeof currentWallet == "undefined") ? "" : qsTr("Wallet log path: ") + currentWallet.walletLogPath + translationManager.emptyString
}
TextBlock {
Layout.fillWidth: true
text: qsTr("Wallet Name: ") + walletName + translationManager.emptyString
}
TextBlock {
Layout.fillWidth: true
text: (typeof currentWallet == "undefined") ? "" : qsTr("Daemon log path: ") + currentWallet.daemonLogPath + translationManager.emptyString

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//
@ -383,9 +383,12 @@ Rectangle {
Text {
id: verifyAddressLabel
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: %1px;}</style>\
Signing address <font size='%2'> ( Paste in or select from </font> <a href='#'>Address book</a><font size='%3'> )</font>").arg(14 * scaleRatio).arg(2 * scaleRatio).arg(2 * scaleRatio)
+ translationManager.emptyString
text: "<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: " + (14 * scaleRatio) + "px;}</style>" +
qsTr("Signing address") +
"<font size='" + (2 * scaleRatio) + "'> ( " +
qsTr("Paste in or select from <a href='#'>Address book</a>") +
" )</font>" +
translationManager.emptyString
wrapMode: Text.Wrap
font.pixelSize: 14 * scaleRatio
Layout.fillWidth: true

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//
@ -41,7 +41,10 @@ Rectangle {
signal sweepUnmixableClicked()
color: "#F0EEEE"
property string startLinkText: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style><font size='2'> (</font><a href='#'>Start daemon</a><font size='2'>)</font>") + translationManager.emptyString
property string startLinkText: "<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style><font size='2'> (</font><a href='#'>" +
qsTr("Start daemon") +
"</a><font size='2'>)</font>" +
translationManager.emptyString
property bool showAdvanced: false
function scaleValueToMixinCount(scaleValue) {
@ -184,15 +187,6 @@ Rectangle {
// For translations to work, the strings need to be listed in
// the file components/StandardDropdown.qml too.
// Priorities before v5
ListModel {
id: priorityModel
ListElement { column1: qsTr("Low (x1 fee)") ; column2: ""; priority: PendingTransaction.Priority_Low }
ListElement { column1: qsTr("Medium (x20 fee)") ; column2: ""; priority: PendingTransaction.Priority_Medium }
ListElement { column1: qsTr("High (x166 fee)") ; column2: ""; priority: PendingTransaction.Priority_High }
}
// Priorites after v5
ListModel {
id: priorityModelV5
@ -222,10 +216,12 @@ Rectangle {
Label {
id: addressLabel
textFormat: Text.RichText
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>\
Address <font size='2'> ( Paste in or select from </font> <a href='#'>Address book</a><font size='2'> )</font>")
+ translationManager.emptyString
text: "<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>" +
qsTr("Address") +
"<font size='2'> ( " +
qsTr("Paste in or select from <a href='#'>Address book</a>") +
" )</font>" +
translationManager.emptyString
onLinkActivated: appWindow.showPageRequest("AddressBook")
Layout.fillWidth: true
}
@ -335,7 +331,7 @@ Rectangle {
enabled : !appWindow.viewOnly && pageRoot.checkInformation(amountLine.text, addressLine.text, paymentIdLine.text, appWindow.persistentSettings.testnet)
onClicked: {
console.log("Transfer: paymentClicked")
var priority = priorityModel.get(priorityDropdown.currentIndex).priority
var priority = priorityModelV5.get(priorityDropdown.currentIndex).priority
console.log("priority: " + priority)
console.log("amount: " + amountLine.text)
addressLine.text = addressLine.text.trim()
@ -478,7 +474,7 @@ Rectangle {
enabled: pageRoot.checkInformation(amountLine.text, addressLine.text, paymentIdLine.text, appWindow.persistentSettings.testnet)
onClicked: {
console.log("Transfer: saveTx Clicked")
var priority = priorityModel.get(priorityDropdown.currentIndex).priority
var priority = priorityModelV5.get(priorityDropdown.currentIndex).priority
console.log("priority: " + priority)
console.log("amount: " + amountLine.text)
addressLine.text = addressLine.text.trim()

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//
@ -72,6 +72,10 @@ Rectangle {
if ((signature.length - 9) % 132 != 0)
return false;
return check256(signature, signature.length);
} else if (signature.startsWith("SpendProofV")) {
if ((signature.length - 12) % 88 != 0)
return false;
return check256(signature, signature.length);
}
return false;
}
@ -90,7 +94,8 @@ Rectangle {
property int lineEditFontSize: 12
Text {
text: qsTr("Generate a proof of your incoming/outgoing payment by supplying the transaction ID, the recipient address and an optional message:") + translationManager.emptyString
text: qsTr("Generate a proof of your incoming/outgoing payment by supplying the transaction ID, the recipient address and an optional message. \n" +
"For the case of outgoing payments, you can get a 'Spend Proof' that proves the authorship of a transaction. In this case, you don't need to specify the recipient address.") + translationManager.emptyString
wrapMode: Text.Wrap
Layout.fillWidth: true;
}
@ -183,7 +188,7 @@ Rectangle {
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
enabled: checkTxID(getProofTxIdLine.text) && checkAddress(getProofAddressLine.text, appWindow.persistentSettings.testnet)
enabled: checkTxID(getProofTxIdLine.text) && (getProofAddressLine.text.length == 0 || checkAddress(getProofAddressLine.text, appWindow.persistentSettings.testnet))
onClicked: {
console.log("getProof: Generate clicked: txid " + getProofTxIdLine.text + ", address " + getProofAddressLine.text + ", message: " + getProofMessageLine.text);
root.getProofClicked(getProofTxIdLine.text, getProofAddressLine.text, getProofMessageLine.text)
@ -201,7 +206,8 @@ Rectangle {
}
Text {
text: qsTr("Verify that funds were paid to an address by supplying the transaction ID, the recipient address, the message used for signing and the signature:") + translationManager.emptyString
text: qsTr("Verify that funds were paid to an address by supplying the transaction ID, the recipient address, the message used for signing and the signature.\n" +
"For the case with Spend Proof, you don't need to specify the recipient address.") + translationManager.emptyString
wrapMode: Text.Wrap
Layout.fillWidth: true;
}
@ -322,7 +328,7 @@ Rectangle {
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
enabled: checkTxID(checkProofTxIdLine.text) && checkAddress(checkProofAddressLine.text, appWindow.persistentSettings.testnet) && checkSignature(checkProofSignatureLine.text)
enabled: checkTxID(checkProofTxIdLine.text) && checkSignature(checkProofSignatureLine.text) && ((checkProofSignatureLine.text.startsWith("SpendProofV") && checkProofAddressLine.text.length == 0) || (!checkProofSignatureLine.text.startsWith("SpendProofV") && checkAddress(checkProofAddressLine.text, appWindow.persistentSettings.testnet)))
onClicked: {
console.log("checkProof: Check clicked: txid " + checkProofTxIdLine.text + ", address " + checkProofAddressLine.text + ", message " + checkProofMessageLine.text + ", signature " + checkProofSignatureLine.text);
root.checkProofClicked(checkProofTxIdLine.text, checkProofAddressLine.text, checkProofMessageLine.text, checkProofSignatureLine.text)

View File

@ -51,6 +51,7 @@
<file>tabs/TweetsModel.qml</file>
<file>components/Scroll.qml</file>
<file>components/AddressBookTable.qml</file>
<file>components/SubaddressTable.qml</file>
<file>images/deleteIcon.png</file>
<file>images/moneroIcon.png</file>
<file>components/StandardDropdown.qml</file>
@ -118,11 +119,15 @@
<file>lang/flags/spain.png</file>
<file>lang/flags/sweden.png</file>
<file>lang/flags/taiwan.png</file>
<file>lang/flags/denmark.png</file>
<file>lang/flags/uk.png</file>
<file>lang/flags/usa.png</file>
<file>lang/flags/israel.png</file>
<file>lang/flags/south_korea.png</file>
<file>lang/flags/south_korea.png</file>
<file>lang/flags/romania.png</file>
<file>lang/flags/czech.png</file>
<file>lang/flags/slovakia.png</file>
<file>lang/flags/egypt.png</file>
<file>wizard/WizardManageWalletUI.qml</file>
<file>wizard/WizardRecoveryWallet.qml</file>
<file>wizard/WizardMemoTextInput.qml</file>
@ -131,6 +136,8 @@
<file>pages/TxKey.qml</file>
<file>components/IconButton.qml</file>
<file>components/PasswordDialog.qml</file>
<file>components/NewPasswordDialog.qml</file>
<file>components/InputDialog.qml</file>
<file>components/ProcessingSplash.qml</file>
<file>components/ProgressBar.qml</file>
<file>components/StandardDialog.qml</file>

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2017, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2017, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2017, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2017, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -50,6 +50,16 @@ quint64 PendingTransaction::txCount() const
return m_pimpl->txCount();
}
QList<QVariant> PendingTransaction::subaddrIndices() const
{
std::vector<std::set<uint32_t>> subaddrIndices = m_pimpl->subaddrIndices();
QList<QVariant> result;
for (const auto& x : subaddrIndices)
for (uint32_t i : x)
result.push_back(i);
return result;
}
void PendingTransaction::setFilename(const QString &fileName)
{
m_fileName = fileName;

View File

@ -2,6 +2,8 @@
#define PENDINGTRANSACTION_H
#include <QObject>
#include <QList>
#include <QVariant>
#include <wallet/api/wallet2_api.h>
@ -19,6 +21,7 @@ class PendingTransaction : public QObject
Q_PROPERTY(quint64 fee READ fee)
Q_PROPERTY(QStringList txid READ txid)
Q_PROPERTY(quint64 txCount READ txCount)
Q_PROPERTY(QList<QVariant> subaddrIndices READ subaddrIndices)
public:
enum Status {
@ -44,6 +47,7 @@ public:
quint64 fee() const;
QStringList txid() const;
quint64 txCount() const;
QList<QVariant> subaddrIndices() const;
Q_INVOKABLE void setFilename(const QString &fileName);
private:

View File

@ -0,0 +1,84 @@
// Copyright (c) 2018, 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.
#include "Subaddress.h"
#include <QDebug>
Subaddress::Subaddress(Monero::Subaddress *subaddressImpl, QObject *parent)
: QObject(parent), m_subaddressImpl(subaddressImpl)
{
qDebug(__FUNCTION__);
getAll();
}
QList<Monero::SubaddressRow*> Subaddress::getAll(bool update) const
{
qDebug(__FUNCTION__);
emit refreshStarted();
if(update)
m_rows.clear();
if (m_rows.empty()){
for (auto &row: m_subaddressImpl->getAll()) {
m_rows.append(row);
}
}
emit refreshFinished();
return m_rows;
}
Monero::SubaddressRow * Subaddress::getRow(int index) const
{
return m_rows.at(index);
}
void Subaddress::addRow(quint32 accountIndex, const QString &label) const
{
m_subaddressImpl->addRow(accountIndex, label.toStdString());
getAll(true);
}
void Subaddress::setLabel(quint32 accountIndex, quint32 addressIndex, const QString &label) const
{
m_subaddressImpl->setLabel(accountIndex, addressIndex, label.toStdString());
getAll(true);
}
void Subaddress::refresh(quint32 accountIndex) const
{
m_subaddressImpl->refresh(accountIndex);
getAll(true);
}
quint64 Subaddress::count() const
{
return m_rows.size();
}

View File

@ -0,0 +1,61 @@
// Copyright (c) 2018, 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.
#ifndef SUBADDRESS_H
#define SUBADDRESS_H
#include <wallet/api/wallet2_api.h>
#include <QObject>
#include <QList>
#include <QDateTime>
class Subaddress : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE QList<Monero::SubaddressRow*> getAll(bool update = false) const;
Q_INVOKABLE Monero::SubaddressRow * getRow(int index) const;
Q_INVOKABLE void addRow(quint32 accountIndex, const QString &label) const;
Q_INVOKABLE void setLabel(quint32 accountIndex, quint32 addressIndex, const QString &label) const;
Q_INVOKABLE void refresh(quint32 accountIndex) const;
quint64 count() const;
signals:
void refreshStarted() const;
void refreshFinished() const;
public slots:
private:
explicit Subaddress(Monero::Subaddress * subaddressImpl, QObject *parent);
friend class Wallet;
Monero::Subaddress * m_subaddressImpl;
mutable QList<Monero::SubaddressRow*> m_rows;
};
#endif // SUBADDRESS_H

View File

@ -22,7 +22,7 @@ TransactionInfo *TransactionHistory::transaction(int index)
// return nullptr;
//}
QList<TransactionInfo *> TransactionHistory::getAll() const
QList<TransactionInfo *> TransactionHistory::getAll(quint32 accountIndex) const
{
// XXX this invalidates previously saved history that might be used by model
emit refreshStarted();
@ -37,6 +37,10 @@ QList<TransactionInfo *> TransactionHistory::getAll() const
TransactionHistory * parent = const_cast<TransactionHistory*>(this);
for (const auto i : m_pimpl->getAll()) {
TransactionInfo * ti = new TransactionInfo(i, parent);
if (ti->subaddrAccount() != accountIndex) {
delete ti;
continue;
}
m_tinfo.append(ti);
// looking for transactions timestamp scope
if (ti->timestamp() >= lastDateTime) {
@ -69,12 +73,12 @@ QList<TransactionInfo *> TransactionHistory::getAll() const
return m_tinfo;
}
void TransactionHistory::refresh()
void TransactionHistory::refresh(quint32 accountIndex)
{
// rebuilding transaction list in wallet_api;
m_pimpl->refresh();
// copying list here and keep track on every item to avoid memleaks
getAll();
getAll(accountIndex);
}
quint64 TransactionHistory::count() const

View File

@ -23,8 +23,8 @@ class TransactionHistory : public QObject
public:
Q_INVOKABLE TransactionInfo *transaction(int index);
// Q_INVOKABLE TransactionInfo * transaction(const QString &id);
Q_INVOKABLE QList<TransactionInfo*> getAll() const;
Q_INVOKABLE void refresh();
Q_INVOKABLE QList<TransactionInfo*> getAll(quint32 accountIndex) const;
Q_INVOKABLE void refresh(quint32 accountIndex);
quint64 count() const;
QDateTime firstDateTime() const;
QDateTime lastDateTime() const;

View File

@ -48,6 +48,24 @@ quint64 TransactionInfo::blockHeight() const
return m_pimpl->blockHeight();
}
QSet<quint32> TransactionInfo::subaddrIndex() const
{
QSet<quint32> result;
for (uint32_t i : m_pimpl->subaddrIndex())
result.insert(i);
return result;
}
quint32 TransactionInfo::subaddrAccount() const
{
return m_pimpl->subaddrAccount();
}
QString TransactionInfo::label() const
{
return QString::fromStdString(m_pimpl->label());
}
quint64 TransactionInfo::confirmations() const
{
return m_pimpl->confirmations();

View File

@ -4,6 +4,7 @@
#include <wallet/api/wallet2_api.h>
#include <QObject>
#include <QDateTime>
#include <QSet>
class Transfer;
@ -18,6 +19,9 @@ class TransactionInfo : public QObject
Q_PROPERTY(QString displayAmount READ displayAmount)
Q_PROPERTY(QString fee READ fee)
Q_PROPERTY(quint64 blockHeight READ blockHeight)
Q_PROPERTY(QSet<quint32> subaddrIndex READ subaddrIndex)
Q_PROPERTY(quint32 subaddrAccount READ subaddrAccount)
Q_PROPERTY(QString label READ label)
Q_PROPERTY(quint64 confirmations READ confirmations)
Q_PROPERTY(quint64 unlockTime READ unlockTime)
Q_PROPERTY(QString hash READ hash)
@ -44,6 +48,9 @@ public:
QString displayAmount() const;
QString fee() const;
quint64 blockHeight() const;
QSet<quint32> subaddrIndex() const;
quint32 subaddrAccount() const;
QString label() const;
quint64 confirmations() const;
quint64 unlockTime() const;
//! transaction_id

View File

@ -3,9 +3,11 @@
#include "UnsignedTransaction.h"
#include "TransactionHistory.h"
#include "AddressBook.h"
#include "Subaddress.h"
#include "model/TransactionHistoryModel.h"
#include "model/TransactionHistorySortFilterModel.h"
#include "model/AddressBookModel.h"
#include "model/SubaddressModel.h"
#include "wallet/api/wallet2_api.h"
#include <QFile>
@ -155,9 +157,9 @@ bool Wallet::setPassword(const QString &password)
return m_walletImpl->setPassword(password.toStdString());
}
QString Wallet::address() const
QString Wallet::address(quint32 accountIndex, quint32 addressIndex) const
{
return QString::fromStdString(m_walletImpl->address());
return QString::fromStdString(m_walletImpl->address(accountIndex, addressIndex));
}
QString Wallet::path() const
@ -241,14 +243,63 @@ bool Wallet::viewOnly() const
return m_walletImpl->watchOnly();
}
quint64 Wallet::balance() const
quint64 Wallet::balance(quint32 accountIndex) const
{
return m_walletImpl->balance();
return m_walletImpl->balance(accountIndex);
}
quint64 Wallet::unlockedBalance() const
quint64 Wallet::balanceAll() const
{
return m_walletImpl->unlockedBalance();
return m_walletImpl->balanceAll();
}
quint64 Wallet::unlockedBalance(quint32 accountIndex) const
{
return m_walletImpl->unlockedBalance(accountIndex);
}
quint64 Wallet::unlockedBalanceAll() const
{
return m_walletImpl->unlockedBalanceAll();
}
quint32 Wallet::currentSubaddressAccount() const
{
return m_currentSubaddressAccount;
}
void Wallet::switchSubaddressAccount(quint32 accountIndex)
{
if (accountIndex < numSubaddressAccounts())
{
m_currentSubaddressAccount = accountIndex;
m_subaddress->refresh(m_currentSubaddressAccount);
m_history->refresh(m_currentSubaddressAccount);
}
}
void Wallet::addSubaddressAccount(const QString& label)
{
m_walletImpl->addSubaddressAccount(label.toStdString());
switchSubaddressAccount(numSubaddressAccounts() - 1);
}
quint32 Wallet::numSubaddressAccounts() const
{
return m_walletImpl->numSubaddressAccounts();
}
quint32 Wallet::numSubaddresses(quint32 accountIndex) const
{
return m_walletImpl->numSubaddresses(accountIndex);
}
void Wallet::addSubaddress(const QString& label)
{
m_walletImpl->addSubaddress(currentSubaddressAccount(), label.toStdString());
}
QString Wallet::getSubaddressLabel(quint32 accountIndex, quint32 addressIndex) const
{
return QString::fromStdString(m_walletImpl->getSubaddressLabel(accountIndex, addressIndex));
}
void Wallet::setSubaddressLabel(quint32 accountIndex, quint32 addressIndex, const QString &label)
{
m_walletImpl->setSubaddressLabel(accountIndex, addressIndex, label.toStdString());
}
quint64 Wallet::blockChainHeight() const
@ -288,7 +339,8 @@ quint64 Wallet::daemonBlockChainTargetHeight() const
bool Wallet::refresh()
{
bool result = m_walletImpl->refresh();
m_history->refresh();
m_history->refresh(currentSubaddressAccount());
m_subaddress->refresh(currentSubaddressAccount());
if (result)
emit updated();
return result;
@ -324,9 +376,10 @@ PendingTransaction *Wallet::createTransaction(const QString &dst_addr, const QSt
quint64 amount, quint32 mixin_count,
PendingTransaction::Priority priority)
{
std::set<uint32_t> subaddr_indices;
Monero::PendingTransaction * ptImpl = m_walletImpl->createTransaction(
dst_addr.toStdString(), payment_id.toStdString(), amount, mixin_count,
static_cast<Monero::PendingTransaction::Priority>(priority));
static_cast<Monero::PendingTransaction::Priority>(priority), currentSubaddressAccount(), subaddr_indices);
PendingTransaction * result = new PendingTransaction(ptImpl,0);
return result;
}
@ -351,9 +404,10 @@ void Wallet::createTransactionAsync(const QString &dst_addr, const QString &paym
PendingTransaction *Wallet::createTransactionAll(const QString &dst_addr, const QString &payment_id,
quint32 mixin_count, PendingTransaction::Priority priority)
{
std::set<uint32_t> subaddr_indices;
Monero::PendingTransaction * ptImpl = m_walletImpl->createTransaction(
dst_addr.toStdString(), payment_id.toStdString(), Monero::optional<uint64_t>(), mixin_count,
static_cast<Monero::PendingTransaction::Priority>(priority));
static_cast<Monero::PendingTransaction::Priority>(priority), currentSubaddressAccount(), subaddr_indices);
PendingTransaction * result = new PendingTransaction(ptImpl, this);
return result;
}
@ -458,6 +512,18 @@ AddressBookModel *Wallet::addressBookModel() const
return m_addressBookModel;
}
Subaddress *Wallet::subaddress()
{
return m_subaddress;
}
SubaddressModel *Wallet::subaddressModel()
{
if (!m_subaddressModel) {
m_subaddressModel = new SubaddressModel(this, m_subaddress);
}
return m_subaddressModel;
}
QString Wallet::generatePaymentId() const
{
@ -523,6 +589,22 @@ QString Wallet::checkTxProof(const QString &txid, const QString &address, const
return QString::fromStdString(result);
}
Q_INVOKABLE QString Wallet::getSpendProof(const QString &txid, const QString &message) const
{
std::string result = m_walletImpl->getSpendProof(txid.toStdString(), message.toStdString());
if (result.empty())
result = "error|" + m_walletImpl->errorString();
return QString::fromStdString(result);
}
Q_INVOKABLE QString Wallet::checkSpendProof(const QString &txid, const QString &message, const QString &signature) const
{
bool good;
bool success = m_walletImpl->checkSpendProof(txid.toStdString(), message.toStdString(), signature.toStdString(), good);
std::string result = std::string(success ? "true" : "false") + "|" + std::string(!success ? m_walletImpl->errorString() : good ? "true" : "false");
return QString::fromStdString(result);
}
QString Wallet::signMessage(const QString &message, bool filename) const
{
if (filename) {
@ -652,14 +734,18 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent)
, m_historyModel(nullptr)
, m_addressBook(nullptr)
, m_addressBookModel(nullptr)
, m_subaddress(nullptr)
, m_subaddressModel(nullptr)
, m_daemonBlockChainHeight(0)
, m_daemonBlockChainHeightTtl(DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS)
, m_daemonBlockChainTargetHeight(0)
, m_daemonBlockChainTargetHeightTtl(DAEMON_BLOCKCHAIN_TARGET_HEIGHT_CACHE_TTL_SECONDS)
, m_connectionStatusTtl(WALLET_CONNECTION_STATUS_CACHE_TTL_SECONDS)
, m_currentSubaddressAccount(0)
{
m_history = new TransactionHistory(m_walletImpl->history(), this);
m_addressBook = new AddressBook(m_walletImpl->addressBook(), this);
m_subaddress = new Subaddress(m_walletImpl->subaddress(), this);
m_walletImpl->setListener(new WalletListenerImpl(this));
m_connectionStatus = Wallet::ConnectionStatus_Disconnected;
// start cache timers
@ -680,6 +766,10 @@ Wallet::~Wallet()
delete m_history;
m_history = NULL;
delete m_addressBook;
m_addressBook = NULL;
delete m_subaddress;
m_subaddress = NULL;
//Monero::WalletManagerFactory::getWalletManager()->closeWallet(m_walletImpl);
if(status() == Status_Critical)
qDebug("Not storing wallet cache");

View File

@ -20,6 +20,8 @@ class TransactionHistoryModel;
class TransactionHistorySortFilterModel;
class AddressBook;
class AddressBookModel;
class Subaddress;
class SubaddressModel;
class Wallet : public QObject
{
@ -29,17 +31,17 @@ class Wallet : public QObject
Q_PROPERTY(Status status READ status)
Q_PROPERTY(bool testnet READ testnet)
// Q_PROPERTY(ConnectionStatus connected READ connected)
Q_PROPERTY(quint32 currentSubaddressAccount READ currentSubaddressAccount)
Q_PROPERTY(bool synchronized READ synchronized)
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)
Q_PROPERTY(QString paymentId READ paymentId WRITE setPaymentId)
Q_PROPERTY(TransactionHistorySortFilterModel * historyModel READ historyModel NOTIFY historyModelChanged)
Q_PROPERTY(QString path READ path)
Q_PROPERTY(AddressBookModel * addressBookModel READ addressBookModel)
Q_PROPERTY(AddressBook * addressBook READ addressBook)
Q_PROPERTY(SubaddressModel * subaddressModel READ subaddressModel)
Q_PROPERTY(Subaddress * subaddress READ subaddress)
Q_PROPERTY(bool viewOnly READ viewOnly)
Q_PROPERTY(QString secretViewKey READ getSecretViewKey)
Q_PROPERTY(QString publicViewKey READ getPublicViewKey)
@ -98,7 +100,7 @@ public:
Q_INVOKABLE bool setPassword(const QString &password);
//! returns wallet's public address
QString address() const;
Q_INVOKABLE QString address(quint32 accountIndex, quint32 addressIndex) const;
//! returns wallet file's path
QString path() const;
@ -126,10 +128,22 @@ public:
Q_INVOKABLE void setTrustedDaemon(bool arg);
//! returns balance
Q_INVOKABLE quint64 balance() const;
Q_INVOKABLE quint64 balance(quint32 accountIndex) const;
Q_INVOKABLE quint64 balanceAll() const;
//! returns unlocked balance
Q_INVOKABLE quint64 unlockedBalance() const;
Q_INVOKABLE quint64 unlockedBalance(quint32 accountIndex) const;
Q_INVOKABLE quint64 unlockedBalanceAll() const;
//! account/address management
quint32 currentSubaddressAccount() const;
Q_INVOKABLE void switchSubaddressAccount(quint32 accountIndex);
Q_INVOKABLE void addSubaddressAccount(const QString& label);
Q_INVOKABLE quint32 numSubaddressAccounts() const;
Q_INVOKABLE quint32 numSubaddresses(quint32 accountIndex) const;
Q_INVOKABLE void addSubaddress(const QString& label);
Q_INVOKABLE QString getSubaddressLabel(quint32 accountIndex, quint32 addressIndex) const;
Q_INVOKABLE void setSubaddressLabel(quint32 accountIndex, quint32 addressIndex, const QString &label);
//! returns if view only wallet
Q_INVOKABLE bool viewOnly() const;
@ -209,6 +223,12 @@ public:
//! returns adress book model
AddressBookModel *addressBookModel() const;
//! returns subaddress
Subaddress *subaddress();
//! returns subadress model
SubaddressModel *subaddressModel();
//! generate payment id
Q_INVOKABLE QString generatePaymentId() const;
@ -235,6 +255,8 @@ public:
Q_INVOKABLE QString checkTxKey(const QString &txid, const QString &tx_key, const QString &address);
Q_INVOKABLE QString getTxProof(const QString &txid, const QString &address, const QString &message) const;
Q_INVOKABLE QString checkTxProof(const QString &txid, const QString &address, const QString &message, const QString &signature);
Q_INVOKABLE QString getSpendProof(const QString &txid, const QString &message) const;
Q_INVOKABLE QString checkSpendProof(const QString &txid, const QString &message, const QString &signature) const;
// Rescan spent outputs
Q_INVOKABLE bool rescanSpent();
@ -300,8 +322,11 @@ private:
int m_connectionStatusTtl;
mutable QTime m_connectionStatusTime;
mutable bool m_initialized;
uint32_t m_currentSubaddressAccount;
AddressBook * m_addressBook;
mutable AddressBookModel * m_addressBookModel;
Subaddress * m_subaddress;
mutable SubaddressModel * m_subaddressModel;
QMutex m_connectionStatusMutex;
bool m_connectionStatusRunning;
QString m_daemonUsername;

View File

@ -49,7 +49,7 @@ Wallet *WalletManager::openWallet(const QString &path, const QString &password,
__PRETTY_FUNCTION__, qPrintable(path), testnet);
Monero::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());
qDebug("%s: opened wallet: %s, status: %d", __PRETTY_FUNCTION__, w->address(0, 0).c_str(), w->status());
m_currentWallet = new Wallet(w);
// move wallet to the GUI thread. Otherwise it wont be emitting signals
@ -110,7 +110,7 @@ QString WalletManager::closeWallet()
QMutexLocker locker(&m_mutex);
QString result;
if (m_currentWallet) {
result = m_currentWallet->address();
result = m_currentWallet->address(0, 0);
delete m_currentWallet;
} else {
qCritical() << "Trying to close non existing wallet " << m_currentWallet;
@ -304,6 +304,7 @@ QUrl WalletManager::localPathToUrl(const QString &path) const
return QUrl::fromLocalFile(path);
}
#ifndef DISABLE_PASS_STRENGTH_METER
double WalletManager::getPasswordStrength(const QString &password) const
{
static const char *local_dict[] = {
@ -318,6 +319,7 @@ double WalletManager::getPasswordStrength(const QString &password) const
ZxcvbnUnInit();
return e;
}
#endif
bool WalletManager::saveQrCode(const QString &code, const QString &path) const
{

View File

@ -128,7 +128,9 @@ public:
Q_INVOKABLE qint64 addi(qint64 x, qint64 y) const { return x + y; }
Q_INVOKABLE qint64 subi(qint64 x, qint64 y) const { return x - y; }
#ifndef DISABLE_PASS_STRENGTH_METER
Q_INVOKABLE double getPasswordStrength(const QString &password) const;
#endif
Q_INVOKABLE QString resolveOpenAlias(const QString &address) const;
Q_INVOKABLE bool parse_uri(const QString &uri, QString &address, QString &payment_id, uint64_t &amount, QString &tx_description, QString &recipient_name, QVector<QString> &unknown_parameters, QString &error);

View File

@ -0,0 +1,89 @@
// Copyright (c) 2018, 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.
#include "SubaddressModel.h"
#include "Subaddress.h"
#include <QDebug>
#include <QHash>
#include <wallet/api/wallet2_api.h>
SubaddressModel::SubaddressModel(QObject *parent, Subaddress *subaddress)
: QAbstractListModel(parent), m_subaddress(subaddress)
{
qDebug(__FUNCTION__);
connect(m_subaddress,SIGNAL(refreshStarted()),this,SLOT(startReset()));
connect(m_subaddress,SIGNAL(refreshFinished()),this,SLOT(endReset()));
}
void SubaddressModel::startReset(){
qDebug(__FUNCTION__);
beginResetModel();
}
void SubaddressModel::endReset(){
qDebug(__FUNCTION__);
endResetModel();
}
int SubaddressModel::rowCount(const QModelIndex &parent) const
{
return m_subaddress->count();
}
QVariant SubaddressModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || (unsigned)index.row() >= m_subaddress->count())
return {};
Monero::SubaddressRow * sr = m_subaddress->getRow(index.row());
if (!sr)
return {};
QVariant result = "";
switch (role) {
case SubaddressAddressRole:
result = QString::fromStdString(sr->getAddress());
break;
case SubaddressLabelRole:
result = index.row() == 0 ? tr("Primary address") : QString::fromStdString(sr->getLabel());
break;
}
return result;
}
QHash<int, QByteArray> SubaddressModel::roleNames() const
{
static QHash<int, QByteArray> roleNames;
if (roleNames.empty())
{
roleNames.insert(SubaddressAddressRole, "address");
roleNames.insert(SubaddressLabelRole, "label");
}
return roleNames;
}

View File

@ -0,0 +1,62 @@
// Copyright (c) 2018, 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.
#ifndef SUBADDRESSMODEL_H
#define SUBADDRESSMODEL_H
#include <QAbstractListModel>
class Subaddress;
class SubaddressModel : public QAbstractListModel
{
Q_OBJECT
public:
enum SubaddressRowRole {
SubaddressRole = Qt::UserRole + 1, // for the SubaddressRow object;
SubaddressAddressRole,
SubaddressLabelRole,
};
Q_ENUM(SubaddressRowRole)
SubaddressModel(QObject *parent, Subaddress *subaddress);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
public slots:
void startReset();
void endReset();
private:
Subaddress *m_subaddress;
};
#endif // SUBADDRESSMODEL_H

View File

@ -83,6 +83,25 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const
}
break;
case TransactionSubaddrIndexRole:
{
QString str = QString{""};
bool first = true;
for (quint32 i : tInfo->subaddrIndex()) {
if (!first)
str += QString{","};
first = false;
str += QString::number(i);
}
result = str;
}
break;
case TransactionSubaddrAccountRole:
result = tInfo->subaddrAccount();
break;
case TransactionLabelRole:
result = tInfo->subaddrIndex().size() == 1 && *tInfo->subaddrIndex().begin() == 0 ? tr("Primary address") : tInfo->label();
break;
case TransactionConfirmationsRole:
result = tInfo->confirmations();
break;
@ -133,6 +152,9 @@ QHash<int, QByteArray> TransactionHistoryModel::roleNames() const
roleNames.insert(TransactionAtomicAmountRole, "atomicAmount");
roleNames.insert(TransactionFeeRole, "fee");
roleNames.insert(TransactionBlockHeightRole, "blockHeight");
roleNames.insert(TransactionSubaddrIndexRole, "subaddrIndex");
roleNames.insert(TransactionSubaddrAccountRole, "subaddrAccount");
roleNames.insert(TransactionLabelRole, "label");
roleNames.insert(TransactionConfirmationsRole, "confirmations");
roleNames.insert(TransactionConfirmationsRequiredRole, "confirmationsRequired");
roleNames.insert(TransactionHashRole, "hash");

View File

@ -25,6 +25,9 @@ public:
TransactionDisplayAmountRole,
TransactionFeeRole,
TransactionBlockHeightRole,
TransactionSubaddrIndexRole,
TransactionSubaddrAccountRole,
TransactionLabelRole,
TransactionConfirmationsRole,
TransactionConfirmationsRequiredRole,
TransactionHashRole,

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

View File

@ -1,4 +1,4 @@
// Copyright (c) 2014-2015, The Monero Project
// Copyright (c) 2014-2018, The Monero Project
//
// All rights reserved.
//

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More