mirror of
https://github.com/monero-project/monero-gui.git
synced 2024-11-17 00:07:51 +00:00
Merge pull request #1 from monero-project/master
Refresh with source fork
This commit is contained in:
commit
1ad20a1fb3
132 changed files with 28468 additions and 12053 deletions
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2014-2017, The Monero Project
|
Copyright (c) 2014-2018, The Monero Project
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -112,7 +112,7 @@ Rectangle {
|
||||||
}, State {
|
}, State {
|
||||||
name: "Receive"
|
name: "Receive"
|
||||||
PropertyChanges { target: root; currentView: receiveView }
|
PropertyChanges { target: root; currentView: receiveView }
|
||||||
PropertyChanges { target: mainFlickable; contentHeight: minHeight }
|
PropertyChanges { target: mainFlickable; contentHeight: 1000 * scaleRatio }
|
||||||
}, State {
|
}, State {
|
||||||
name: "TxKey"
|
name: "TxKey"
|
||||||
PropertyChanges { target: root; currentView: txkeyView }
|
PropertyChanges { target: root; currentView: txkeyView }
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# Monero GUI
|
# 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)
|
- Web: [getmonero.org](https://getmonero.org)
|
||||||
- Forum: [forum.getmonero.org](https://forum.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
|
## Supporting the project
|
||||||
|
|
||||||
Monero development can be supported directly through donations.
|
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.
|
||||||
|
|
||||||
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`)
|
The Monero donation address is: `44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A` (viewkey: `f359631075708155cc3d92a32b75a7d02a5dcf27756707b47a2b31b21c389501`)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2014-2017, The Monero Project
|
Copyright (c) 2014-2018, The Monero Project
|
||||||
|
|
||||||
|
|
||||||
## Current status : ALPHA
|
## Current status : ALPHA
|
||||||
|
@ -22,7 +22,7 @@ Copyright (c) 2014-2017, The Monero Project
|
||||||
|
|
||||||
# Get the apk
|
# 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
|
## 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)
|
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 :
|
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
|
adb shell pm install -r /data/local/tmp/QtApp-debug.apk
|
||||||
|
|
||||||
- Troubleshooting:
|
- Troubleshooting:
|
||||||
|
|
|
@ -88,21 +88,20 @@ APP_CFLAGS += -target armv7-none-linux-androideabi -fexceptions -fstack-protect
|
||||||
&& android update project --path . -t "${ANDROID_API}" \
|
&& 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
|
&& 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 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 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
|
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
|
RUN git clone https://github.com/monero-project/monero-gui.git \
|
||||||
|
&& cd monero-gui \
|
||||||
# NB : zxcvbn-c needs to build a local binary and Qt don't care about these environnement variable
|
&& git submodule update \
|
||||||
RUN cd monero-core \
|
&& CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ BOOST_ROOT=/opt/android/boost_1_62_0 \
|
||||||
&& CC="gcc" CXX="g++" ./build.sh release-android \
|
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 \
|
&& cd build \
|
||||||
&& make deploy
|
&& make deploy
|
||||||
|
|
||||||
|
|
36
build.sh
36
build.sh
|
@ -8,6 +8,22 @@ if [ -z $BUILD_TYPE ]; then
|
||||||
BUILD_TYPE=release
|
BUILD_TYPE=release
|
||||||
fi
|
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
|
if [ "$BUILD_TYPE" == "release" ]; then
|
||||||
echo "Building release"
|
echo "Building release"
|
||||||
CONFIG="CONFIG+=release";
|
CONFIG="CONFIG+=release";
|
||||||
|
@ -24,14 +40,16 @@ elif [ "$BUILD_TYPE" == "release-static" ]; then
|
||||||
BIN_PATH=release/bin
|
BIN_PATH=release/bin
|
||||||
elif [ "$BUILD_TYPE" == "release-android" ]; then
|
elif [ "$BUILD_TYPE" == "release-android" ]; then
|
||||||
echo "Building release for ANDROID"
|
echo "Building release for ANDROID"
|
||||||
CONFIG="CONFIG+=release static WITH_SCANNER";
|
CONFIG="CONFIG+=release static WITH_SCANNER DISABLE_PASS_STRENGTH_METER";
|
||||||
ANDROID=true
|
ANDROID=true
|
||||||
BIN_PATH=release/bin
|
BIN_PATH=release/bin
|
||||||
|
DISABLE_PASS_STRENGTH_METER=true
|
||||||
elif [ "$BUILD_TYPE" == "debug-android" ]; then
|
elif [ "$BUILD_TYPE" == "debug-android" ]; then
|
||||||
echo "Building debug for ANDROID : ultra INSECURE !!"
|
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
|
ANDROID=true
|
||||||
BIN_PATH=debug/bin
|
BIN_PATH=debug/bin
|
||||||
|
DISABLE_PASS_STRENGTH_METER=true
|
||||||
elif [ "$BUILD_TYPE" == "debug" ]; then
|
elif [ "$BUILD_TYPE" == "debug" ]; then
|
||||||
echo "Building debug"
|
echo "Building debug"
|
||||||
CONFIG="CONFIG+=debug"
|
CONFIG="CONFIG+=debug"
|
||||||
|
@ -57,15 +75,17 @@ fi
|
||||||
./get_libwallet_api.sh $BUILD_TYPE
|
./get_libwallet_api.sh $BUILD_TYPE
|
||||||
|
|
||||||
# build zxcvbn
|
# 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
|
if [ ! -d build ]; then mkdir build; fi
|
||||||
|
|
||||||
|
|
||||||
# Platform indepenent settings
|
# Platform indepenent settings
|
||||||
if [ "$ANDROID" != true ] && ([ "$platform" == "linux32" ] || [ "$platform" == "linux64" ]); then
|
if [ "$ANDROID" != true ] && ([ "$platform" == "linux32" ] || [ "$platform" == "linux64" ]); then
|
||||||
distro=$(lsb_release -is)
|
exists lsb_release && distro="$(lsb_release -is)"
|
||||||
if [ "$distro" == "Ubuntu" ]; then
|
if [ "$distro" = "Ubuntu" ] || [ "$distro" = "Fedora" ] || test -f /etc/fedora-release; then
|
||||||
CONFIG="$CONFIG libunwind_off"
|
CONFIG="$CONFIG libunwind_off"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -85,7 +105,11 @@ popd
|
||||||
echo "var GUI_MONERO_VERSION = \"$TAGNAME\"" >> version.js
|
echo "var GUI_MONERO_VERSION = \"$TAGNAME\"" >> version.js
|
||||||
|
|
||||||
cd build
|
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
|
$MAKE || exit
|
||||||
|
|
||||||
# Copy monerod to bin folder
|
# Copy monerod to bin folder
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -260,10 +260,51 @@ ListView {
|
||||||
return blockHeight
|
return blockHeight
|
||||||
if (!isOut)
|
if (!isOut)
|
||||||
return qsTr("UNCONFIRMED") + translationManager.emptyString
|
return qsTr("UNCONFIRMED") + translationManager.emptyString
|
||||||
|
if (isFailed)
|
||||||
|
return qsTr("FAILED") + translationManager.emptyString
|
||||||
return qsTr("PENDING") + 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
|
// -- "Date", "Balance" and "Amound" section
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2017, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -150,6 +150,8 @@ ListView {
|
||||||
return qsTr("(%1/%2 confirmations)").arg(confirmations).arg(confirmationsRequired)
|
return qsTr("(%1/%2 confirmations)").arg(confirmations).arg(confirmationsRequired)
|
||||||
if (!isOut)
|
if (!isOut)
|
||||||
return qsTr("UNCONFIRMED") + translationManager.emptyString
|
return qsTr("UNCONFIRMED") + translationManager.emptyString
|
||||||
|
if (isFailed)
|
||||||
|
return qsTr("FAILED") + translationManager.emptyString
|
||||||
return qsTr("PENDING") + translationManager.emptyString
|
return qsTr("PENDING") + translationManager.emptyString
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -30,6 +30,7 @@
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
property alias image : buttonImage
|
||||||
property alias imageSource : buttonImage.source
|
property alias imageSource : buttonImage.source
|
||||||
|
|
||||||
signal clicked(var mouse)
|
signal clicked(var mouse)
|
||||||
|
@ -53,7 +54,8 @@ Item {
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: buttonArea
|
id: buttonArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
onPressed: {
|
onPressed: {
|
||||||
buttonImage.x = buttonImage.x + 2
|
buttonImage.x = buttonImage.x + 2
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
181
components/InputDialog.qml
Normal file
181
components/InputDialog.qml
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -37,6 +37,7 @@ Item {
|
||||||
property alias cursorPosition: input.cursorPosition
|
property alias cursorPosition: input.cursorPosition
|
||||||
property alias echoMode: input.echoMode
|
property alias echoMode: input.echoMode
|
||||||
property int fontSize: 18 * scaleRatio
|
property int fontSize: 18 * scaleRatio
|
||||||
|
property bool showBorder: true
|
||||||
property bool error: false
|
property bool error: false
|
||||||
signal editingFinished()
|
signal editingFinished()
|
||||||
signal accepted();
|
signal accepted();
|
||||||
|
@ -52,6 +53,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
visible: showBorder
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.bottomMargin: 1 * scaleRatio
|
anchors.bottomMargin: 1 * scaleRatio
|
||||||
color: "#DBDBDB"
|
color: "#DBDBDB"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
254
components/NewPasswordDialog.qml
Normal file
254
components/NewPasswordDialog.qml
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2017, The Monero Project
|
// Copyright (c) 2017-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2017, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2017, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
109
components/SubaddressTable.qml
Normal file
109
components/SubaddressTable.qml
Normal 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
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
2
filter.h
2
filter.h
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2014-2017, The Monero Project
|
Copyright (c) 2014-2018, The Monero Project
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
; Monero Helium Hydra GUI Wallet Installer for Windows
|
; Monero Helium Hydra GUI Wallet Installer for Windows
|
||||||
; Copyright (c) 2014-2017, The Monero Project
|
; Copyright (c) 2014-2018, The Monero Project
|
||||||
; See LICENSE
|
; See LICENSE
|
||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
|
@ -33,173 +33,187 @@ Name: "en"; MessagesFile: "compiler:Default.isl"
|
||||||
|
|
||||||
|
|
||||||
[Files]
|
[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
|
Source: "FinishImage.bmp"; Flags: dontcopy
|
||||||
|
|
||||||
; Monero GUI wallet
|
; 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
|
; 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
|
; 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
|
; 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
|
; 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
|
; 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
|
; 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
|
; 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
|
; Monero blockchain utilities
|
||||||
Source: "bin\monero-blockchain-export.exe"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\monero-blockchain-export.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "bin\monero-blockchain-import.exe"; DestDir: "{app}"; Flags: comparetimestamp
|
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
|
; 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
|
; 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
|
; Core Qt runtime
|
||||||
Source: "bin\Qt5Core.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\Qt5Core.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "bin\Qt5Gui.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\Qt5Gui.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "bin\Qt5Multimedia.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\Qt5Multimedia.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "bin\Qt5MultimediaQuick_p.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\Qt5MultimediaQuick_p.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "bin\Qt5Network.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\Qt5Network.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "bin\Qt5Qml.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\Qt5Qml.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "bin\Qt5Quick.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\Qt5Quick.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "bin\Qt5Svg.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\Qt5Svg.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "bin\Qt5Widgets.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\Qt5Widgets.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "bin\Qt5XmlPatterns.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\Qt5XmlPatterns.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
|
||||||
; Qt QML elements like the local files selector "FolderListModel" and "Settings"
|
; 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
|
; 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
|
; 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
|
; 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
|
; 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)
|
; 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
|
; Qt multimedia support
|
||||||
Source: "bin\QtMultimedia\*"; DestDir: "{app}\QtMultimedia"; Flags: recursesubdirs comparetimestamp
|
Source: "bin\QtMultimedia\*"; DestDir: "{app}\QtMultimedia"; Flags: recursesubdirs ignoreversion
|
||||||
Source: "bin\mediaservice\*"; DestDir: "{app}\mediaservice"; Flags: recursesubdirs comparetimestamp
|
Source: "bin\mediaservice\*"; DestDir: "{app}\mediaservice"; Flags: recursesubdirs ignoreversion
|
||||||
|
|
||||||
; Qt support for "m3u" playlists
|
; Qt support for "m3u" playlists
|
||||||
; candidate for elimination? Don't think the GUI wallet needs such 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
|
; 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
|
; Some more Qt graphical effects
|
||||||
; "private" as a name for this directory looks a little strange. Historical reasons?
|
; "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
|
; Qt QML files
|
||||||
Source: "bin\QtQml\*"; DestDir: "{app}\QtQml"; Flags: recursesubdirs comparetimestamp
|
Source: "bin\QtQml\*"; DestDir: "{app}\QtQml"; Flags: recursesubdirs ignoreversion
|
||||||
|
|
||||||
; Qt Quick files
|
; Qt Quick files
|
||||||
Source: "bin\QtQuick\*"; DestDir: "{app}\QtQuick"; Flags: recursesubdirs comparetimestamp
|
Source: "bin\QtQuick\*"; DestDir: "{app}\QtQuick"; Flags: recursesubdirs ignoreversion
|
||||||
Source: "bin\QtQuick.2\*"; DestDir: "{app}\QtQuick.2"; Flags: recursesubdirs comparetimestamp
|
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
|
; 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\scenegraph\*"; DestDir: "{app}\scenegraph"; Flags: recursesubdirs ignoreversion
|
||||||
Source: "bin\start-low-graphics-mode.bat"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\start-low-graphics-mode.bat"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
|
||||||
; Mesa, open-source OpenGL implementation; part of "low-level graphics" support
|
; 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
|
; Left out subdirectory "qmltooling" with the Qt QML debugger: Probably not relevant in an end-user package
|
||||||
|
|
||||||
; Microsoft Direct3D runtime
|
; Microsoft Direct3D runtime
|
||||||
Source: "bin\D3Dcompiler_47.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\D3Dcompiler_47.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
|
||||||
; bzip2 support
|
; 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
|
; ANGLE ("Almost Native Graphics Layer Engine") support, as used by Qt
|
||||||
Source: "bin\libEGL.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\libEGL.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "bin\libGLESV2.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\libGLESV2.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
|
||||||
; FreeType font engine, as used by Qt
|
; 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
|
; 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+
|
; GLib, low level core library e.g. for GNOME and GTK+
|
||||||
; Really needed under Windows?
|
; 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
|
; Graphite font support
|
||||||
; Really needed?
|
; Really needed?
|
||||||
Source: "bin\libgraphite2.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\libgraphite2.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
|
||||||
; HarfBuzz OpenType text shaping engine
|
; HarfBuzz OpenType text shaping engine
|
||||||
; Really needed?
|
; 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
|
; 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?
|
; Part of cygwin? Needed by Qt somehow?
|
||||||
Source: "bin\libicudt57.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\libicudt57.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "bin\libicuin57.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\libicuin57.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "bin\libicuuc57.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\libicuuc57.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
|
||||||
; Library for native language support, part of GNU gettext
|
; 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
|
; JasPer, support for JPEG-2000
|
||||||
; was present in 0.10.3.1, not present anymore in 0.11.1.0
|
; 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
|
; 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
|
; 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
|
; 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")
|
; 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
|
; PCRE, Perl Compatible Regular Expressions
|
||||||
Source: "bin\libpcre-1.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\libpcre-1.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "bin\libpcre16-0.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\libpcre16-0.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
|
||||||
; libpng, the official PNG reference library
|
; 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
|
; 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
|
; 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
|
; C++ threading support
|
||||||
Source: "bin\libwinpthread-1.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\libwinpthread-1.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
|
||||||
; zlib compression library
|
; zlib compression library
|
||||||
Source: "bin\zlib1.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
Source: "bin\zlib1.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
|
||||||
|
|
||||||
[Tasks]
|
[Tasks]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Monero GUI Wallet Windows Installer #
|
# Monero GUI Wallet Windows Installer #
|
||||||
|
|
||||||
Copyright (c) 2014-2017, The Monero Project
|
Copyright (c) 2014-2018, The Monero Project
|
||||||
|
|
||||||
## Introduction ##
|
## Introduction ##
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<body style="font-family: Arial, Helvetica, sans-serif">
|
<body style="font-family: Arial, Helvetica, sans-serif">
|
||||||
<h1>Monero Helium Hydra GUI Wallet</h1>
|
<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>
|
Date: September 19, 2017</p>
|
||||||
|
|
||||||
<h2>Preface</h2>
|
<h2>Preface</h2>
|
||||||
|
|
BIN
lang/flags/czech.png
Normal file
BIN
lang/flags/czech.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
BIN
lang/flags/denmark.png
Normal file
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
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
BIN
lang/flags/slovakia.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
|
@ -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="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="한국어" 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="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>
|
</languages>
|
||||||
|
|
11
main.cpp
11
main.cpp
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -50,6 +50,8 @@
|
||||||
#include "model/TransactionHistorySortFilterModel.h"
|
#include "model/TransactionHistorySortFilterModel.h"
|
||||||
#include "AddressBook.h"
|
#include "AddressBook.h"
|
||||||
#include "model/AddressBookModel.h"
|
#include "model/AddressBookModel.h"
|
||||||
|
#include "Subaddress.h"
|
||||||
|
#include "model/SubaddressModel.h"
|
||||||
#include "wallet/api/wallet2_api.h"
|
#include "wallet/api/wallet2_api.h"
|
||||||
#include "MainApp.h"
|
#include "MainApp.h"
|
||||||
|
|
||||||
|
@ -70,6 +72,7 @@ void messageHandler(QtMsgType type, const QMessageLogContext &context, const QSt
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
Monero::Utils::onStartup();
|
||||||
// // Enable high DPI scaling on windows & linux
|
// // Enable high DPI scaling on windows & linux
|
||||||
//#if !defined(Q_OS_ANDROID) && QT_VERSION >= 0x050600
|
//#if !defined(Q_OS_ANDROID) && QT_VERSION >= 0x050600
|
||||||
// QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
// QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
|
@ -132,6 +135,12 @@ int main(int argc, char *argv[])
|
||||||
qmlRegisterUncreatableType<AddressBook>("moneroComponents.AddressBook", 1, 0, "AddressBook",
|
qmlRegisterUncreatableType<AddressBook>("moneroComponents.AddressBook", 1, 0, "AddressBook",
|
||||||
"AddressBook can't be instantiated directly");
|
"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<PendingTransaction::Priority>();
|
||||||
qRegisterMetaType<TransactionInfo::Direction>();
|
qRegisterMetaType<TransactionInfo::Direction>();
|
||||||
qRegisterMetaType<TransactionHistoryModel::TransactionInfoRole>();
|
qRegisterMetaType<TransactionHistoryModel::TransactionInfoRole>();
|
||||||
|
|
240
main.qml
240
main.qml
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -53,7 +53,7 @@ ApplicationWindow {
|
||||||
property var currentWallet;
|
property var currentWallet;
|
||||||
property var transaction;
|
property var transaction;
|
||||||
property var transactionDescription;
|
property var transactionDescription;
|
||||||
property alias password : passwordDialog.password
|
property var walletPassword
|
||||||
property bool isNewWallet: false
|
property bool isNewWallet: false
|
||||||
property int restoreHeight:0
|
property int restoreHeight:0
|
||||||
property bool daemonSynced: false
|
property bool daemonSynced: false
|
||||||
|
@ -144,6 +144,8 @@ ApplicationWindow {
|
||||||
else if(middlePanel.state === "Transfer") middlePanel.state = "Settings"
|
else if(middlePanel.state === "Transfer") middlePanel.state = "Settings"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (middlePanel.state !== "Advanced") updateBalance();
|
||||||
|
|
||||||
leftPanel.selectItem(middlePanel.state)
|
leftPanel.selectItem(middlePanel.state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +166,7 @@ ApplicationWindow {
|
||||||
persistentSettings.restore_height = 0
|
persistentSettings.restore_height = 0
|
||||||
restoreHeight = 0;
|
restoreHeight = 0;
|
||||||
persistentSettings.is_recovering = false
|
persistentSettings.is_recovering = false
|
||||||
appWindow.password = ""
|
walletPassword = ""
|
||||||
fileDialog.open();
|
fileDialog.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +226,7 @@ ApplicationWindow {
|
||||||
wallet_path = moneroAccountsDir + wallet_path;
|
wallet_path = moneroAccountsDir + wallet_path;
|
||||||
// console.log("opening wallet at: ", wallet_path, "with password: ", appWindow.password);
|
// console.log("opening wallet at: ", wallet_path, "with password: ", appWindow.password);
|
||||||
console.log("opening wallet at: ", wallet_path, ", testnet: ", persistentSettings.testnet);
|
console.log("opening wallet at: ", wallet_path, ", testnet: ", persistentSettings.testnet);
|
||||||
walletManager.openWalletAsync(wallet_path, appWindow.password,
|
walletManager.openWalletAsync(wallet_path, walletPassword,
|
||||||
persistentSettings.testnet);
|
persistentSettings.testnet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,6 +309,13 @@ ApplicationWindow {
|
||||||
return path.replace(/.*[\/\\]/, '').replace(/\.keys$/, '')
|
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){
|
function onWalletConnectionStatusChanged(status){
|
||||||
console.log("Wallet connection status changed " + status)
|
console.log("Wallet connection status changed " + status)
|
||||||
middlePanel.updateStatus();
|
middlePanel.updateStatus();
|
||||||
|
@ -322,7 +331,7 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
// initialize transaction history once wallet is initialized first time;
|
// initialize transaction history once wallet is initialized first time;
|
||||||
if (!walletInitialized) {
|
if (!walletInitialized) {
|
||||||
currentWallet.history.refresh()
|
currentWallet.history.refresh(currentWallet.currentSubaddressAccount)
|
||||||
walletInitialized = true
|
walletInitialized = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,25 +340,25 @@ ApplicationWindow {
|
||||||
walletName = usefulName(wallet.path)
|
walletName = usefulName(wallet.path)
|
||||||
console.log(">>> wallet opened: " + wallet)
|
console.log(">>> wallet opened: " + wallet)
|
||||||
if (wallet.status !== Wallet.Status_Ok) {
|
if (wallet.status !== Wallet.Status_Ok) {
|
||||||
if (appWindow.password === '') {
|
passwordDialog.onAcceptedCallback = function() {
|
||||||
console.error("Error opening wallet with empty password: ", wallet.errorString);
|
walletPassword = passwordDialog.password;
|
||||||
console.log("closing wallet async : " + wallet.address)
|
appWindow.initialize();
|
||||||
closeWallet();
|
}
|
||||||
// try to open wallet with password;
|
passwordDialog.onRejectedCallback = function() {
|
||||||
passwordDialog.open(walletName);
|
walletPassword = "";
|
||||||
} else {
|
//appWindow.enableUI(false)
|
||||||
// opening with password but password doesn't match
|
rootItem.state = "wizard";
|
||||||
console.error("Error opening wallet with password: ", wallet.errorString);
|
}
|
||||||
|
// opening with password but password doesn't match
|
||||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
console.error("Error opening wallet with password: ", wallet.errorString);
|
||||||
informationPopup.text = qsTr("Couldn't open wallet: ") + wallet.errorString;
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||||
informationPopup.icon = StandardIcon.Critical
|
informationPopup.text = qsTr("Couldn't open wallet: ") + wallet.errorString;
|
||||||
console.log("closing wallet async : " + wallet.address)
|
informationPopup.icon = StandardIcon.Critical
|
||||||
closeWallet();
|
console.log("closing wallet async : " + wallet.address)
|
||||||
informationPopup.open()
|
closeWallet();
|
||||||
informationPopup.onCloseCallback = function() {
|
informationPopup.open()
|
||||||
passwordDialog.open(walletName)
|
informationPopup.onCloseCallback = function() {
|
||||||
}
|
passwordDialog.open(walletName)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -365,13 +374,12 @@ ApplicationWindow {
|
||||||
|
|
||||||
function onWalletUpdate() {
|
function onWalletUpdate() {
|
||||||
console.log(">>> wallet updated")
|
console.log(">>> wallet updated")
|
||||||
middlePanel.unlockedBalanceText = leftPanel.unlockedBalanceText = walletManager.displayAmount(currentWallet.unlockedBalance);
|
updateBalance();
|
||||||
middlePanel.balanceText = leftPanel.balanceText = walletManager.displayAmount(currentWallet.balance);
|
|
||||||
// Update history if new block found since last update
|
// Update history if new block found since last update
|
||||||
if(foundNewBlock) {
|
if(foundNewBlock) {
|
||||||
foundNewBlock = false;
|
foundNewBlock = false;
|
||||||
console.log("New block found - updating history")
|
console.log("New block found - updating history")
|
||||||
currentWallet.history.refresh()
|
currentWallet.history.refresh(currentWallet.currentSubaddressAccount)
|
||||||
timeToUnlock = currentWallet.history.minutesToUnlock
|
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");
|
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");
|
console.log("Saving wallet after first refresh");
|
||||||
currentWallet.store()
|
currentWallet.store()
|
||||||
isNewWallet = false
|
isNewWallet = false
|
||||||
|
|
||||||
|
// Update History
|
||||||
|
currentWallet.history.refresh(currentWallet.currentSubaddressAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// recovering from seed is finished after first refresh
|
// recovering from seed is finished after first refresh
|
||||||
|
@ -457,7 +468,7 @@ ApplicationWindow {
|
||||||
|
|
||||||
// Update history on every refresh if it's empty
|
// Update history on every refresh if it's empty
|
||||||
if(currentWallet.history.count == 0)
|
if(currentWallet.history.count == 0)
|
||||||
currentWallet.history.refresh()
|
currentWallet.history.refresh(currentWallet.currentSubaddressAccount)
|
||||||
|
|
||||||
onWalletUpdate();
|
onWalletUpdate();
|
||||||
}
|
}
|
||||||
|
@ -520,19 +531,21 @@ ApplicationWindow {
|
||||||
currentWallet.refresh()
|
currentWallet.refresh()
|
||||||
console.log("Confirmed money found")
|
console.log("Confirmed money found")
|
||||||
// history refresh is handled by walletUpdated
|
// history refresh is handled by walletUpdated
|
||||||
|
currentWallet.history.refresh(currentWallet.currentSubaddressAccount) // this will refresh model
|
||||||
|
currentWallet.subaddress.refresh(currentWallet.currentSubaddressAccount)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onWalletUnconfirmedMoneyReceived(txId, amount) {
|
function onWalletUnconfirmedMoneyReceived(txId, amount) {
|
||||||
// refresh history
|
// refresh history
|
||||||
console.log("unconfirmed money found")
|
console.log("unconfirmed money found")
|
||||||
currentWallet.history.refresh()
|
currentWallet.history.refresh(currentWallet.currentSubaddressAccount)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onWalletMoneySent(txId, amount) {
|
function onWalletMoneySent(txId, amount) {
|
||||||
// refresh transaction history here
|
// refresh transaction history here
|
||||||
console.log("money sent found")
|
console.log("money sent found")
|
||||||
currentWallet.refresh()
|
currentWallet.refresh()
|
||||||
currentWallet.history.refresh() // this will refresh model
|
currentWallet.history.refresh(currentWallet.currentSubaddressAccount) // this will refresh model
|
||||||
}
|
}
|
||||||
|
|
||||||
function walletsFound() {
|
function walletsFound() {
|
||||||
|
@ -578,8 +591,11 @@ ApplicationWindow {
|
||||||
// here we show confirmation popup;
|
// here we show confirmation popup;
|
||||||
|
|
||||||
transactionConfirmationPopup.title = qsTr("Confirmation") + translationManager.emptyString
|
transactionConfirmationPopup.title = qsTr("Confirmation") + translationManager.emptyString
|
||||||
transactionConfirmationPopup.text = qsTr("Please confirm transaction:\n")
|
transactionConfirmationPopup.text = qsTr("Please confirm transaction:\n");
|
||||||
+ (address === "" ? "" : (qsTr("\nAddress: ") + address))
|
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))
|
+ (paymentId === "" ? "" : (qsTr("\nPayment ID: ") + paymentId))
|
||||||
+ qsTr("\n\nAmount: ") + walletManager.displayAmount(transaction.amount)
|
+ qsTr("\n\nAmount: ") + walletManager.displayAmount(transaction.amount)
|
||||||
+ qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee)
|
+ qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee)
|
||||||
|
@ -764,7 +780,11 @@ ApplicationWindow {
|
||||||
", address: ", address,
|
", address: ", address,
|
||||||
", message: ", message);
|
", 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;
|
informationPopup.title = qsTr("Payment proof") + translationManager.emptyString;
|
||||||
if (result.startsWith("error|")) {
|
if (result.startsWith("error|")) {
|
||||||
var errorString = result.split("|")[1];
|
var errorString = result.split("|")[1];
|
||||||
|
@ -786,12 +806,16 @@ ApplicationWindow {
|
||||||
", message: ", message,
|
", message: ", message,
|
||||||
", signature: ", signature);
|
", 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("|");
|
var results = result.split("|");
|
||||||
if (results.length == 5 && results[0] == "true") {
|
if (address.length > 0 && results.length == 5 && results[0] === "true") {
|
||||||
var good = results[1] == "true";
|
var good = results[1] === "true";
|
||||||
var received = results[2];
|
var received = results[2];
|
||||||
var in_pool = results[3] == "true";
|
var in_pool = results[3] === "true";
|
||||||
var confirmations = results[4];
|
var confirmations = results[4];
|
||||||
|
|
||||||
informationPopup.title = qsTr("Payment proof check") + translationManager.emptyString;
|
informationPopup.title = qsTr("Payment proof check") + translationManager.emptyString;
|
||||||
|
@ -812,6 +836,12 @@ ApplicationWindow {
|
||||||
informationPopup.text = qsTr("This address received nothing");
|
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 {
|
else {
|
||||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||||
informationPopup.text = currentWallet.errorString;
|
informationPopup.text = currentWallet.errorString;
|
||||||
|
@ -931,7 +961,14 @@ ApplicationWindow {
|
||||||
rootItem.state = "wizard"
|
rootItem.state = "wizard"
|
||||||
} else {
|
} else {
|
||||||
rootItem.state = "normal"
|
rootItem.state = "normal"
|
||||||
|
passwordDialog.onAcceptedCallback = function() {
|
||||||
|
walletPassword = passwordDialog.password;
|
||||||
initialize(persistentSettings);
|
initialize(persistentSettings);
|
||||||
|
}
|
||||||
|
passwordDialog.onRejectedCallback = function() {
|
||||||
|
rootItem.state = "wizard"
|
||||||
|
}
|
||||||
|
passwordDialog.open(usefulName(walletPath()))
|
||||||
}
|
}
|
||||||
|
|
||||||
checkUpdates();
|
checkUpdates();
|
||||||
|
@ -993,8 +1030,8 @@ ApplicationWindow {
|
||||||
id: transactionConfirmationPopup
|
id: transactionConfirmationPopup
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
close();
|
close();
|
||||||
transactionConfirmationPasswordDialog.onAcceptedCallback = function() {
|
passwordDialog.onAcceptedCallback = function() {
|
||||||
if(appWindow.password === transactionConfirmationPasswordDialog.password){
|
if(walletPassword === passwordDialog.password){
|
||||||
// Save transaction to file if view only wallet
|
// Save transaction to file if view only wallet
|
||||||
if(viewOnly) {
|
if(viewOnly) {
|
||||||
saveTxDialog.open();
|
saveTxDialog.open();
|
||||||
|
@ -1006,15 +1043,12 @@ ApplicationWindow {
|
||||||
informationPopup.text = qsTr("Wrong password");
|
informationPopup.text = qsTr("Wrong password");
|
||||||
informationPopup.open()
|
informationPopup.open()
|
||||||
informationPopup.onCloseCallback = function() {
|
informationPopup.onCloseCallback = function() {
|
||||||
transactionConfirmationPasswordDialog.open()
|
passwordDialog.open()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
transactionConfirmationPasswordDialog.password = ""
|
|
||||||
}
|
}
|
||||||
transactionConfirmationPasswordDialog.onRejectedCallback = function() {
|
passwordDialog.onRejectedCallback = null;
|
||||||
transactionConfirmationPasswordDialog.password = ""
|
passwordDialog.open()
|
||||||
}
|
|
||||||
transactionConfirmationPasswordDialog.open()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1052,7 +1086,15 @@ ApplicationWindow {
|
||||||
console.log(moneroAccountsDir)
|
console.log(moneroAccountsDir)
|
||||||
console.log(fileDialog.fileUrl)
|
console.log(fileDialog.fileUrl)
|
||||||
console.log(persistentSettings.wallet_path)
|
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: {
|
onRejected: {
|
||||||
console.log("Canceled")
|
console.log("Canceled")
|
||||||
|
@ -1118,21 +1160,6 @@ ApplicationWindow {
|
||||||
visible: false
|
visible: false
|
||||||
z: parent.z + 1
|
z: parent.z + 1
|
||||||
anchors.fill: parent
|
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 onAcceptedCallback
|
||||||
property var onRejectedCallback
|
property var onRejectedCallback
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
|
@ -1145,34 +1172,43 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PasswordDialog {
|
NewPasswordDialog {
|
||||||
id: settingsPasswordDialog
|
id: newPasswordDialog
|
||||||
z: parent.z + 1
|
z: parent.z + 1
|
||||||
visible:false
|
visible:false
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
if(appWindow.password === settingsPasswordDialog.password){
|
if (currentWallet.setPassword(newPasswordDialog.password)) {
|
||||||
if(currentWallet.seedLanguage == "") {
|
appWindow.walletPassword = newPasswordDialog.password;
|
||||||
console.log("No seed language set. Using English as default");
|
informationPopup.title = qsTr("Information") + translationManager.emptyString;
|
||||||
currentWallet.setSeedLanguage("English");
|
informationPopup.text = qsTr("Password changed successfully") + translationManager.emptyString;
|
||||||
}
|
informationPopup.icon = StandardIcon.Information;
|
||||||
|
|
||||||
// Load keys page
|
|
||||||
middlePanel.state = "Keys"
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||||
informationPopup.text = qsTr("Wrong password");
|
informationPopup.text = qsTr("Error: ") + currentWallet.errorString;
|
||||||
informationPopup.open()
|
informationPopup.icon = StandardIcon.Critical;
|
||||||
informationPopup.onCloseCallback = function() {
|
|
||||||
settingsPasswordDialog.open()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
informationPopup.onCloseCallback = null;
|
||||||
settingsPasswordDialog.password = ""
|
informationPopup.open();
|
||||||
}
|
}
|
||||||
onRejected: {
|
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.top: mobileHeader.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
onDashboardClicked: {middlePanel.state = "Dashboard"; if(isMobile) hideMenu()}
|
onDashboardClicked: { middlePanel.state = "Dashboard"; if(isMobile) hideMenu(); updateBalance(); }
|
||||||
onTransferClicked: {middlePanel.state = "Transfer"; if(isMobile) hideMenu()}
|
onTransferClicked: { middlePanel.state = "Transfer"; if(isMobile) hideMenu(); updateBalance(); }
|
||||||
onReceiveClicked: {middlePanel.state = "Receive"; if(isMobile) hideMenu()}
|
onReceiveClicked: { middlePanel.state = "Receive"; if(isMobile) hideMenu(); updateBalance(); }
|
||||||
onTxkeyClicked: {middlePanel.state = "TxKey"; if(isMobile) hideMenu()}
|
onTxkeyClicked: { middlePanel.state = "TxKey"; if(isMobile) hideMenu(); updateBalance(); }
|
||||||
onHistoryClicked: {middlePanel.state = "History"; if(isMobile) hideMenu()}
|
onHistoryClicked: { middlePanel.state = "History"; if(isMobile) hideMenu(); updateBalance(); }
|
||||||
onAddressBookClicked: {middlePanel.state = "AddressBook"; if(isMobile) hideMenu()}
|
onAddressBookClicked: { middlePanel.state = "AddressBook"; if(isMobile) hideMenu(); updateBalance(); }
|
||||||
onMiningClicked: {middlePanel.state = "Mining"; if(isMobile) hideMenu()}
|
onMiningClicked: { middlePanel.state = "Mining"; if(isMobile) hideMenu(); updateBalance(); }
|
||||||
onSignClicked: {middlePanel.state = "Sign"; if(isMobile) hideMenu()}
|
onSignClicked: { middlePanel.state = "Sign"; if(isMobile) hideMenu(); updateBalance(); }
|
||||||
onSettingsClicked: {middlePanel.state = "Settings"; if(isMobile) hideMenu()}
|
onSettingsClicked: { middlePanel.state = "Settings"; if(isMobile) hideMenu(); updateBalance(); }
|
||||||
onKeysClicked: {settingsPasswordDialog.open(); if(isMobile) hideMenu()}
|
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 {
|
RightPanel {
|
||||||
|
|
|
@ -35,6 +35,8 @@ HEADERS += \
|
||||||
src/QR-Code-generator/QrSegment.hpp \
|
src/QR-Code-generator/QrSegment.hpp \
|
||||||
src/model/AddressBookModel.h \
|
src/model/AddressBookModel.h \
|
||||||
src/libwalletqt/AddressBook.h \
|
src/libwalletqt/AddressBook.h \
|
||||||
|
src/model/SubaddressModel.h \
|
||||||
|
src/libwalletqt/Subaddress.h \
|
||||||
src/zxcvbn-c/zxcvbn.h \
|
src/zxcvbn-c/zxcvbn.h \
|
||||||
src/libwalletqt/UnsignedTransaction.h \
|
src/libwalletqt/UnsignedTransaction.h \
|
||||||
MainApp.h
|
MainApp.h
|
||||||
|
@ -58,10 +60,18 @@ SOURCES += main.cpp \
|
||||||
src/QR-Code-generator/QrSegment.cpp \
|
src/QR-Code-generator/QrSegment.cpp \
|
||||||
src/model/AddressBookModel.cpp \
|
src/model/AddressBookModel.cpp \
|
||||||
src/libwalletqt/AddressBook.cpp \
|
src/libwalletqt/AddressBook.cpp \
|
||||||
|
src/model/SubaddressModel.cpp \
|
||||||
|
src/libwalletqt/Subaddress.cpp \
|
||||||
src/zxcvbn-c/zxcvbn.c \
|
src/zxcvbn-c/zxcvbn.c \
|
||||||
src/libwalletqt/UnsignedTransaction.cpp \
|
src/libwalletqt/UnsignedTransaction.cpp \
|
||||||
MainApp.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 {
|
!ios {
|
||||||
HEADERS += src/daemon/DaemonManager.h
|
HEADERS += src/daemon/DaemonManager.h
|
||||||
SOURCES += src/daemon/DaemonManager.cpp
|
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_he.ts \ # Hebrew
|
||||||
$$PWD/translations/monero-core_ko.ts \ # Korean
|
$$PWD/translations/monero-core_ko.ts \ # Korean
|
||||||
$$PWD/translations/monero-core_ro.ts \ # Romanian
|
$$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) {
|
CONFIG(release, debug|release) {
|
||||||
DESTDIR = release/bin
|
DESTDIR = release/bin
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -546,7 +546,7 @@ Rectangle {
|
||||||
|
|
||||||
function onPageCompleted() {
|
function onPageCompleted() {
|
||||||
if(currentWallet != null && typeof currentWallet.history !== "undefined" ) {
|
if(currentWallet != null && typeof currentWallet.history !== "undefined" ) {
|
||||||
currentWallet.history.refresh()
|
currentWallet.history.refresh(currentWallet.currentSubaddressAccount)
|
||||||
table.addressBookModel = currentWallet ? currentWallet.addressBookModel : null
|
table.addressBookModel = currentWallet ? currentWallet.addressBookModel : null
|
||||||
transactionTypeDropdown.update()
|
transactionTypeDropdown.update()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2017, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -151,7 +151,7 @@ Rectangle {
|
||||||
releasedColor: "#FF6C3C"
|
releasedColor: "#FF6C3C"
|
||||||
pressedColor: "#FF4304"
|
pressedColor: "#FF4304"
|
||||||
onClicked: {
|
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) {
|
if (success) {
|
||||||
update()
|
update()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -38,53 +38,26 @@ import moneroComponents.Wallet 1.0
|
||||||
import moneroComponents.WalletManager 1.0
|
import moneroComponents.WalletManager 1.0
|
||||||
import moneroComponents.TransactionHistory 1.0
|
import moneroComponents.TransactionHistory 1.0
|
||||||
import moneroComponents.TransactionHistoryModel 1.0
|
import moneroComponents.TransactionHistoryModel 1.0
|
||||||
|
import moneroComponents.Subaddress 1.0
|
||||||
|
import moneroComponents.SubaddressModel 1.0
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
id: pageReceive
|
||||||
color: "#F0EEEE"
|
color: "#F0EEEE"
|
||||||
property alias addressText : addressLine.text
|
|
||||||
property alias paymentIdText : paymentIdLine.text
|
|
||||||
property alias integratedAddressText : integratedAddressLine.text
|
|
||||||
property var model
|
property var model
|
||||||
|
property var current_address
|
||||||
|
property alias addressText : pageReceive.current_address
|
||||||
property string trackingLineText: ""
|
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() {
|
function makeQRCodeString() {
|
||||||
var s = "monero:"
|
var s = "monero:"
|
||||||
var nfields = 0
|
var nfields = 0
|
||||||
s += addressLine.text
|
s += current_address;
|
||||||
var amount = amountLine.text.trim()
|
var amount = amountLine.text.trim()
|
||||||
if (amount !== "") {
|
if (amount !== "") {
|
||||||
s += (nfields++ ? "&" : "?")
|
s += (nfields++ ? "&" : "?")
|
||||||
s += "tx_amount=" + amount
|
s += "tx_amount=" + amount
|
||||||
}
|
}
|
||||||
var pid = paymentIdLine.text.trim()
|
|
||||||
if (pid !== "") {
|
|
||||||
s += (nfields++ ? "&" : "?")
|
|
||||||
s += "tx_payment_id=" + pid
|
|
||||||
}
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,13 +85,14 @@ Rectangle {
|
||||||
var count = model.rowCount()
|
var count = model.rowCount()
|
||||||
var totalAmount = 0
|
var totalAmount = 0
|
||||||
var nTransactions = 0
|
var nTransactions = 0
|
||||||
var list = ""
|
var list = []
|
||||||
var blockchainHeight = 0
|
var blockchainHeight = 0
|
||||||
for (var i = 0; i < count; ++i) {
|
for (var i = 0; i < count; ++i) {
|
||||||
var idx = model.index(i, 0)
|
var idx = model.index(i, 0)
|
||||||
var isout = model.data(idx, TransactionHistoryModel.TransactionIsOutRole);
|
var isout = model.data(idx, TransactionHistoryModel.TransactionIsOutRole);
|
||||||
var payment_id = model.data(idx, TransactionHistoryModel.TransactionPaymentIdRole);
|
var subaddrAccount = model.data(idx, TransactionHistoryModel.TransactionSubaddrAccountRole);
|
||||||
if (!isout && payment_id == paymentIdLine.text) {
|
var subaddrIndex = model.data(idx, TransactionHistoryModel.TransactionSubaddrIndexRole);
|
||||||
|
if (!isout && subaddrAccount == appWindow.currentWallet.currentSubaddressAccount && subaddrIndex == table.currentIndex) {
|
||||||
var amount = model.data(idx, TransactionHistoryModel.TransactionAtomicAmountRole);
|
var amount = model.data(idx, TransactionHistoryModel.TransactionAtomicAmountRole);
|
||||||
totalAmount = walletManager.addi(totalAmount, amount)
|
totalAmount = walletManager.addi(totalAmount, amount)
|
||||||
nTransactions += 1
|
nTransactions += 1
|
||||||
|
@ -126,21 +100,25 @@ Rectangle {
|
||||||
var txid = model.data(idx, TransactionHistoryModel.TransactionHashRole);
|
var txid = model.data(idx, TransactionHistoryModel.TransactionHashRole);
|
||||||
var blockHeight = model.data(idx, TransactionHistoryModel.TransactionBlockHeightRole);
|
var blockHeight = model.data(idx, TransactionHistoryModel.TransactionBlockHeightRole);
|
||||||
if (blockHeight == 0) {
|
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 {
|
} else {
|
||||||
if (blockchainHeight == 0)
|
if (blockchainHeight == 0)
|
||||||
blockchainHeight = walletManager.blockchainHeight()
|
blockchainHeight = walletManager.blockchainHeight()
|
||||||
var confirmations = blockchainHeight - blockHeight - 1
|
var confirmations = blockchainHeight - blockHeight - 1
|
||||||
var displayAmount = model.data(idx, TransactionHistoryModel.TransactionDisplayAmountRole);
|
var displayAmount = model.data(idx, TransactionHistoryModel.TransactionDisplayAmountRole);
|
||||||
if (confirmations > 1) {
|
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 {
|
} 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) {
|
if (nTransactions == 0) {
|
||||||
setTrackingLineText(qsTr("No transaction found yet...") + translationManager.emptyString)
|
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 }
|
Clipboard { id: clipboard }
|
||||||
|
@ -186,116 +164,68 @@ Rectangle {
|
||||||
id: addressRow
|
id: addressRow
|
||||||
Label {
|
Label {
|
||||||
id: addressLabel
|
id: addressLabel
|
||||||
text: qsTr("Address") + translationManager.emptyString
|
text: qsTr("Addresses") + translationManager.emptyString
|
||||||
width: mainLayout.labelWidth
|
width: mainLayout.labelWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
LineEdit {
|
Rectangle {
|
||||||
id: addressLine
|
id: tableRect
|
||||||
fontSize: mainLayout.lineEditFontSize
|
|
||||||
placeholderText: qsTr("ReadOnly wallet address displayed here") + translationManager.emptyString;
|
|
||||||
readOnly: true
|
|
||||||
width: mainLayout.editWidth
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
onTextChanged: cursorPosition = 0
|
Layout.preferredHeight: 200
|
||||||
|
color: "#FFFFFF"
|
||||||
IconButton {
|
Scroll {
|
||||||
imageSource: "../images/copyToClipboard.png"
|
id: flickableScroll
|
||||||
onClicked: {
|
anchors.right: table.right
|
||||||
if (addressLine.text.length > 0) {
|
anchors.top: table.top
|
||||||
console.log(addressLine.text + " copied to clipboard")
|
anchors.bottom: table.bottom
|
||||||
clipboard.setText(addressLine.text)
|
flickable: table
|
||||||
appWindow.showStatusMessage(qsTr("Address copied to clipboard"),3)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
SubaddressTable {
|
||||||
}
|
id: table
|
||||||
|
anchors.fill: parent
|
||||||
GridLayout {
|
onContentYChanged: flickableScroll.flickableContentYChanged()
|
||||||
id: paymentIdRow
|
onCurrentItemChanged: {
|
||||||
columns:2
|
current_address = appWindow.currentWallet.address(appWindow.currentWallet.currentSubaddressAccount, table.currentIndex);
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StandardButton {
|
RowLayout {
|
||||||
id: generatePaymentId
|
spacing: 20
|
||||||
shadowReleasedColor: "#FF4304"
|
StandardButton {
|
||||||
shadowPressedColor: "#B32D00"
|
shadowReleasedColor: "#FF4304"
|
||||||
releasedColor: "#FF6C3C"
|
shadowPressedColor: "#B32D00"
|
||||||
pressedColor: "#FF4304"
|
releasedColor: "#FF6C3C"
|
||||||
text: qsTr("Generate") + translationManager.emptyString;
|
pressedColor: "#FF4304"
|
||||||
onClicked: updatePaymentId()
|
text: qsTr("Create new address") + translationManager.emptyString;
|
||||||
}
|
|
||||||
|
|
||||||
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"
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (integratedAddressLine.text.length > 0) {
|
inputDialog.labelText = qsTr("Set the label of the new address:") + translationManager.emptyString
|
||||||
clipboard.setText(integratedAddressLine.text)
|
inputDialog.inputText = qsTr("(Untitled)")
|
||||||
appWindow.showStatusMessage(qsTr("Integrated address copied to clipboard"),3)
|
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 {
|
Label {
|
||||||
id: trackingLabel
|
id: trackingLabel
|
||||||
textFormat: Text.RichText
|
textFormat: Text.RichText
|
||||||
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>\
|
text: "<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>")
|
qsTr("Tracking") +
|
||||||
+ translationManager.emptyString
|
"<font size='2'> (</font><a href='#'>" +
|
||||||
|
qsTr("help") +
|
||||||
|
"</a><font size='2'>)</font>" +
|
||||||
|
translationManager.emptyString
|
||||||
width: mainLayout.labelWidth
|
width: mainLayout.labelWidth
|
||||||
onLinkActivated: {
|
onLinkActivated: {
|
||||||
trackingHowToUseDialog.title = qsTr("Tracking payments") + translationManager.emptyString;
|
trackingHowToUseDialog.title = qsTr("Tracking payments") + translationManager.emptyString;
|
||||||
trackingHowToUseDialog.text = qsTr(
|
trackingHowToUseDialog.text = qsTr(
|
||||||
"<p><font size='+2'>This is a simple sales tracker:</font></p>" +
|
"<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 " +
|
"<p>Let your customer scan that QR code to make a payment (if that customer has software which " +
|
||||||
"supports QR code scanning).</p>" +
|
"supports QR code scanning).</p>" +
|
||||||
"<p>This page will automatically scan the blockchain and the tx pool " +
|
"<p>This page will automatically scan the blockchain and the tx pool " +
|
||||||
|
@ -427,11 +359,12 @@ Rectangle {
|
||||||
|
|
||||||
function onPageCompleted() {
|
function onPageCompleted() {
|
||||||
console.log("Receive page loaded");
|
console.log("Receive page loaded");
|
||||||
|
table.model = currentWallet.subaddressModel;
|
||||||
|
|
||||||
if (appWindow.currentWallet) {
|
if (appWindow.currentWallet) {
|
||||||
if (addressLine.text.length === 0 || addressLine.text !== appWindow.currentWallet.address) {
|
current_address = appWindow.currentWallet.address(appWindow.currentWallet.currentSubaddressAccount, 0)
|
||||||
addressLine.text = appWindow.currentWallet.address
|
appWindow.currentWallet.subaddress.refresh(appWindow.currentWallet.currentSubaddressAccount)
|
||||||
}
|
table.currentIndex = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
update()
|
update()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// 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 {
|
RowLayout {
|
||||||
|
@ -565,6 +591,10 @@ Rectangle {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: (typeof currentWallet == "undefined") ? "" : qsTr("Wallet log path: ") + currentWallet.walletLogPath + translationManager.emptyString
|
text: (typeof currentWallet == "undefined") ? "" : qsTr("Wallet log path: ") + currentWallet.walletLogPath + translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
TextBlock {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("Wallet Name: ") + walletName + translationManager.emptyString
|
||||||
|
}
|
||||||
TextBlock {
|
TextBlock {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: (typeof currentWallet == "undefined") ? "" : qsTr("Daemon log path: ") + currentWallet.daemonLogPath + translationManager.emptyString
|
text: (typeof currentWallet == "undefined") ? "" : qsTr("Daemon log path: ") + currentWallet.daemonLogPath + translationManager.emptyString
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -383,9 +383,12 @@ Rectangle {
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: verifyAddressLabel
|
id: verifyAddressLabel
|
||||||
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: %1px;}</style>\
|
text: "<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: " + (14 * scaleRatio) + "px;}</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)
|
qsTr("Signing address") +
|
||||||
+ translationManager.emptyString
|
"<font size='" + (2 * scaleRatio) + "'> ( " +
|
||||||
|
qsTr("Paste in or select from <a href='#'>Address book</a>") +
|
||||||
|
" )</font>" +
|
||||||
|
translationManager.emptyString
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
font.pixelSize: 14 * scaleRatio
|
font.pixelSize: 14 * scaleRatio
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -41,7 +41,10 @@ Rectangle {
|
||||||
signal sweepUnmixableClicked()
|
signal sweepUnmixableClicked()
|
||||||
|
|
||||||
color: "#F0EEEE"
|
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
|
property bool showAdvanced: false
|
||||||
|
|
||||||
function scaleValueToMixinCount(scaleValue) {
|
function scaleValueToMixinCount(scaleValue) {
|
||||||
|
@ -184,15 +187,6 @@ Rectangle {
|
||||||
// For translations to work, the strings need to be listed in
|
// For translations to work, the strings need to be listed in
|
||||||
// the file components/StandardDropdown.qml too.
|
// 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
|
// Priorites after v5
|
||||||
ListModel {
|
ListModel {
|
||||||
id: priorityModelV5
|
id: priorityModelV5
|
||||||
|
@ -222,10 +216,12 @@ Rectangle {
|
||||||
Label {
|
Label {
|
||||||
id: addressLabel
|
id: addressLabel
|
||||||
textFormat: Text.RichText
|
textFormat: Text.RichText
|
||||||
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>\
|
text: "<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>")
|
qsTr("Address") +
|
||||||
+ translationManager.emptyString
|
"<font size='2'> ( " +
|
||||||
|
qsTr("Paste in or select from <a href='#'>Address book</a>") +
|
||||||
|
" )</font>" +
|
||||||
|
translationManager.emptyString
|
||||||
onLinkActivated: appWindow.showPageRequest("AddressBook")
|
onLinkActivated: appWindow.showPageRequest("AddressBook")
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
@ -335,7 +331,7 @@ Rectangle {
|
||||||
enabled : !appWindow.viewOnly && pageRoot.checkInformation(amountLine.text, addressLine.text, paymentIdLine.text, appWindow.persistentSettings.testnet)
|
enabled : !appWindow.viewOnly && pageRoot.checkInformation(amountLine.text, addressLine.text, paymentIdLine.text, appWindow.persistentSettings.testnet)
|
||||||
onClicked: {
|
onClicked: {
|
||||||
console.log("Transfer: paymentClicked")
|
console.log("Transfer: paymentClicked")
|
||||||
var priority = priorityModel.get(priorityDropdown.currentIndex).priority
|
var priority = priorityModelV5.get(priorityDropdown.currentIndex).priority
|
||||||
console.log("priority: " + priority)
|
console.log("priority: " + priority)
|
||||||
console.log("amount: " + amountLine.text)
|
console.log("amount: " + amountLine.text)
|
||||||
addressLine.text = addressLine.text.trim()
|
addressLine.text = addressLine.text.trim()
|
||||||
|
@ -478,7 +474,7 @@ Rectangle {
|
||||||
enabled: pageRoot.checkInformation(amountLine.text, addressLine.text, paymentIdLine.text, appWindow.persistentSettings.testnet)
|
enabled: pageRoot.checkInformation(amountLine.text, addressLine.text, paymentIdLine.text, appWindow.persistentSettings.testnet)
|
||||||
onClicked: {
|
onClicked: {
|
||||||
console.log("Transfer: saveTx Clicked")
|
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("priority: " + priority)
|
||||||
console.log("amount: " + amountLine.text)
|
console.log("amount: " + amountLine.text)
|
||||||
addressLine.text = addressLine.text.trim()
|
addressLine.text = addressLine.text.trim()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -72,6 +72,10 @@ Rectangle {
|
||||||
if ((signature.length - 9) % 132 != 0)
|
if ((signature.length - 9) % 132 != 0)
|
||||||
return false;
|
return false;
|
||||||
return check256(signature, signature.length);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +94,8 @@ Rectangle {
|
||||||
property int lineEditFontSize: 12
|
property int lineEditFontSize: 12
|
||||||
|
|
||||||
Text {
|
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
|
wrapMode: Text.Wrap
|
||||||
Layout.fillWidth: true;
|
Layout.fillWidth: true;
|
||||||
}
|
}
|
||||||
|
@ -183,7 +188,7 @@ Rectangle {
|
||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
releasedColor: "#FF6C3C"
|
releasedColor: "#FF6C3C"
|
||||||
pressedColor: "#FF4304"
|
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: {
|
onClicked: {
|
||||||
console.log("getProof: Generate clicked: txid " + getProofTxIdLine.text + ", address " + getProofAddressLine.text + ", message: " + getProofMessageLine.text);
|
console.log("getProof: Generate clicked: txid " + getProofTxIdLine.text + ", address " + getProofAddressLine.text + ", message: " + getProofMessageLine.text);
|
||||||
root.getProofClicked(getProofTxIdLine.text, getProofAddressLine.text, getProofMessageLine.text)
|
root.getProofClicked(getProofTxIdLine.text, getProofAddressLine.text, getProofMessageLine.text)
|
||||||
|
@ -201,7 +206,8 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
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
|
wrapMode: Text.Wrap
|
||||||
Layout.fillWidth: true;
|
Layout.fillWidth: true;
|
||||||
}
|
}
|
||||||
|
@ -322,7 +328,7 @@ Rectangle {
|
||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
releasedColor: "#FF6C3C"
|
releasedColor: "#FF6C3C"
|
||||||
pressedColor: "#FF4304"
|
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: {
|
onClicked: {
|
||||||
console.log("checkProof: Check clicked: txid " + checkProofTxIdLine.text + ", address " + checkProofAddressLine.text + ", message " + checkProofMessageLine.text + ", signature " + checkProofSignatureLine.text);
|
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)
|
root.checkProofClicked(checkProofTxIdLine.text, checkProofAddressLine.text, checkProofMessageLine.text, checkProofSignatureLine.text)
|
||||||
|
|
7
qml.qrc
7
qml.qrc
|
@ -51,6 +51,7 @@
|
||||||
<file>tabs/TweetsModel.qml</file>
|
<file>tabs/TweetsModel.qml</file>
|
||||||
<file>components/Scroll.qml</file>
|
<file>components/Scroll.qml</file>
|
||||||
<file>components/AddressBookTable.qml</file>
|
<file>components/AddressBookTable.qml</file>
|
||||||
|
<file>components/SubaddressTable.qml</file>
|
||||||
<file>images/deleteIcon.png</file>
|
<file>images/deleteIcon.png</file>
|
||||||
<file>images/moneroIcon.png</file>
|
<file>images/moneroIcon.png</file>
|
||||||
<file>components/StandardDropdown.qml</file>
|
<file>components/StandardDropdown.qml</file>
|
||||||
|
@ -118,11 +119,15 @@
|
||||||
<file>lang/flags/spain.png</file>
|
<file>lang/flags/spain.png</file>
|
||||||
<file>lang/flags/sweden.png</file>
|
<file>lang/flags/sweden.png</file>
|
||||||
<file>lang/flags/taiwan.png</file>
|
<file>lang/flags/taiwan.png</file>
|
||||||
|
<file>lang/flags/denmark.png</file>
|
||||||
<file>lang/flags/uk.png</file>
|
<file>lang/flags/uk.png</file>
|
||||||
<file>lang/flags/usa.png</file>
|
<file>lang/flags/usa.png</file>
|
||||||
<file>lang/flags/israel.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/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/WizardManageWalletUI.qml</file>
|
||||||
<file>wizard/WizardRecoveryWallet.qml</file>
|
<file>wizard/WizardRecoveryWallet.qml</file>
|
||||||
<file>wizard/WizardMemoTextInput.qml</file>
|
<file>wizard/WizardMemoTextInput.qml</file>
|
||||||
|
@ -131,6 +136,8 @@
|
||||||
<file>pages/TxKey.qml</file>
|
<file>pages/TxKey.qml</file>
|
||||||
<file>components/IconButton.qml</file>
|
<file>components/IconButton.qml</file>
|
||||||
<file>components/PasswordDialog.qml</file>
|
<file>components/PasswordDialog.qml</file>
|
||||||
|
<file>components/NewPasswordDialog.qml</file>
|
||||||
|
<file>components/InputDialog.qml</file>
|
||||||
<file>components/ProcessingSplash.qml</file>
|
<file>components/ProcessingSplash.qml</file>
|
||||||
<file>components/ProgressBar.qml</file>
|
<file>components/ProgressBar.qml</file>
|
||||||
<file>components/StandardDialog.qml</file>
|
<file>components/StandardDialog.qml</file>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2017, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2017, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2017, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2017, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -50,6 +50,16 @@ quint64 PendingTransaction::txCount() const
|
||||||
return m_pimpl->txCount();
|
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)
|
void PendingTransaction::setFilename(const QString &fileName)
|
||||||
{
|
{
|
||||||
m_fileName = fileName;
|
m_fileName = fileName;
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#define PENDINGTRANSACTION_H
|
#define PENDINGTRANSACTION_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QList>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
#include <wallet/api/wallet2_api.h>
|
#include <wallet/api/wallet2_api.h>
|
||||||
|
|
||||||
|
@ -19,6 +21,7 @@ class PendingTransaction : public QObject
|
||||||
Q_PROPERTY(quint64 fee READ fee)
|
Q_PROPERTY(quint64 fee READ fee)
|
||||||
Q_PROPERTY(QStringList txid READ txid)
|
Q_PROPERTY(QStringList txid READ txid)
|
||||||
Q_PROPERTY(quint64 txCount READ txCount)
|
Q_PROPERTY(quint64 txCount READ txCount)
|
||||||
|
Q_PROPERTY(QList<QVariant> subaddrIndices READ subaddrIndices)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum Status {
|
enum Status {
|
||||||
|
@ -44,6 +47,7 @@ public:
|
||||||
quint64 fee() const;
|
quint64 fee() const;
|
||||||
QStringList txid() const;
|
QStringList txid() const;
|
||||||
quint64 txCount() const;
|
quint64 txCount() const;
|
||||||
|
QList<QVariant> subaddrIndices() const;
|
||||||
Q_INVOKABLE void setFilename(const QString &fileName);
|
Q_INVOKABLE void setFilename(const QString &fileName);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
84
src/libwalletqt/Subaddress.cpp
Normal file
84
src/libwalletqt/Subaddress.cpp
Normal 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();
|
||||||
|
}
|
61
src/libwalletqt/Subaddress.h
Normal file
61
src/libwalletqt/Subaddress.h
Normal 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
|
|
@ -22,7 +22,7 @@ TransactionInfo *TransactionHistory::transaction(int index)
|
||||||
// return nullptr;
|
// 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
|
// XXX this invalidates previously saved history that might be used by model
|
||||||
emit refreshStarted();
|
emit refreshStarted();
|
||||||
|
@ -37,6 +37,10 @@ QList<TransactionInfo *> TransactionHistory::getAll() const
|
||||||
TransactionHistory * parent = const_cast<TransactionHistory*>(this);
|
TransactionHistory * parent = const_cast<TransactionHistory*>(this);
|
||||||
for (const auto i : m_pimpl->getAll()) {
|
for (const auto i : m_pimpl->getAll()) {
|
||||||
TransactionInfo * ti = new TransactionInfo(i, parent);
|
TransactionInfo * ti = new TransactionInfo(i, parent);
|
||||||
|
if (ti->subaddrAccount() != accountIndex) {
|
||||||
|
delete ti;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
m_tinfo.append(ti);
|
m_tinfo.append(ti);
|
||||||
// looking for transactions timestamp scope
|
// looking for transactions timestamp scope
|
||||||
if (ti->timestamp() >= lastDateTime) {
|
if (ti->timestamp() >= lastDateTime) {
|
||||||
|
@ -69,12 +73,12 @@ QList<TransactionInfo *> TransactionHistory::getAll() const
|
||||||
return m_tinfo;
|
return m_tinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransactionHistory::refresh()
|
void TransactionHistory::refresh(quint32 accountIndex)
|
||||||
{
|
{
|
||||||
// rebuilding transaction list in wallet_api;
|
// rebuilding transaction list in wallet_api;
|
||||||
m_pimpl->refresh();
|
m_pimpl->refresh();
|
||||||
// copying list here and keep track on every item to avoid memleaks
|
// copying list here and keep track on every item to avoid memleaks
|
||||||
getAll();
|
getAll(accountIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
quint64 TransactionHistory::count() const
|
quint64 TransactionHistory::count() const
|
||||||
|
|
|
@ -23,8 +23,8 @@ class TransactionHistory : public QObject
|
||||||
public:
|
public:
|
||||||
Q_INVOKABLE TransactionInfo *transaction(int index);
|
Q_INVOKABLE TransactionInfo *transaction(int index);
|
||||||
// Q_INVOKABLE TransactionInfo * transaction(const QString &id);
|
// Q_INVOKABLE TransactionInfo * transaction(const QString &id);
|
||||||
Q_INVOKABLE QList<TransactionInfo*> getAll() const;
|
Q_INVOKABLE QList<TransactionInfo*> getAll(quint32 accountIndex) const;
|
||||||
Q_INVOKABLE void refresh();
|
Q_INVOKABLE void refresh(quint32 accountIndex);
|
||||||
quint64 count() const;
|
quint64 count() const;
|
||||||
QDateTime firstDateTime() const;
|
QDateTime firstDateTime() const;
|
||||||
QDateTime lastDateTime() const;
|
QDateTime lastDateTime() const;
|
||||||
|
|
|
@ -48,6 +48,24 @@ quint64 TransactionInfo::blockHeight() const
|
||||||
return m_pimpl->blockHeight();
|
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
|
quint64 TransactionInfo::confirmations() const
|
||||||
{
|
{
|
||||||
return m_pimpl->confirmations();
|
return m_pimpl->confirmations();
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <wallet/api/wallet2_api.h>
|
#include <wallet/api/wallet2_api.h>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include <QSet>
|
||||||
|
|
||||||
class Transfer;
|
class Transfer;
|
||||||
|
|
||||||
|
@ -18,6 +19,9 @@ class TransactionInfo : public QObject
|
||||||
Q_PROPERTY(QString displayAmount READ displayAmount)
|
Q_PROPERTY(QString displayAmount READ displayAmount)
|
||||||
Q_PROPERTY(QString fee READ fee)
|
Q_PROPERTY(QString fee READ fee)
|
||||||
Q_PROPERTY(quint64 blockHeight READ blockHeight)
|
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 confirmations READ confirmations)
|
||||||
Q_PROPERTY(quint64 unlockTime READ unlockTime)
|
Q_PROPERTY(quint64 unlockTime READ unlockTime)
|
||||||
Q_PROPERTY(QString hash READ hash)
|
Q_PROPERTY(QString hash READ hash)
|
||||||
|
@ -44,6 +48,9 @@ public:
|
||||||
QString displayAmount() const;
|
QString displayAmount() const;
|
||||||
QString fee() const;
|
QString fee() const;
|
||||||
quint64 blockHeight() const;
|
quint64 blockHeight() const;
|
||||||
|
QSet<quint32> subaddrIndex() const;
|
||||||
|
quint32 subaddrAccount() const;
|
||||||
|
QString label() const;
|
||||||
quint64 confirmations() const;
|
quint64 confirmations() const;
|
||||||
quint64 unlockTime() const;
|
quint64 unlockTime() const;
|
||||||
//! transaction_id
|
//! transaction_id
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
#include "UnsignedTransaction.h"
|
#include "UnsignedTransaction.h"
|
||||||
#include "TransactionHistory.h"
|
#include "TransactionHistory.h"
|
||||||
#include "AddressBook.h"
|
#include "AddressBook.h"
|
||||||
|
#include "Subaddress.h"
|
||||||
#include "model/TransactionHistoryModel.h"
|
#include "model/TransactionHistoryModel.h"
|
||||||
#include "model/TransactionHistorySortFilterModel.h"
|
#include "model/TransactionHistorySortFilterModel.h"
|
||||||
#include "model/AddressBookModel.h"
|
#include "model/AddressBookModel.h"
|
||||||
|
#include "model/SubaddressModel.h"
|
||||||
#include "wallet/api/wallet2_api.h"
|
#include "wallet/api/wallet2_api.h"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
@ -155,9 +157,9 @@ bool Wallet::setPassword(const QString &password)
|
||||||
return m_walletImpl->setPassword(password.toStdString());
|
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
|
QString Wallet::path() const
|
||||||
|
@ -241,14 +243,63 @@ bool Wallet::viewOnly() const
|
||||||
return m_walletImpl->watchOnly();
|
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
|
quint64 Wallet::blockChainHeight() const
|
||||||
|
@ -288,7 +339,8 @@ quint64 Wallet::daemonBlockChainTargetHeight() const
|
||||||
bool Wallet::refresh()
|
bool Wallet::refresh()
|
||||||
{
|
{
|
||||||
bool result = m_walletImpl->refresh();
|
bool result = m_walletImpl->refresh();
|
||||||
m_history->refresh();
|
m_history->refresh(currentSubaddressAccount());
|
||||||
|
m_subaddress->refresh(currentSubaddressAccount());
|
||||||
if (result)
|
if (result)
|
||||||
emit updated();
|
emit updated();
|
||||||
return result;
|
return result;
|
||||||
|
@ -324,9 +376,10 @@ PendingTransaction *Wallet::createTransaction(const QString &dst_addr, const QSt
|
||||||
quint64 amount, quint32 mixin_count,
|
quint64 amount, quint32 mixin_count,
|
||||||
PendingTransaction::Priority priority)
|
PendingTransaction::Priority priority)
|
||||||
{
|
{
|
||||||
|
std::set<uint32_t> subaddr_indices;
|
||||||
Monero::PendingTransaction * ptImpl = m_walletImpl->createTransaction(
|
Monero::PendingTransaction * ptImpl = m_walletImpl->createTransaction(
|
||||||
dst_addr.toStdString(), payment_id.toStdString(), amount, mixin_count,
|
dst_addr.toStdString(), payment_id.toStdString(), amount, mixin_count,
|
||||||
static_cast<Monero::PendingTransaction::Priority>(priority));
|
static_cast<Monero::PendingTransaction::Priority>(priority), currentSubaddressAccount(), subaddr_indices);
|
||||||
PendingTransaction * result = new PendingTransaction(ptImpl,0);
|
PendingTransaction * result = new PendingTransaction(ptImpl,0);
|
||||||
return result;
|
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,
|
PendingTransaction *Wallet::createTransactionAll(const QString &dst_addr, const QString &payment_id,
|
||||||
quint32 mixin_count, PendingTransaction::Priority priority)
|
quint32 mixin_count, PendingTransaction::Priority priority)
|
||||||
{
|
{
|
||||||
|
std::set<uint32_t> subaddr_indices;
|
||||||
Monero::PendingTransaction * ptImpl = m_walletImpl->createTransaction(
|
Monero::PendingTransaction * ptImpl = m_walletImpl->createTransaction(
|
||||||
dst_addr.toStdString(), payment_id.toStdString(), Monero::optional<uint64_t>(), mixin_count,
|
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);
|
PendingTransaction * result = new PendingTransaction(ptImpl, this);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -458,6 +512,18 @@ AddressBookModel *Wallet::addressBookModel() const
|
||||||
return m_addressBookModel;
|
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
|
QString Wallet::generatePaymentId() const
|
||||||
{
|
{
|
||||||
|
@ -523,6 +589,22 @@ QString Wallet::checkTxProof(const QString &txid, const QString &address, const
|
||||||
return QString::fromStdString(result);
|
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
|
QString Wallet::signMessage(const QString &message, bool filename) const
|
||||||
{
|
{
|
||||||
if (filename) {
|
if (filename) {
|
||||||
|
@ -652,14 +734,18 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent)
|
||||||
, m_historyModel(nullptr)
|
, m_historyModel(nullptr)
|
||||||
, m_addressBook(nullptr)
|
, m_addressBook(nullptr)
|
||||||
, m_addressBookModel(nullptr)
|
, m_addressBookModel(nullptr)
|
||||||
|
, m_subaddress(nullptr)
|
||||||
|
, m_subaddressModel(nullptr)
|
||||||
, m_daemonBlockChainHeight(0)
|
, m_daemonBlockChainHeight(0)
|
||||||
, m_daemonBlockChainHeightTtl(DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS)
|
, m_daemonBlockChainHeightTtl(DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS)
|
||||||
, m_daemonBlockChainTargetHeight(0)
|
, m_daemonBlockChainTargetHeight(0)
|
||||||
, m_daemonBlockChainTargetHeightTtl(DAEMON_BLOCKCHAIN_TARGET_HEIGHT_CACHE_TTL_SECONDS)
|
, m_daemonBlockChainTargetHeightTtl(DAEMON_BLOCKCHAIN_TARGET_HEIGHT_CACHE_TTL_SECONDS)
|
||||||
, m_connectionStatusTtl(WALLET_CONNECTION_STATUS_CACHE_TTL_SECONDS)
|
, m_connectionStatusTtl(WALLET_CONNECTION_STATUS_CACHE_TTL_SECONDS)
|
||||||
|
, m_currentSubaddressAccount(0)
|
||||||
{
|
{
|
||||||
m_history = new TransactionHistory(m_walletImpl->history(), this);
|
m_history = new TransactionHistory(m_walletImpl->history(), this);
|
||||||
m_addressBook = new AddressBook(m_walletImpl->addressBook(), this);
|
m_addressBook = new AddressBook(m_walletImpl->addressBook(), this);
|
||||||
|
m_subaddress = new Subaddress(m_walletImpl->subaddress(), this);
|
||||||
m_walletImpl->setListener(new WalletListenerImpl(this));
|
m_walletImpl->setListener(new WalletListenerImpl(this));
|
||||||
m_connectionStatus = Wallet::ConnectionStatus_Disconnected;
|
m_connectionStatus = Wallet::ConnectionStatus_Disconnected;
|
||||||
// start cache timers
|
// start cache timers
|
||||||
|
@ -680,6 +766,10 @@ Wallet::~Wallet()
|
||||||
|
|
||||||
delete m_history;
|
delete m_history;
|
||||||
m_history = NULL;
|
m_history = NULL;
|
||||||
|
delete m_addressBook;
|
||||||
|
m_addressBook = NULL;
|
||||||
|
delete m_subaddress;
|
||||||
|
m_subaddress = NULL;
|
||||||
//Monero::WalletManagerFactory::getWalletManager()->closeWallet(m_walletImpl);
|
//Monero::WalletManagerFactory::getWalletManager()->closeWallet(m_walletImpl);
|
||||||
if(status() == Status_Critical)
|
if(status() == Status_Critical)
|
||||||
qDebug("Not storing wallet cache");
|
qDebug("Not storing wallet cache");
|
||||||
|
|
|
@ -20,6 +20,8 @@ class TransactionHistoryModel;
|
||||||
class TransactionHistorySortFilterModel;
|
class TransactionHistorySortFilterModel;
|
||||||
class AddressBook;
|
class AddressBook;
|
||||||
class AddressBookModel;
|
class AddressBookModel;
|
||||||
|
class Subaddress;
|
||||||
|
class SubaddressModel;
|
||||||
|
|
||||||
class Wallet : public QObject
|
class Wallet : public QObject
|
||||||
{
|
{
|
||||||
|
@ -29,17 +31,17 @@ class Wallet : public QObject
|
||||||
Q_PROPERTY(Status status READ status)
|
Q_PROPERTY(Status status READ status)
|
||||||
Q_PROPERTY(bool testnet READ testnet)
|
Q_PROPERTY(bool testnet READ testnet)
|
||||||
// Q_PROPERTY(ConnectionStatus connected READ connected)
|
// Q_PROPERTY(ConnectionStatus connected READ connected)
|
||||||
|
Q_PROPERTY(quint32 currentSubaddressAccount READ currentSubaddressAccount)
|
||||||
Q_PROPERTY(bool synchronized READ synchronized)
|
Q_PROPERTY(bool synchronized READ synchronized)
|
||||||
Q_PROPERTY(QString errorString READ errorString)
|
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(TransactionHistory * history READ history)
|
||||||
Q_PROPERTY(QString paymentId READ paymentId WRITE setPaymentId)
|
Q_PROPERTY(QString paymentId READ paymentId WRITE setPaymentId)
|
||||||
Q_PROPERTY(TransactionHistorySortFilterModel * historyModel READ historyModel NOTIFY historyModelChanged)
|
Q_PROPERTY(TransactionHistorySortFilterModel * historyModel READ historyModel NOTIFY historyModelChanged)
|
||||||
Q_PROPERTY(QString path READ path)
|
Q_PROPERTY(QString path READ path)
|
||||||
Q_PROPERTY(AddressBookModel * addressBookModel READ addressBookModel)
|
Q_PROPERTY(AddressBookModel * addressBookModel READ addressBookModel)
|
||||||
Q_PROPERTY(AddressBook * addressBook READ addressBook)
|
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(bool viewOnly READ viewOnly)
|
||||||
Q_PROPERTY(QString secretViewKey READ getSecretViewKey)
|
Q_PROPERTY(QString secretViewKey READ getSecretViewKey)
|
||||||
Q_PROPERTY(QString publicViewKey READ getPublicViewKey)
|
Q_PROPERTY(QString publicViewKey READ getPublicViewKey)
|
||||||
|
@ -98,7 +100,7 @@ public:
|
||||||
Q_INVOKABLE bool setPassword(const QString &password);
|
Q_INVOKABLE bool setPassword(const QString &password);
|
||||||
|
|
||||||
//! returns wallet's public address
|
//! returns wallet's public address
|
||||||
QString address() const;
|
Q_INVOKABLE QString address(quint32 accountIndex, quint32 addressIndex) const;
|
||||||
|
|
||||||
//! returns wallet file's path
|
//! returns wallet file's path
|
||||||
QString path() const;
|
QString path() const;
|
||||||
|
@ -126,10 +128,22 @@ public:
|
||||||
Q_INVOKABLE void setTrustedDaemon(bool arg);
|
Q_INVOKABLE void setTrustedDaemon(bool arg);
|
||||||
|
|
||||||
//! returns balance
|
//! returns balance
|
||||||
Q_INVOKABLE quint64 balance() const;
|
Q_INVOKABLE quint64 balance(quint32 accountIndex) const;
|
||||||
|
Q_INVOKABLE quint64 balanceAll() const;
|
||||||
|
|
||||||
//! returns unlocked balance
|
//! 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
|
//! returns if view only wallet
|
||||||
Q_INVOKABLE bool viewOnly() const;
|
Q_INVOKABLE bool viewOnly() const;
|
||||||
|
@ -209,6 +223,12 @@ public:
|
||||||
//! returns adress book model
|
//! returns adress book model
|
||||||
AddressBookModel *addressBookModel() const;
|
AddressBookModel *addressBookModel() const;
|
||||||
|
|
||||||
|
//! returns subaddress
|
||||||
|
Subaddress *subaddress();
|
||||||
|
|
||||||
|
//! returns subadress model
|
||||||
|
SubaddressModel *subaddressModel();
|
||||||
|
|
||||||
//! generate payment id
|
//! generate payment id
|
||||||
Q_INVOKABLE QString generatePaymentId() const;
|
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 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 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 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
|
// Rescan spent outputs
|
||||||
Q_INVOKABLE bool rescanSpent();
|
Q_INVOKABLE bool rescanSpent();
|
||||||
|
|
||||||
|
@ -300,8 +322,11 @@ private:
|
||||||
int m_connectionStatusTtl;
|
int m_connectionStatusTtl;
|
||||||
mutable QTime m_connectionStatusTime;
|
mutable QTime m_connectionStatusTime;
|
||||||
mutable bool m_initialized;
|
mutable bool m_initialized;
|
||||||
|
uint32_t m_currentSubaddressAccount;
|
||||||
AddressBook * m_addressBook;
|
AddressBook * m_addressBook;
|
||||||
mutable AddressBookModel * m_addressBookModel;
|
mutable AddressBookModel * m_addressBookModel;
|
||||||
|
Subaddress * m_subaddress;
|
||||||
|
mutable SubaddressModel * m_subaddressModel;
|
||||||
QMutex m_connectionStatusMutex;
|
QMutex m_connectionStatusMutex;
|
||||||
bool m_connectionStatusRunning;
|
bool m_connectionStatusRunning;
|
||||||
QString m_daemonUsername;
|
QString m_daemonUsername;
|
||||||
|
|
|
@ -49,7 +49,7 @@ Wallet *WalletManager::openWallet(const QString &path, const QString &password,
|
||||||
__PRETTY_FUNCTION__, qPrintable(path), testnet);
|
__PRETTY_FUNCTION__, qPrintable(path), testnet);
|
||||||
|
|
||||||
Monero::Wallet * w = m_pimpl->openWallet(path.toStdString(), password.toStdString(), 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);
|
m_currentWallet = new Wallet(w);
|
||||||
|
|
||||||
// move wallet to the GUI thread. Otherwise it wont be emitting signals
|
// move wallet to the GUI thread. Otherwise it wont be emitting signals
|
||||||
|
@ -110,7 +110,7 @@ QString WalletManager::closeWallet()
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
QString result;
|
QString result;
|
||||||
if (m_currentWallet) {
|
if (m_currentWallet) {
|
||||||
result = m_currentWallet->address();
|
result = m_currentWallet->address(0, 0);
|
||||||
delete m_currentWallet;
|
delete m_currentWallet;
|
||||||
} else {
|
} else {
|
||||||
qCritical() << "Trying to close non existing wallet " << m_currentWallet;
|
qCritical() << "Trying to close non existing wallet " << m_currentWallet;
|
||||||
|
@ -304,6 +304,7 @@ QUrl WalletManager::localPathToUrl(const QString &path) const
|
||||||
return QUrl::fromLocalFile(path);
|
return QUrl::fromLocalFile(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef DISABLE_PASS_STRENGTH_METER
|
||||||
double WalletManager::getPasswordStrength(const QString &password) const
|
double WalletManager::getPasswordStrength(const QString &password) const
|
||||||
{
|
{
|
||||||
static const char *local_dict[] = {
|
static const char *local_dict[] = {
|
||||||
|
@ -318,6 +319,7 @@ double WalletManager::getPasswordStrength(const QString &password) const
|
||||||
ZxcvbnUnInit();
|
ZxcvbnUnInit();
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool WalletManager::saveQrCode(const QString &code, const QString &path) const
|
bool WalletManager::saveQrCode(const QString &code, const QString &path) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -128,7 +128,9 @@ public:
|
||||||
Q_INVOKABLE qint64 addi(qint64 x, qint64 y) const { return x + y; }
|
Q_INVOKABLE qint64 addi(qint64 x, qint64 y) const { return x + y; }
|
||||||
Q_INVOKABLE qint64 subi(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;
|
Q_INVOKABLE double getPasswordStrength(const QString &password) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
Q_INVOKABLE QString resolveOpenAlias(const QString &address) const;
|
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);
|
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);
|
||||||
|
|
89
src/model/SubaddressModel.cpp
Normal file
89
src/model/SubaddressModel.cpp
Normal 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;
|
||||||
|
}
|
62
src/model/SubaddressModel.h
Normal file
62
src/model/SubaddressModel.h
Normal 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
|
|
@ -83,6 +83,25 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case TransactionConfirmationsRole:
|
||||||
result = tInfo->confirmations();
|
result = tInfo->confirmations();
|
||||||
break;
|
break;
|
||||||
|
@ -133,6 +152,9 @@ QHash<int, QByteArray> TransactionHistoryModel::roleNames() const
|
||||||
roleNames.insert(TransactionAtomicAmountRole, "atomicAmount");
|
roleNames.insert(TransactionAtomicAmountRole, "atomicAmount");
|
||||||
roleNames.insert(TransactionFeeRole, "fee");
|
roleNames.insert(TransactionFeeRole, "fee");
|
||||||
roleNames.insert(TransactionBlockHeightRole, "blockHeight");
|
roleNames.insert(TransactionBlockHeightRole, "blockHeight");
|
||||||
|
roleNames.insert(TransactionSubaddrIndexRole, "subaddrIndex");
|
||||||
|
roleNames.insert(TransactionSubaddrAccountRole, "subaddrAccount");
|
||||||
|
roleNames.insert(TransactionLabelRole, "label");
|
||||||
roleNames.insert(TransactionConfirmationsRole, "confirmations");
|
roleNames.insert(TransactionConfirmationsRole, "confirmations");
|
||||||
roleNames.insert(TransactionConfirmationsRequiredRole, "confirmationsRequired");
|
roleNames.insert(TransactionConfirmationsRequiredRole, "confirmationsRequired");
|
||||||
roleNames.insert(TransactionHashRole, "hash");
|
roleNames.insert(TransactionHashRole, "hash");
|
||||||
|
|
|
@ -25,6 +25,9 @@ public:
|
||||||
TransactionDisplayAmountRole,
|
TransactionDisplayAmountRole,
|
||||||
TransactionFeeRole,
|
TransactionFeeRole,
|
||||||
TransactionBlockHeightRole,
|
TransactionBlockHeightRole,
|
||||||
|
TransactionSubaddrIndexRole,
|
||||||
|
TransactionSubaddrAccountRole,
|
||||||
|
TransactionLabelRole,
|
||||||
TransactionConfirmationsRole,
|
TransactionConfirmationsRole,
|
||||||
TransactionConfirmationsRequiredRole,
|
TransactionConfirmationsRequiredRole,
|
||||||
TransactionHashRole,
|
TransactionHashRole,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2015, The Monero Project
|
// Copyright (c) 2014-2018, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
2535
translations/monero-core_cs.ts
Normal file
2535
translations/monero-core_cs.ts
Normal file
File diff suppressed because it is too large
Load diff
2508
translations/monero-core_da.ts
Normal file
2508
translations/monero-core_da.ts
Normal file
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
Loading…
Reference in a new issue