Compare commits

..

52 Commits

Author SHA1 Message Date
Alexander Blair
3ca5f10fa8 Merge pull request #3294
f7b81797 build: prepare v0.17.1.9 (selsta)
2021-01-07 18:00:05 -08:00
selsta
f7b817972f build: prepare v0.17.1.9 2021-01-08 02:56:28 +01:00
Alexander Blair
9399839d96 Merge pull request #3287
72ab846b installer: remove high dpi shortcut (selsta)
2021-01-03 18:46:20 -08:00
Alexander Blair
51a4d1f629 Merge pull request #3283
5662841d docker: Windows - use Qt 5.15.2 (xiphon)
2021-01-03 18:45:48 -08:00
Alexander Blair
bbe3716542 Merge pull request #3277
8d4cda03 QR-Code-scanner: integrate QUIRC library, implement QrDecoder, drop ZBar (xiphon)
2021-01-03 18:45:26 -08:00
selsta
72ab846be5 installer: remove high dpi shortcut
Qt 5.15 supports high DPI natively
2021-01-01 05:13:36 +01:00
Alexander Blair
8e6a2cde0f Merge pull request #3285
c34d4ee9 build: prepare v0.17.1.8 (selsta)
2020-12-30 01:53:31 -08:00
selsta
c34d4ee97c build: prepare v0.17.1.8 2020-12-30 10:37:36 +01:00
Alexander Blair
0194cf8f22 Merge pull request #3280
ba4d6993 LineEdit: fix padding, fix inline buttons layout, multiple btns support (xiphon)
2020-12-28 11:41:47 -08:00
Alexander Blair
ad06fcc79e Merge pull request #3271
78f5360a Transfer: support pasting amount with whitespaces (xiphon)
2020-12-28 11:41:38 -08:00
Alexander Blair
7d4b82c691 Merge pull request #3270
a1fdffca WizardRestoreWallet1: fix mnemonic seed placeholder (xiphon)
2020-12-28 11:41:15 -08:00
Alexander Blair
69f989d617 Merge pull request #3281
3f0bbfb6 Transfer: updateFromQrCode - fix extra space (empty recipient name) (xiphon)
2020-12-26 13:47:31 -08:00
Alexander Blair
0f3df860e3 Merge pull request #3275
772b828b cmake: MacOS - detect ICU link directory (required by Boost.Locale) (xiphon)
2020-12-26 13:45:24 -08:00
xiphon
5662841d22 docker: Windows - use Qt 5.15.2 2020-12-26 08:37:45 +00:00
xiphon
3f0bbfb6aa Transfer: updateFromQrCode - fix extra space (empty recipient name) 2020-12-24 10:07:08 +00:00
xiphon
ba4d6993b7 LineEdit: fix padding, fix inline buttons layout, multiple btns support 2020-12-24 08:20:38 +00:00
xiphon
8d4cda030e QR-Code-scanner: integrate QUIRC library, implement QrDecoder, drop ZBar 2020-12-23 15:08:42 +00:00
xiphon
772b828b67 cmake: MacOS - detect ICU link directory (required by Boost.Locale) 2020-12-20 20:00:23 +00:00
xiphon
78f5360af2 Transfer: support pasting amount with whitespaces 2020-12-14 11:59:45 +00:00
xiphon
a1fdffcabe WizardRestoreWallet1: fix mnemonic seed placeholder 2020-12-13 11:31:14 +00:00
luigi1111
fed00a5662 Merge pull request #3269
14a4777 build: prepare v0.17.1.7 (selsta)
2020-12-12 22:16:13 -06:00
luigi1111
79f2843b09 Merge pull request #3268
cebb789 Wallet: fix initialization flag handling (xiphon)
2020-12-12 22:15:10 -06:00
selsta
14a477748e build: prepare v0.17.1.7 2020-12-13 05:11:20 +01:00
xiphon
cebb78979c Wallet: fix initialization flag handling 2020-12-12 11:22:52 +00:00
Alexander Blair
df771470c2 Merge pull request #3267
90e9968d main: get back "Sending transaction ..." splash (xiphon)
2020-12-10 18:02:11 -08:00
Alexander Blair
e359c60f00 Merge pull request #3266
841d0e01 Utils: removeTrailingZeros - handle .0* decimal part (i.e. 1.00000) (xiphon)
2020-12-10 18:01:38 -08:00
Alexander Blair
53335a8487 Merge pull request #3264
2feee9e9 workflows: shorten name (selsta)
2020-12-10 18:01:19 -08:00
Alexander Blair
3f64312283 Merge pull request #3262
486ba055 main: disable QML cache (xiphon)
2020-12-10 17:59:09 -08:00
Alexander Blair
897946af13 Merge pull request #3260
ae8394e5 main: Linux - fix missing askDesktopShortcut setting (xiphon)
2020-12-10 17:58:42 -08:00
Alexander Blair
e90626e05a Merge pull request #3259
fa79e609 workflows: bump docker cache action (selsta)
2020-12-10 17:58:06 -08:00
xiphon
90e9968dcb main: get back "Sending transaction ..." splash 2020-12-10 23:59:12 +00:00
xiphon
841d0e01dc Utils: removeTrailingZeros - handle .0* decimal part (i.e. 1.00000) 2020-12-10 23:00:39 +00:00
selsta
2feee9e956 workflows: shorten name 2020-12-10 04:01:43 +01:00
xiphon
486ba05526 main: disable QML cache 2020-12-09 14:29:02 +00:00
xiphon
ae8394e5f8 main: Linux - fix missing askDesktopShortcut setting 2020-12-08 01:02:00 +00:00
selsta
fa79e609e1 workflows: bump docker cache action 2020-12-07 19:22:37 +01:00
luigi1111
cc352e4913 Merge pull request #3258
903539b build: prepare v0.17.1.6 (selsta)
2020-12-07 10:37:31 -06:00
selsta
903539bd30 build: prepare v0.17.1.6 2020-12-07 17:34:40 +01:00
Alexander Blair
af0b3142a0 Merge pull request #3255
606dbed4 README: update Linux Docker build instructions (xiphon)
2020-12-03 12:24:50 -08:00
Alexander Blair
6fe41e6f55 Merge pull request #3254
0d5d2dbf Transfer: fix focus, cycle focus between Address, Amount and Send (xiphon)
2020-12-03 12:24:22 -08:00
Alexander Blair
2a6ad67f77 Merge pull request #3253
110b09ef TxConfirmationDialog: fix keys handling (xiphon)
2020-12-03 12:23:58 -08:00
Alexander Blair
5652284572 Merge pull request #3252
0fdf81bc SuccessfulTxDialog: fix keys handling (xiphon)
2020-12-03 12:23:24 -08:00
Alexander Blair
2eeeadfd10 Merge pull request #3251
ea1fee2f main: Linux - ask to create desktop entry on the first start (xiphon)
2020-12-03 12:23:02 -08:00
xiphon
0d5d2dbf5e Transfer: fix focus, cycle focus between Address, Amount and Send 2020-12-03 19:40:15 +00:00
xiphon
606dbed4a0 README: update Linux Docker build instructions 2020-12-03 00:55:29 +00:00
Alexander Blair
301b20d19c Merge pull request #3249
ef54a32d workflows: print hash for reproducible builds (selsta)
2020-12-01 14:25:22 -08:00
Alexander Blair
f6196d48ab Merge pull request #3169
cd3a0f85 Restore: display red border if invalid seed (rating89us)
2020-12-01 14:25:01 -08:00
xiphon
110b09efba TxConfirmationDialog: fix keys handling 2020-12-01 16:25:35 +00:00
xiphon
0fdf81bc92 SuccessfulTxDialog: fix keys handling 2020-12-01 16:19:56 +00:00
xiphon
ea1fee2f5f main: Linux - ask to create desktop entry on the first start 2020-11-30 15:36:19 +00:00
selsta
ef54a32de0 workflows: print hash for reproducible builds 2020-11-26 10:34:19 +01:00
rating89us
cd3a0f85a6 Restore: display red border if invalid seed 2020-10-18 17:06:34 +02:00
39 changed files with 369 additions and 391 deletions

View File

@@ -1,4 +1,4 @@
name: continuous-integration/gh-actions/gui
name: ci/gh-actions/gui
on: [push, pull_request]
@@ -93,7 +93,7 @@ jobs:
- uses: actions/checkout@v1
with:
submodules: recursive
- uses: satackey/action-docker-layer-caching@v0.0.8
- uses: satackey/action-docker-layer-caching@v0.0.10
continue-on-error: true
with:
key: docker-linux-static-{hash}
@@ -103,6 +103,8 @@ jobs:
run: docker build --tag monero:build-env-linux --build-arg THREADS=3 --file Dockerfile.linux .
- name: build
run: docker run --rm -v /home/runner/work/monero-gui/monero-gui:/monero-gui -w /monero-gui monero:build-env-linux sh -c 'make release-static -j3'
- name: sha256sum
run: shasum -a256 /home/runner/work/monero-gui/monero-gui/build/release/bin/monero-wallet-gui
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
@@ -116,7 +118,7 @@ jobs:
- uses: actions/checkout@v1
with:
submodules: recursive
- uses: satackey/action-docker-layer-caching@v0.0.8
- uses: satackey/action-docker-layer-caching@v0.0.10
continue-on-error: true
with:
key: docker-windows-static-{hash}

3
.gitmodules vendored
View File

@@ -2,3 +2,6 @@
path = monero
url = https://github.com/monero-project/monero
ignore = all
[submodule "external/quirc"]
path = external/quirc
url = https://github.com/dlbeer/quirc/

View File

@@ -5,7 +5,7 @@ message(STATUS "Initiating compile using CMake ${CMAKE_VERSION}")
set(VERSION_MAJOR "17")
set(VERSION_MINOR "1")
set(VERSION_REVISION "5")
set(VERSION_REVISION "9")
set(VERSION "0.${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}")
option(STATIC "Link libraries statically, requires static Qt")
@@ -131,12 +131,8 @@ message(STATUS "OpenSSL: Version ${OPENSSL_VERSION}")
message(STATUS "OpenSSL: include dir at ${OPENSSL_INCLUDE_DIR}")
message(STATUS "OpenSSL: libraries at ${OPENSSL_LIBRARIES} ${OPENSSL_SSL_LIBRARIES}")
# Zbar (for QR scanner)
if(WITH_SCANNER)
add_definitions(-DWITH_SCANNER)
find_package(ZBar0 REQUIRED)
message(STATUS "libzbar: include dir at ${ZBAR_INCLUDE_DIR}")
message(STATUS "libzbar: libraries at ${ZBAR_LIBRARIES}")
endif()
# Sodium
@@ -563,6 +559,6 @@ if (HIDAPI_FOUND OR LibUSB_COMPILE_TEST_PASSED)
endif()
endif()
add_subdirectory(external)
add_subdirectory(translations)
add_subdirectory(src)

View File

@@ -151,25 +151,6 @@ RUN set -ex \
&& make -j${THREADS} install \
&& rm -rf $(pwd)
RUN git clone https://github.com/ZBar/ZBar.git --depth 1 \
&& cd ZBar \
&& git reset --hard 854a5d97059e395807091ac4d80c53f7968abb8f \
&& sed -i 's/SHARED/STATIC/' android/jni/Android.mk \
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CPP_FEATURES := exceptions rtti features\n\0/' android/jni/Android.mk \
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS := -Wno-multichar\n\0/' android/jni/Android.mk \
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -D_ANDROID\n\0/' android/jni/Android.mk \
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -DLIBDIR="\\".\\""\n\0/' android/jni/Android.mk \
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -DBUILDING_LIBICONV\n\0/' android/jni/Android.mk \
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -DBUILDING_LIBCHARSET\n\0/' android/jni/Android.mk \
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -DIN_LIBRARY\n\0/' android/jni/Android.mk \
&& sed -i -E 's/(.*BUILD_STATIC_LIBRARY.*)/LOCAL_CFLAGS += -fno-stack-protector\n\0/' android/jni/Android.mk \
&& echo "APP_ABI := arm64-v8a \nAPP_STL := c++_shared \nTARGET_PLATFORM := ${ANDROID_API} \nTARGET_ARCH_ABI := arm64-v8a \nAPP_CFLAGS += -target aarch64-none-linux-android -fexceptions -fstack-protector-strong -fno-limit-debug-info -mfloat-abi=softfp -fno-builtin-memmove -fno-omit-frame-pointer -fno-stack-protector\n" \
>> android/jni/Application.mk \
&& cd android \
&& CC=${ANDROID_CLANG} CXX=${ANDROID_CLANGPP} ${ANDROID_NDK_ROOT}/ndk-build ICONV_SRC=${WORKDIR}/libiconv-${ICONV_VERSION} -B V=1 NDK_APPLICATION_MK=jni/Application.mk \
&& cp obj/local/arm64-v8a/lib* ${PREFIX}/lib \
&& cp -r ../include/* ${PREFIX}/include
RUN git clone -b libgpg-error-1.38 --depth 1 git://git.gnupg.org/libgpg-error.git \
&& cd libgpg-error \
&& git reset --hard 71d278824c5fe61865f7927a2ed1aa3115f9e439 \

View File

@@ -1,6 +1,8 @@
FROM ubuntu:20.04
ARG THREADS=1
ARG QT_VERSION=5.15.2
ENV SOURCE_DATE_EPOCH=1397818193
RUN apt update && \
DEBIAN_FRONTEND=noninteractive apt install -y build-essential cmake g++-mingw-w64 gettext git libtool pkg-config \
@@ -19,26 +21,35 @@ RUN git clone -b v0.17.0.0 --depth 1 https://github.com/monero-project/monero &&
RUN make -j$THREADS -C /depends HOST=x86_64-w64-mingw32 NO_QT=1
RUN curl -LO https://download.qt.io/archive/qt/5.9/5.9.9/single/qt-everywhere-opensource-src-5.9.9.tar.xz && \
echo "5ce285209290a157d7f42ec8eb22bf3f1d76f2e03a95fc0b99b553391be01642 qt-everywhere-opensource-src-5.9.9.tar.xz" > hashsum.txt && \
sha256sum -c hashsum.txt && \
tar -xf qt-everywhere-opensource-src-5.9.9.tar.xz && \
rm qt-everywhere-opensource-src-5.9.9.tar.xz && \
cd qt-everywhere-opensource-src-5.9.9 && \
RUN git clone git://code.qt.io/qt/qt5.git -b ${QT_VERSION} --depth 1 && \
cd qt5 && \
git clone git://code.qt.io/qt/qtbase.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtdeclarative.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtgraphicaleffects.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtimageformats.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtmultimedia.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtquickcontrols.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtquickcontrols2.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtsvg.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qttools.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qttranslations.git -b ${QT_VERSION} --depth 1 && \
git clone git://code.qt.io/qt/qtxmlpatterns.git -b ${QT_VERSION} --depth 1 && \
./configure --prefix=/depends/x86_64-w64-mingw32 -xplatform win32-g++ \
-device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- \
-I $(pwd)/qtbase/src/3rdparty/angle/include \
-opensource -confirm-license -release -static -static-runtime -opengl dynamic -no-angle \
-no-avx -no-openssl -no-sql-sqlite \
-no-feature-qml-worker-script -no-openssl -no-sql-sqlite \
-qt-freetype -qt-harfbuzz -qt-libjpeg -qt-libpng -qt-pcre -qt-zlib \
-skip gamepad -skip location -skip qt3d -skip qtactiveqt -skip qtandroidextras -skip qtcanvas3d -skip qtcharts \
-skip qtconnectivity -skip qtdatavis3d -skip qtdoc -skip qtgamepad -skip qtlocation -skip qtmacextras \
-skip qtmultimedia -skip qtnetworkauth -skip qtpurchasing -skip qtscript -skip qtscxml -skip qtsensors \
-skip qtserialbus -skip qtserialport -skip qtspeech -skip qttools -skip qtvirtualkeyboard -skip qtwayland \
-skip qtwebchannel -skip qtwebengine -skip qtwebsockets -skip qtwebview -skip qtwinextras -skip qtx11extras \
-skip gamepad -skip location -skip qt3d -skip qtactiveqt -skip qtandroidextras \
-skip qtcanvas3d -skip qtcharts -skip qtconnectivity -skip qtdatavis3d -skip qtdoc \
-skip qtgamepad -skip qtlocation -skip qtmacextras -skip qtnetworkauth -skip qtpurchasing \
-skip qtscript -skip qtscxml -skip qtsensors -skip qtserialbus -skip qtserialport \
-skip qtspeech -skip qttools -skip qtvirtualkeyboard -skip qtwayland -skip qtwebchannel \
-skip qtwebengine -skip qtwebsockets -skip qtwebview -skip qtwinextras -skip qtx11extras \
-skip serialbus -skip webengine \
-nomake examples -nomake tests -nomake tools && \
make QMAKE="$(pwd)/qtbase/bin/qmake CONFIG-='debug debug_and_release'" -j$THREADS && \
make -j$THREADS && \
make -j$THREADS install && \
cd qttools/src/linguist/lrelease && \
../../../../qtbase/bin/qmake && \

View File

@@ -102,13 +102,14 @@ Packaging for your favorite distribution would be a welcome contribution!
\* `4` - number of CPU threads to use
5. Monero GUI Windows static binaries will be placed in `monero-gui/build/x86_64-w64-mingw32/release/bin` directory
### Building Linux static binaries with Docker (any OS)
### Building Reproducible Linux static binaries with Docker (any OS)
1. Install Docker [https://docs.docker.com/engine/install/](https://docs.docker.com/engine/install/)
2. Clone the repository
```
git clone --recursive https://github.com/monero-project/monero-gui.git
git clone --branch master --recursive https://github.com/monero-project/monero-gui.git
```
\* `master` - replace with the desired version tag (e.g. `v0.17.1.5`) to build the release binaries.
3. Prepare build environment
```
cd monero-gui
@@ -123,6 +124,11 @@ Packaging for your favorite distribution would be a welcome contribution!
\* `<MONERO_GUI_DIR_FULL_PATH>` - absolute path to `monero-gui` directory
\* `4` - number of CPU threads to use
5. Monero GUI Linux static binaries will be placed in `monero-gui/build/release/bin` directory
6. (*Optional*) Compare `monero-wallet-gui` SHA-256 hash to the one obtained from a trusted source
```
docker run --rm -it -v <MONERO_GUI_DIR_FULL_PATH>:/monero-gui -w /monero-gui monero:build-env-linux sh -c 'shasum -a 256 /monero-gui/build/release/bin/monero-wallet-gui'
```
\* `<MONERO_GUI_DIR_FULL_PATH>` - absolute path to `monero-gui` directory
### Building Android APK with Docker (any OS) *Experimental*
- Minimum Android 9 Pie (API 28)
@@ -211,13 +217,13 @@ The following instructions will fetch Qt from your distribution's repositories i
- For Ubuntu
`sudo apt install qtmultimedia5-dev qml-module-qtmultimedia libzbar-dev`
`sudo apt install qtmultimedia5-dev qml-module-qtmultimedia`
- For Gentoo
The *qml* USE flag must be enabled.
`emerge dev-qt/qtmultimedia:5 media-gfx/zbar`
`emerge dev-qt/qtmultimedia:5`
3. Clone repository
@@ -284,12 +290,6 @@ The Monero GUI on Windows is 64 bits only; 32-bit Windows GUI builds are not off
pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb mingw-w64-x86_64-libgcrypt
```
Optional : To build the flag `WITH_SCANNER`
```
pacman -S mingw-w64-x86_64-zbar
```
You find more details about those dependencies in the [Monero documentation](https://github.com/monero-project/monero). Note that that there is no more need to compile Boost from source; like everything else, you can install it now with a MSYS2 package.
4. Install Qt5

View File

@@ -1,38 +0,0 @@
# from http://code.google.com/p/low-cost-vision-2012/source/browse/CMakeModules/FindZBar0.cmake?name=2-helium-1&r=d61f248bd5565b3c086bf4769a04bfd98f7079df
# - Try to find ZBar
# This will define
#
# ZBAR_FOUND -
# ZBAR_LIBRARY_DIR -
# ZBAR_INCLUDE_DIR -
# ZBAR_LIBRARIES -
#
find_package(PkgConfig)
if(PkgConfig_FOUND)
pkg_check_modules(PC_ZBAR QUIET zbar)
if(PC_ZBAR_FOUND)
set(ZBAR_DEFINITIONS ${PC_ZBAR_CFLAGS_OTHER})
find_library(ZBAR_LIBRARIES NAMES zbar HINTS ${PC_ZBAR_LIBDIR} ${PC_ZBAR_LIBRARY_DIRS})
find_path(ZBAR_INCLUDE_DIR Decoder.h HINTS ${PC_ZBAR_INCLUDEDIR} ${PC_ZBAR_INCLUDE_DIRS} PATH_SUFFIXES zbar)
endif()
endif()
if(NOT ZBAR_LIBRARIES AND ANDROID)
find_library(ZBARJNI_LIBRARY NAMES zbarjni)
find_library(ICONV_LIBRARY NAMES iconv)
if(ZBARJNI_LIBRARY AND ICONV_LIBRARY)
set(ZBAR_LIBRARIES ${ZBARJNI_LIBRARY} ${ICONV_LIBRARY})
endif()
endif()
if(NOT ZBAR_INCLUDE_DIR)
find_path(ZBAR_H_PATH zbar.h)
if(ZBAR_H_PATH)
set(ZBAR_INCLUDE_DIR "${ZBAR_H_PATH}/zbar")
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(ZBAR DEFAULT_MSG ZBAR_LIBRARIES ZBAR_INCLUDE_DIR)
message(STATUS "Found zbar libraries ${ZBAR_LIBRARIES}")

View File

@@ -30,30 +30,26 @@ import QtQuick 2.9
import QtQuick.Layouts 1.1
import QtGraphicalEffects 1.0
import FontAwesome 1.0
import "." as MoneroComponents
import "./effects/" as MoneroEffects
Item {
id: inlineButton
height: parent.height
anchors.top: parent.top
anchors.bottom: parent.bottom
property bool small: false
property string shadowPressedColor: "#B32D00"
property string shadowReleasedColor: "#FF4304"
property string pressedColor: "#FF4304"
property string releasedColor: "#FF6C3C"
property string icon: ""
property string textColor: MoneroComponents.Style.inlineButtonTextColor
property int fontSize: small ? 14 : 16
property int rectHeight: small ? 24 : 24
property int rectHMargin: small ? 16 : 22
property alias text: inlineText.text
property alias fontPixelSize: inlineText.font.pixelSize
property alias fontFamily: inlineText.font.family
property bool isFontAwesomeIcon: fontFamily == FontAwesome.fontFamily || fontFamily == FontAwesome.fontFamilySolid
property alias buttonColor: rect.color
property alias buttonHeight: rect.height
Layout.rightMargin: isFontAwesomeIcon ? 0 : 4
height: isFontAwesomeIcon ? 30 : 24
width: isFontAwesomeIcon ? height : inlineText.width + 16
signal clicked()
function doClick() {
@@ -64,20 +60,16 @@ Item {
Rectangle{
id: rect
anchors.fill: parent
color: MoneroComponents.Style.buttonInlineBackgroundColor
height: 24
width: inlineText.text ? (inlineText.width + 16) : inlineButton.icon ? (inlineImage.width + 16) : rect.height
radius: 4
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 4
MoneroComponents.TextPlain {
id: inlineText
font.family: MoneroComponents.Style.fontBold.name
font.bold: true
font.pixelSize: inlineButton.fontSize
font.pixelSize: inlineButton.isFontAwesomeIcon ? 22 : inlineButton.small ? 14 : 16
color: inlineButton.textColor
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
@@ -90,13 +82,6 @@ Item {
}
}
Image {
id: inlineImage
visible: inlineButton.icon !== ""
anchors.centerIn: parent
source: inlineButton.icon
}
MouseArea {
id: buttonArea
cursorShape: rect.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor

View File

@@ -29,11 +29,15 @@
import FontAwesome 1.0
import QtQuick 2.9
import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.1
import "../components" as MoneroComponents
Item {
id: item
default property alias content: inlineButtons.children
property alias input: input
property alias text: input.text
@@ -53,8 +57,6 @@ Item {
property alias validator: input.validator
property alias readOnly : input.readOnly
property alias cursorPosition: input.cursorPosition
property alias inlineButton: inlineButtonId
property alias inlineButtonText: inlineButtonId.text
property alias inlineIcon: inlineIcon.visible
property bool copyButton: false
property alias copyButtonText: copyButtonId.text
@@ -94,6 +96,7 @@ Item {
height: showingHeader ? (inputLabel.height + inputItem.height + 2) : 42
onActiveFocusChanged: activeFocus && input.forceActiveFocus()
onTextUpdated: {
// check to remove placeholder text when there is content
if(item.isEmpty()){
@@ -234,9 +237,11 @@ Item {
anchors.leftMargin: inlineIcon.visible ? 44 : 0
font.pixelSize: item.fontSize
font.bold: item.fontBold
KeyNavigation.tab: item.KeyNavigation.tab
onEditingFinished: item.editingFinished()
onAccepted: item.accepted();
onTextChanged: item.textUpdated()
rightPadding: inlineButtons.width + 14
topPadding: 10
bottomPadding: 10
echoMode: isPasswordHidden() ? TextInput.Password : TextInput.Normal
@@ -260,13 +265,15 @@ Item {
onClicked: passwordToggle()
}
}
}
MoneroComponents.InlineButton {
id: inlineButtonId
visible: item.inlineButtonText ? true : false
anchors.right: parent.right
anchors.rightMargin: 8
RowLayout {
id: inlineButtons
anchors.bottom: parent.bottom
anchors.top: parent.top
anchors.right: parent.right
anchors.margins: 4
spacing: 4
}
}
}
}

View File

@@ -36,13 +36,15 @@ ColumnLayout {
Layout.fillWidth: true
default property alias content: inlineButtons.children
property alias text: input.text
property alias labelText: inputLabel.text
property alias labelButtonText: labelButton.text
property alias placeholderText: placeholderLabel.text
property int inputPaddingLeft: 10
property int inputPaddingRight: 10
property alias inputPaddingRight: input.rightPadding
property int inputPaddingTop: 10
property int inputPaddingBottom: 10
property int inputRadius: 4
@@ -85,15 +87,12 @@ ColumnLayout {
property alias addressValidation: input.addressValidation
property string backgroundColor: "" // mock
property alias inlineButton: inlineButtonId
property bool inlineButtonVisible: false
property alias inlineButton2: inlineButton2Id
property bool inlineButton2Visible: false
signal labelButtonClicked();
signal inputLabelLinkActivated();
signal editingFinished();
onActiveFocusChanged: activeFocus && input.forceActiveFocus()
spacing: 0
Rectangle {
id: inputLabelRect
@@ -159,10 +158,12 @@ ColumnLayout {
id: input
readOnly: false
addressValidation: false
KeyNavigation.priority: KeyNavigation.BeforeItem
KeyNavigation.tab: item.KeyNavigation.tab
Layout.fillWidth: true
leftPadding: item.inputPaddingLeft
rightPadding: item.inputPaddingRight
rightPadding: inlineButtons.width + 14
topPadding: item.inputPaddingTop
bottomPadding: item.inputPaddingBottom
@@ -198,18 +199,12 @@ ColumnLayout {
visible: !item.borderDisabled
}
MoneroComponents.InlineButton {
id: inlineButtonId
visible: (inlineButtonId.text || inlineButtonId.icon) && inlineButtonVisible ? true : false
RowLayout {
id: inlineButtons
anchors.top: parent.top
anchors.right: parent.right
anchors.rightMargin: 8
}
MoneroComponents.InlineButton {
id: inlineButton2Id
visible: (inlineButton2Id.text || inlineButton2Id.icon) && inlineButton2Visible ? true : false
anchors.right: parent.right
anchors.rightMargin: inlineButtonVisible ? 48 : 8
anchors.margins: 4
spacing: 4
}
}
}

View File

@@ -68,7 +68,7 @@ Item {
id: buttonRect
anchors.fill: parent
radius: 3
border.width: parent.focus ? 1 : 0
border.width: parent.focus && parent.enabled ? 1 : 0
state: button.enabled ? "active" : "disabled"
Component.onCompleted: state = state
@@ -76,7 +76,7 @@ Item {
states: [
State {
name: "hover"
when: buttonArea.containsMouse || button.focus
when: button.enabled && (buttonArea.containsMouse || button.focus)
PropertyChanges {
target: buttonRect
color: primary

View File

@@ -45,20 +45,11 @@ Rectangle {
radius: 10
border.color: MoneroComponents.Style.blackTheme ? Qt.rgba(255, 255, 255, 0.25) : Qt.rgba(0, 0, 0, 0.25)
border.width: 1
focus: true
Keys.enabled: true
Keys.onEscapePressed: {
root.close()
root.rejected()
}
Keys.onEnterPressed: {
root.close()
root.accepted()
}
Keys.onReturnPressed: {
root.close()
root.accepted()
}
KeyNavigation.tab: doneButton
Clipboard { id: clipboard }
@@ -72,7 +63,6 @@ Rectangle {
function open(txid) {
root.transactionID = txid;
root.visible = true;
root.forceActiveFocus();
}
function close() {
@@ -156,13 +146,6 @@ Rectangle {
text: qsTr("Open folder") + translationManager.emptyString;
width: 200
KeyNavigation.tab: doneButton
Keys.enabled: openFolderButton.visible
Keys.onReturnPressed: openFolderButton.onClicked
Keys.onEnterPressed: openFolderButton.onClicked
Keys.onEscapePressed: {
root.close()
root.rejected()
}
onClicked: {
oshelper.openContainingFolder(walletManager.urlToLocalPath(saveTxDialog.fileUrl))
}
@@ -172,15 +155,8 @@ Rectangle {
id: doneButton
text: qsTr("Done") + translationManager.emptyString;
width: 200
focus: true
focus: root.visible
KeyNavigation.tab: openFolderButton
Keys.enabled: doneButton.visible
Keys.onReturnPressed: doneButton.onClicked
Keys.onEnterPressed: doneButton.onClicked
Keys.onEscapePressed: {
root.close()
root.rejected()
}
onClicked: {
root.close()
root.accepted()

View File

@@ -45,33 +45,12 @@ Rectangle {
radius: 10
border.color: MoneroComponents.Style.blackTheme ? Qt.rgba(255, 255, 255, 0.25) : Qt.rgba(0, 0, 0, 0.25)
border.width: 1
focus: true
Keys.enabled: true
Keys.onEscapePressed: {
root.close()
root.clearFields()
root.rejected()
}
Keys.onEnterPressed: {
if (root.state == "default") {
root.close()
root.accepted()
} else if (root.state == "error") {
root.close()
root.clearFields()
root.rejected()
}
}
Keys.onReturnPressed: {
if (root.state == "default") {
root.close()
root.accepted()
} else if (root.state == "error") {
root.close()
root.clearFields()
root.rejected()
}
}
KeyNavigation.tab: confirmButton
property var transactionAmount: ""
@@ -101,7 +80,7 @@ Rectangle {
PropertyChanges { target: bottomMessage; visible: false }
PropertyChanges { target: buttons; visible: true }
PropertyChanges { target: backButton; visible: true; primary: false }
PropertyChanges { target: confirmButton; visible: true }
PropertyChanges { target: confirmButton; visible: true; focus: true }
}, State {
// error message being displayed, show only back button
name: "error";
@@ -115,7 +94,7 @@ Rectangle {
PropertyChanges { target: bottom; visible: true }
PropertyChanges { target: bottomMessage; visible: false }
PropertyChanges { target: buttons; visible: true }
PropertyChanges { target: backButton; visible: true; primary: true }
PropertyChanges { target: backButton; visible: true; primary: true; focus: true }
PropertyChanges { target: confirmButton; visible: false }
}, State {
// creating or sending transaction, show tx details and don't show any button
@@ -141,7 +120,6 @@ Rectangle {
//clean previous error message
errorText.text = "";
root.forceActiveFocus()
}
function close() {
@@ -422,17 +400,8 @@ Rectangle {
id: backButton
text: qsTr("Back") + translationManager.emptyString;
width: 200
focus: false
primary: false
KeyNavigation.tab: confirmButton
Keys.enabled: backButton.visible
Keys.onReturnPressed: backButton.onClicked
Keys.onEnterPressed: backButton.onClicked
Keys.onEscapePressed: {
root.close()
root.clearFields()
root.rejected()
}
onClicked: {
root.close()
root.clearFields()
@@ -445,16 +414,7 @@ Rectangle {
text: qsTr("Confirm") + translationManager.emptyString;
rightIcon: "qrc:///images/rightArrow.png"
width: 200
focus: false
KeyNavigation.tab: backButton
Keys.enabled: confirmButton.visible
Keys.onReturnPressed: confirmButton.onClicked
Keys.onEnterPressed: confirmButton.onClicked
Keys.onEscapePressed: {
root.close()
root.clearFields()
root.rejected()
}
onClicked: {
root.close()
root.accepted()

7
external/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,7 @@
add_library(quirc STATIC
quirc/lib/decode.c
quirc/lib/identify.c
quirc/lib/quirc.c
quirc/lib/version_db.c
)
target_include_directories(quirc PUBLIC quirc/lib)

1
external/quirc vendored Submodule

Submodule external/quirc added at 7e7ab596e4

View File

@@ -105,9 +105,6 @@ Source: "bin\extras\monero-gen-ssl-cert.exe"; DestDir: "{app}"; Flags: ignorever
; Qt Quick 2D Renderer fallback for systems / environments with "low-level graphics" i.e. without 3D support
Source: "bin\start-low-graphics-mode.bat"; DestDir: "{app}"; Flags: ignoreversion
; Use a scale factor of 2 for Qt for high-DPI systems, as long as Qt does not handle some such systems adequately
Source: "bin\start-high-dpi.bat"; DestDir: "{app}"; Flags: ignoreversion
; Mesa, open-source OpenGL implementation; part of "low-level graphics" support
Source: "bin\opengl32sw.dll"; DestDir: "{app}"; Flags: ignoreversion
@@ -170,6 +167,7 @@ Type: files; Name: "{app}\libssp-0.dll"
Type: files; Name: "{app}\libhidapi-0.dll"
Type: files; Name: "{app}\libeay32.dll"
Type: files; Name: "{app}\ssleay32.dll"
Type: files; Name: "{app}\start-high-dpi.bat"
Type: files; Name: "{group}\Utilities\x (Check Blockchain Folder).lnk"

View File

@@ -113,5 +113,5 @@ function capitalize(s){
}
function removeTrailingZeros(value) {
return (value + '').replace(/(\.\d*[1-9])0+$/, '$1');
return (value + '').replace(/\.?0*$/, '');
}

View File

@@ -952,10 +952,12 @@ ApplicationWindow {
// Store to file
transaction.setFilename(path);
}
appWindow.showProcessingSplash(qsTr("Sending transaction ..."));
currentWallet.commitTransactionAsync(transaction);
}
function onTransactionCommitted(success, transaction, txid) {
hideProcessingSplash();
if (!success) {
console.log("Error committing transaction: " + transaction.errorString);
informationPopup.title = qsTr("Error") + translationManager.emptyString
@@ -1332,6 +1334,25 @@ ApplicationWindow {
appWindow.fiatApiRefresh();
appWindow.fiatTimerStart();
}
if (persistentSettings.askDesktopShortcut && !persistentSettings.portable) {
persistentSettings.askDesktopShortcut = false;
if (isTails) {
oshelper.createDesktopEntry();
} else if (isLinux) {
confirmationDialog.title = qsTr("Desktop entry") + translationManager.emptyString;
confirmationDialog.text = qsTr("Would you like to register Monero GUI Desktop entry?") + translationManager.emptyString;
confirmationDialog.icon = StandardIcon.Question;
confirmationDialog.cancelText = qsTr("No") + translationManager.emptyString;
confirmationDialog.okText = qsTr("Yes") + translationManager.emptyString;
confirmationDialog.onAcceptedCallback = function() {
oshelper.createDesktopEntry();
};
confirmationDialog.onRejectedCallback = null;
confirmationDialog.open();
}
}
}
MoneroSettings {
@@ -1342,6 +1363,7 @@ ApplicationWindow {
return "";
}
property bool askDesktopShortcut: isLinux
property string language: 'English (US)'
property string language_wallet: 'English'
property string locale: 'en_US'

2
monero

Submodule monero updated: 3942a1cd04...8fef32e45c

View File

@@ -314,16 +314,16 @@ Rectangle {
}
}
inlineButton.text: FontAwesome.qrcode
inlineButton.fontPixelSize: 22
inlineButton.fontFamily: FontAwesome.fontFamily
inlineButton.textColor: MoneroComponents.Style.defaultFontColor
inlineButton.buttonColor: MoneroComponents.Style.orange
inlineButton.onClicked: {
cameraUi.state = "Capture"
cameraUi.qrcode_decoded.connect(root.updateFromQrCode)
MoneroComponents.InlineButton {
buttonColor: MoneroComponents.Style.orange
fontFamily: FontAwesome.fontFamily
text: FontAwesome.qrcode
visible : appWindow.qrScannerEnabled && !addressLine.text
onClicked: {
cameraUi.state = "Capture"
cameraUi.qrcode_decoded.connect(root.updateFromQrCode)
}
}
inlineButtonVisible : appWindow.qrScannerEnabled && !addressLine.text
}
MoneroComponents.StandardButton {

View File

@@ -98,7 +98,7 @@ Rectangle {
addressLine.text = address
setPaymentId(payment_id);
amountLine.text = amount
setDescription(recipient_name + " " + tx_description);
setDescription((recipient_name ? recipient_name + " " : "") + tx_description);
cameraUi.qrcode_decoded.disconnect(updateFromQrCode)
}
@@ -170,8 +170,8 @@ Rectangle {
LineEditMulti {
id: addressLine
KeyNavigation.tab: amountLine
spacing: 0
inputPaddingRight: inlineButtonVisible && inlineButton2Visible ? 100 : 60
fontBold: true
labelText: qsTr("Address") + translationManager.emptyString
labelButtonText: qsTr("Resolve") + translationManager.emptyString
@@ -195,27 +195,25 @@ Rectangle {
setDescription(parsed.tx_description);
}
}
inlineButton.text: FontAwesome.addressBook
inlineButton.buttonHeight: 30
inlineButton.fontPixelSize: 22
inlineButton.fontFamily: FontAwesome.fontFamily
inlineButton.textColor: MoneroComponents.Style.defaultFontColor
inlineButton.onClicked: {
middlePanel.addressBookView.selectAndSend = true;
appWindow.showPageRequest("AddressBook");
}
inlineButtonVisible: true
inlineButton2.text: FontAwesome.qrcode
inlineButton2.buttonHeight: 30
inlineButton2.fontPixelSize: 22
inlineButton2.fontFamily: FontAwesome.fontFamily
inlineButton2.textColor: MoneroComponents.Style.defaultFontColor
inlineButton2.onClicked: {
cameraUi.state = "Capture"
cameraUi.qrcode_decoded.connect(updateFromQrCode)
}
inlineButton2Visible: appWindow.qrScannerEnabled
MoneroComponents.InlineButton {
fontFamily: FontAwesome.fontFamily
text: FontAwesome.addressBook
onClicked: {
middlePanel.addressBookView.selectAndSend = true;
appWindow.showPageRequest("AddressBook");
}
}
MoneroComponents.InlineButton {
fontFamily: FontAwesome.fontFamily
text: FontAwesome.qrcode
visible: appWindow.qrScannerEnabled
onClicked: {
cameraUi.state = "Capture"
cameraUi.qrcode_decoded.connect(updateFromQrCode)
}
}
}
}
@@ -277,6 +275,7 @@ Rectangle {
// Amount input
LineEdit {
id: amountLine
KeyNavigation.tab: sendButton
Layout.fillWidth: true
inlineIcon: true
labelText: "<style type='text/css'>a {text-decoration: none; color: #858585; font-size: 14px;}</style>\
@@ -293,10 +292,8 @@ Rectangle {
placeholderText: "0.00"
width: 100
fontBold: true
inlineButtonText: qsTr("All") + translationManager.emptyString
inlineButton.onClicked: amountLine.text = "(all)"
onTextChanged: {
amountLine.text = amountLine.text.replace(",", ".");
amountLine.text = amountLine.text.trim().replace(",", ".");
const match = amountLine.text.match(/^0+(\d.*)/);
if (match) {
const cursorPosition = amountLine.cursorPosition;
@@ -310,10 +307,14 @@ Rectangle {
}
amountLine.error = walletManager.amountFromString(amountLine.text) > appWindow.getUnlockedBalance()
}
validator: RegExpValidator {
regExp: /^(\d{1,8})?([\.,]\d{1,12})?$/
regExp: /^\s*(\d{1,8})?([\.,]\d{1,12})?\s*$/
}
MoneroComponents.InlineButton {
text: qsTr("All") + translationManager.emptyString
onClicked: amountLine.text = "(all)"
}
}
MoneroComponents.TextPlain {
@@ -488,6 +489,7 @@ Rectangle {
RowLayout {
StandardButton {
id: sendButton
KeyNavigation.tab: addressLine
rightIcon: "qrc:///images/rightArrow.png"
rightIconInactive: "qrc:///images/rightArrowInactive.png"
Layout.topMargin: 4

View File

@@ -55,13 +55,6 @@ if(ENABLE_PASS_STRENGTH_METER)
)
endif()
if(WITH_SCANNER)
file(GLOB QR_CODE_FILES
"QR-Code-scanner/*.h"
"QR-Code-scanner/*.cpp"
)
endif()
set(EXECUTABLE_FLAG)
if(MINGW)
set(EXECUTABLE_FLAG WIN32)
@@ -84,7 +77,6 @@ endif()
set(monero_wallet_gui_sources
${SOURCE_FILES}
${PASS_STRENGTH_FILES}
${QR_CODE_FILES}
${RESOURCES}
)
@@ -128,7 +120,6 @@ target_include_directories(monero-wallet-gui PUBLIC
${X11_INCLUDE_DIR}
${Boost_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIR}
${ZBAR_INCLUDE_DIR}
)
target_compile_definitions(monero-wallet-gui
@@ -137,6 +128,14 @@ target_compile_definitions(monero-wallet-gui
${Qt5Qml_DEFINITIONS}
)
if(APPLE)
if(NOT ICU_ROOT)
execute_process(COMMAND brew --prefix icu4c OUTPUT_VARIABLE ICU_ROOT OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
find_package(ICU REQUIRED COMPONENTS data i18n uc)
target_link_directories(monero-wallet-gui PRIVATE ${ICU_ROOT}/lib)
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
target_link_libraries(monero-wallet-gui
@@ -159,6 +158,7 @@ target_link_libraries(monero-wallet-gui
${EXTRA_LIBRARIES}
${ICU_LIBRARIES}
openpgp
qrdecoder
translations
)
@@ -171,16 +171,14 @@ if(X11_FOUND)
endif()
if(WITH_SCANNER)
if(NOT ANDROID)
target_link_libraries(monero-wallet-gui qrscanner)
if(LINUX AND NOT ANDROID)
target_link_libraries(monero-wallet-gui
${ZBAR_LIBRARIES}
jpeg
v4l2
v4lconvert
rt
)
else()
target_link_libraries(monero-wallet-gui ${ZBAR_LIBRARIES})
endif()
endif()

View File

@@ -1,4 +1,21 @@
file(GLOB_RECURSE SRC_SOURCES *.cpp)
file(GLOB_RECURSE SRC_HEADERS *.h)
add_library(qrdecoder STATIC
Decoder.cpp
)
target_link_libraries(qrdecoder
PUBLIC
Qt5::Gui
PRIVATE
quirc
)
if(WITH_SCANNER)
add_library(qrscanner
QrCodeScanner.cpp
QrScanThread.cpp
)
target_link_libraries(qrscanner
PUBLIC
Qt5::Multimedia
qrdecoder
)
endif()

View File

@@ -0,0 +1,71 @@
#include "Decoder.h"
#include <limits>
#include "quirc.h"
QrDecoder::QrDecoder()
: m_qr(quirc_new())
{
if (m_qr == nullptr)
{
throw std::runtime_error("QUIRC: failed to allocate memory");
}
}
QrDecoder::~QrDecoder()
{
quirc_destroy(m_qr);
}
std::vector<std::string> QrDecoder::decode(const QImage &image)
{
if (image.format() == QImage::Format_Grayscale8)
{
return decodeGrayscale8(image);
}
return decodeGrayscale8(image.convertToFormat(QImage::Format_Grayscale8));
}
std::vector<std::string> QrDecoder::decodeGrayscale8(const QImage &image)
{
if (quirc_resize(m_qr, image.width(), image.height()) < 0)
{
throw std::runtime_error("QUIRC: failed to allocate video memory");
}
uint8_t *rawImage = quirc_begin(m_qr, nullptr, nullptr);
if (rawImage == nullptr)
{
throw std::runtime_error("QUIRC: failed to get image buffer");
}
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
std::copy(image.constBits(), image.constBits() + image.sizeInBytes(), rawImage);
#else
std::copy(image.constBits(), image.constBits() + image.byteCount(), rawImage);
#endif
quirc_end(m_qr);
const int count = quirc_count(m_qr);
if (count < 0)
{
throw std::runtime_error("QUIRC: failed to get the number of recognized QR-codes");
}
std::vector<std::string> result;
result.reserve(static_cast<size_t>(count));
for (int index = 0; index < count; ++index)
{
quirc_code code;
quirc_extract(m_qr, index, &code);
quirc_data data;
const quirc_decode_error_t err = quirc_decode(&code, &data);
if (err == QUIRC_SUCCESS)
{
result.emplace_back(&data.payload[0], &data.payload[data.payload_len]);
}
}
return result;
}

View File

@@ -0,0 +1,21 @@
#include <QImage>
struct quirc;
class QrDecoder
{
public:
QrDecoder(const QrDecoder &) = delete;
QrDecoder &operator=(const QrDecoder &) = delete;
QrDecoder();
~QrDecoder();
std::vector<std::string> decode(const QImage &image);
private:
std::vector<std::string> decodeGrayscale8(const QImage &image);
private:
quirc *m_qr;
};

View File

@@ -27,7 +27,6 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "QrCodeScanner.h"
#include <WalletManager.h>
#include <QVideoProbe>
#include <QCamera>
@@ -40,7 +39,7 @@ QrCodeScanner::QrCodeScanner(QObject *parent)
m_probe = new QVideoProbe(this);
m_thread = new QrScanThread(this);
m_thread->start();
QObject::connect(m_thread, SIGNAL(decoded(int, QString)), this, SIGNAL(decoded(int, QString)));
QObject::connect(m_thread, SIGNAL(decoded(QString)), this, SIGNAL(decoded(QString)));
QObject::connect(m_thread, SIGNAL(notifyError(const QString &, bool)), this, SIGNAL(notifyError(const QString &, bool)));
connect(m_probe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(processFrame(QVideoFrame)));
}

View File

@@ -56,8 +56,7 @@ public Q_SLOTS:
Q_SIGNALS:
void enabledChanged();
void decoded(int type, const QString &data);
void decode(int type, const QString &data);
void decoded(const QString &data);
void notifyError(const QString &error, bool warning = false);
protected:

View File

@@ -38,62 +38,15 @@ QrScanThread::QrScanThread(QObject *parent)
: QThread(parent)
,m_running(true)
{
m_scanner.set_handler(*this);
}
void QrScanThread::image_callback(zbar::Image &image)
{
qDebug() << "image_callback : Found Code ! " ;
for(zbar::Image::SymbolIterator sym = image.symbol_begin();
sym != image.symbol_end();
++sym)
if(!sym->get_count()) {
QString data = QString::fromStdString(sym->get_data());
emit decoded(sym->get_type(), data);
}
}
void QrScanThread::processZImage(zbar::Image &image)
{
m_scanner.recycle_image(image);
zbar::Image tmp = image.convert(*(long*)"Y800");
m_scanner.scan(tmp);
image.set_symbols(tmp.get_symbols());
}
bool QrScanThread::zimageFromQImage(const QImage &qimg, zbar::Image &dst)
{
switch( qimg.format() ){
case QImage::Format_RGB32 :
case QImage::Format_ARGB32 :
case QImage::Format_ARGB32_Premultiplied :
break;
default :
emit notifyError(QString("Invalid QImage Format !"));
return false;
}
unsigned int bpl( qimg.bytesPerLine() ), width( bpl / 4), height( qimg.height());
dst.set_size(width, height);
dst.set_format("BGR4");
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
unsigned long datalen = qimg.sizeInBytes();
#else
unsigned long datalen = qimg.byteCount();
#endif
dst.set_data(qimg.bits(), datalen);
if((width * 4 != bpl) || (width * height * 4 > datalen)){
emit notifyError(QString("QImage to Zbar::Image failed !"));
return false;
}
return true;
}
void QrScanThread::processQImage(const QImage &qimg)
{
try {
m_image = QSharedPointer<zbar::Image>(new zbar::Image());
if( ! zimageFromQImage(qimg, *m_image) )
return;
processZImage(*m_image);
for (const std::string &code : m_decoder.decode(qimg))
{
emit decoded(QString::fromStdString(code));
}
}
catch(std::exception &e) {
qDebug() << "ERROR: " << e.what();

View File

@@ -35,9 +35,10 @@
#include <QEvent>
#include <QVideoFrame>
#include <QCamera>
#include <zbar.h>
class QrScanThread : public QThread, public zbar::Image::Handler
#include "Decoder.h"
class QrScanThread : public QThread
{
Q_OBJECT
@@ -47,20 +48,16 @@ public:
virtual void stop();
Q_SIGNALS:
void decoded(int type, const QString &data);
void decoded(const QString &data);
void notifyError(const QString &error, bool warning = false);
protected:
virtual void run();
void processVideoFrame(const QVideoFrame &);
void processQImage(const QImage &);
void processZImage(zbar::Image &image);
virtual void image_callback(zbar::Image &image);
bool zimageFromQImage(const QImage&, zbar::Image &);
private:
zbar::ImageScanner m_scanner;
QSharedPointer<zbar::Image> m_image;
QrDecoder m_decoder;
bool m_running;
QMutex m_mutex;
QWaitCondition m_waitCondition;

View File

@@ -104,10 +104,7 @@ void Wallet::updateConnectionStatusAsync()
setConnectionStatus(ConnectionStatus_Connecting);
}
ConnectionStatus newStatus = static_cast<ConnectionStatus>(m_walletImpl->connected());
if (newStatus != m_connectionStatus || !m_initialized) {
m_initialized = true;
setConnectionStatus(newStatus);
}
setConnectionStatus(newStatus);
// Release lock
m_connectionStatusRunning = false;
});
@@ -115,8 +112,13 @@ void Wallet::updateConnectionStatusAsync()
Wallet::ConnectionStatus Wallet::connected(bool forceCheck)
{
if (!m_initialized)
{
return ConnectionStatus_Connecting;
}
// cache connection status
if (forceCheck || !m_initialized || (m_connectionStatusTime.elapsed() / 1000 > m_connectionStatusTtl && !m_connectionStatusRunning) || m_connectionStatusTime.elapsed() > 30000) {
if (forceCheck || (m_connectionStatusTime.elapsed() / 1000 > m_connectionStatusTtl && !m_connectionStatusRunning) || m_connectionStatusTime.elapsed() > 30000) {
qDebug() << "Checking connection status";
m_connectionStatusRunning = true;
m_connectionStatusTime.restart();
@@ -277,14 +279,25 @@ void Wallet::initAsync(
{
qDebug() << "initAsync: " + daemonAddress;
const auto future = m_scheduler.run([this, daemonAddress, trustedDaemon, upperTransactionLimit, isRecovering, isRecoveringFromDevice, restoreHeight, proxyAddress] {
bool success = init(daemonAddress, trustedDaemon, upperTransactionLimit, isRecovering, isRecoveringFromDevice, restoreHeight, proxyAddress);
if (success)
m_initialized = init(
daemonAddress,
trustedDaemon,
upperTransactionLimit,
isRecovering,
isRecoveringFromDevice,
restoreHeight,
proxyAddress);
if (m_initialized)
{
emit walletCreationHeightChanged();
qDebug() << "init async finished - starting refresh";
connected(true);
startRefresh();
}
else
{
qCritical() << "Failed to initialize the wallet";
}
});
if (future.first)
{
@@ -1054,6 +1067,7 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent)
, m_connectionStatus(Wallet::ConnectionStatus_Disconnected)
, m_connectionStatusTtl(WALLET_CONNECTION_STATUS_CACHE_TTL_SECONDS)
, m_disconnected(true)
, m_initialized(false)
, m_currentSubaddressAccount(0)
, m_subaddress(nullptr)
, m_subaddressModel(nullptr)
@@ -1074,7 +1088,6 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent)
m_connectionStatusTime.start();
m_daemonBlockChainHeightTime.start();
m_daemonBlockChainTargetHeightTime.start();
m_initialized = false;
m_connectionStatusRunning = false;
m_daemonUsername = "";
m_daemonPassword = "";

View File

@@ -29,6 +29,8 @@
#ifndef WALLET_H
#define WALLET_H
#include <atomic>
#include <QElapsedTimer>
#include <QObject>
#include <QMutex>
@@ -444,7 +446,7 @@ private:
int m_connectionStatusTtl;
mutable QElapsedTimer m_connectionStatusTime;
bool m_disconnected;
mutable bool m_initialized;
std::atomic<bool> m_initialized;
uint32_t m_currentSubaddressAccount;
Subaddress * m_subaddress;
mutable SubaddressModel * m_subaddressModel;

View File

@@ -194,15 +194,7 @@ int main(int argc, char *argv[])
QDir::setCurrent(QDir(MacOSHelper::bundlePath() + QDir::separator() + "..").canonicalPath());
#endif
if (MoneroSettings::portableConfigExists())
{
const QString cacheDir(MoneroSettings::portableFolderName() + QDir::separator() + ".cache");
if (!qputenv("QML_DISK_CACHE_PATH", cacheDir.toUtf8()))
{
qCritical() << "Error: failed to set QML disk cache path";
return 1;
}
}
qputenv("QML_DISABLE_DISK_CACHE", "1");
MainApp app(argc, argv);
@@ -319,11 +311,6 @@ Verify update binary using 'shasum'-compatible (SHA256 algo) output signed by tw
return 1;
}
// Desktop entry
#ifdef Q_OS_LINUX
registerXdgMime(app);
#endif
IPC *ipc = new IPC(&app);
QStringList posArgs = parser.positionalArguments();

View File

@@ -46,11 +46,13 @@
#endif
#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
#include <X11/XKBlib.h>
#undef Bool
#undef KeyPress
#undef KeyRelease
#undef FocusIn
#undef FocusOut
// #undef those Xlib #defines that conflict with QEvent::Type enum
#include "qt/utils.h"
#endif
#if defined(Q_OS_WIN)
@@ -85,6 +87,13 @@ OSHelper::OSHelper(QObject *parent) : QObject(parent)
}
void OSHelper::createDesktopEntry() const
{
#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
registerXdgMime();
#endif
}
QString OSHelper::downloadLocation() const
{
return QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);

View File

@@ -41,6 +41,7 @@ class OSHelper : public QObject
public:
explicit OSHelper(QObject *parent = 0);
Q_INVOKABLE void createDesktopEntry() const;
Q_INVOKABLE QString downloadLocation() const;
Q_INVOKABLE bool openContainingFolder(const QString &filePath) const;
Q_INVOKABLE QString openSaveFileDialog(const QString &title, const QString &folder, const QString &filename) const;

View File

@@ -27,7 +27,7 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QtCore>
#include <QApplication>
#include <QCoreApplication>
#include <QtGlobal>
#include "TailsOS.h"
@@ -88,7 +88,7 @@ QString getAccountName(){
}
#ifdef Q_OS_LINUX
QString xdgMime(QApplication &app){
QString xdgMime(){
return QString(
"[Desktop Entry]\n"
"Name=Monero GUI\n"
@@ -105,32 +105,31 @@ QString xdgMime(QApplication &app){
"StartupNotify=true\n"
"X-GNOME-Bugzilla-Bugzilla=GNOME\n"
"X-GNOME-UsesNotifications=true\n"
).arg(app.applicationFilePath());
).arg(QCoreApplication::applicationFilePath());
}
void registerXdgMime(QApplication &app){
void registerXdgMime(){
// Register desktop entry
// - MacOS handled via Info.plist
// - Windows handled in the installer by rbrunner7
// - Linux written to `QStandardPaths::ApplicationsLocation`
// - Tails written to persistent dotfiles
QString mime = xdgMime(app);
QString mime = xdgMime();
QString appPath = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation);
QString filePath = QString("%1/monero-gui.desktop").arg(appPath);
if (TailsOS::detect() && TailsOS::detectDotPersistence() && TailsOS::usePersistence) {
TailsOS::persistXdgMime(filePath, mime);
return;
if (TailsOS::detect())
{
if (TailsOS::detectDotPersistence() && TailsOS::usePersistence)
{
TailsOS::persistXdgMime(filePath, mime);
}
}
else
{
QDir().mkpath(QFileInfo(filePath).path());
fileWrite(filePath, mime);
}
QFileInfo file(filePath);
QDir().mkpath(file.path()); // ensure directory exists
#ifdef QT_DEBUG
qDebug() << "Writing xdg mime: " << filePath;
#endif
fileWrite(filePath, mime);
}
#endif

View File

@@ -39,8 +39,8 @@ QByteArray fileOpen(QString path);
bool fileWrite(QString path, QString data);
QString getAccountName();
#ifdef Q_OS_LINUX
QString xdgMime(QApplication &app);
void registerXdgMime(QApplication &app);
QString xdgMime();
void registerXdgMime();
#endif
const static QRegExp reURI = QRegExp("^\\w+:\\/\\/([\\w+\\-?\\-_\\-=\\-&]+)");
QString randomUserAgent();

View File

@@ -81,13 +81,16 @@ ColumnLayout {
placeholderText: qsTr("Default") + translationManager.emptyString
placeholderFontSize: 15
text: persistentSettings.blockchainDataDir
inlineButton.small: true
inlineButtonText: qsTr("Browse") + translationManager.emptyString
inlineButton.onClicked: {
if(persistentSettings.blockchainDataDir != "");
blockchainFileDialog.folder = "file://" + persistentSettings.blockchainDataDir;
blockchainFileDialog.open();
blockchainFolder.focus = true;
MoneroComponents.InlineButton {
small: true
text: qsTr("Browse") + translationManager.emptyString
onClicked: {
if(persistentSettings.blockchainDataDir != "");
blockchainFileDialog.folder = "file://" + persistentSettings.blockchainDataDir;
blockchainFileDialog.open();
blockchainFolder.focus = true;
}
}
}

View File

@@ -50,10 +50,8 @@ Rectangle {
if(wizardController.walletRestoreMode === "keys") {
return wizardWalletInput.verify() && wizardRestoreWallet1.verifyFromKeys();
} else if(wizardController.walletRestoreMode === "seed") {
valid = wizardWalletInput.verify();
if(!valid) return false;
valid = Wizard.checkSeed(seedInput.text);
return valid;
seedInput.error = seedInput.text && !Wizard.checkSeed(seedInput.text);
return wizardWalletInput.verify() && seedInput.text && Wizard.checkSeed(seedInput.text);
}
return false;
@@ -210,7 +208,7 @@ Rectangle {
anchors.margins: 8
anchors.leftMargin: 10
font.family: MoneroComponents.Style.fontRegular.name
text: qsTr("Enter your 25 (or 24) word mnemonic seed") + translationManager.emptyString
text: qsTr("Enter your 25 word mnemonic seed") + translationManager.emptyString
color: MoneroComponents.Style.defaultFontColor
visible: !seedInput.text
}

View File

@@ -89,16 +89,19 @@ GridLayout {
placeholderText: "..."
placeholderFontSize: 16
text: appWindow.accountsDir + "/"
inlineButton.small: true
inlineButtonText: qsTr("Browse") + translationManager.emptyString
inlineButton.onClicked: {
fileWalletDialog.folder = walletManager.localPathToUrl(walletLocation.text)
fileWalletDialog.open()
walletLocation.focus = true
}
onTextChanged: {
walletLocation.error = walletLocation.text === "";
}
MoneroComponents.InlineButton {
small: true
text: qsTr("Browse") + translationManager.emptyString
onClicked: {
fileWalletDialog.folder = walletManager.localPathToUrl(walletLocation.text)
fileWalletDialog.open()
walletLocation.focus = true
}
}
}
FileDialog {