forked from Public/monero-gui
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ca5f10fa8 | ||
|
|
f7b817972f | ||
|
|
9399839d96 | ||
|
|
51a4d1f629 | ||
|
|
bbe3716542 | ||
|
|
72ab846be5 | ||
|
|
8e6a2cde0f | ||
|
|
c34d4ee97c | ||
|
|
0194cf8f22 | ||
|
|
ad06fcc79e | ||
|
|
7d4b82c691 | ||
|
|
69f989d617 | ||
|
|
0f3df860e3 | ||
|
|
5662841d22 | ||
|
|
3f0bbfb6aa | ||
|
|
ba4d6993b7 | ||
|
|
8d4cda030e | ||
|
|
772b828b67 | ||
|
|
78f5360af2 | ||
|
|
a1fdffcabe |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -2,3 +2,6 @@
|
|||||||
path = monero
|
path = monero
|
||||||
url = https://github.com/monero-project/monero
|
url = https://github.com/monero-project/monero
|
||||||
ignore = all
|
ignore = all
|
||||||
|
[submodule "external/quirc"]
|
||||||
|
path = external/quirc
|
||||||
|
url = https://github.com/dlbeer/quirc/
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ message(STATUS "Initiating compile using CMake ${CMAKE_VERSION}")
|
|||||||
|
|
||||||
set(VERSION_MAJOR "17")
|
set(VERSION_MAJOR "17")
|
||||||
set(VERSION_MINOR "1")
|
set(VERSION_MINOR "1")
|
||||||
set(VERSION_REVISION "7")
|
set(VERSION_REVISION "9")
|
||||||
set(VERSION "0.${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}")
|
set(VERSION "0.${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}")
|
||||||
|
|
||||||
option(STATIC "Link libraries statically, requires static Qt")
|
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: include dir at ${OPENSSL_INCLUDE_DIR}")
|
||||||
message(STATUS "OpenSSL: libraries at ${OPENSSL_LIBRARIES} ${OPENSSL_SSL_LIBRARIES}")
|
message(STATUS "OpenSSL: libraries at ${OPENSSL_LIBRARIES} ${OPENSSL_SSL_LIBRARIES}")
|
||||||
|
|
||||||
# Zbar (for QR scanner)
|
|
||||||
if(WITH_SCANNER)
|
if(WITH_SCANNER)
|
||||||
add_definitions(-DWITH_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()
|
endif()
|
||||||
|
|
||||||
# Sodium
|
# Sodium
|
||||||
@@ -563,6 +559,6 @@ if (HIDAPI_FOUND OR LibUSB_COMPILE_TEST_PASSED)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(external)
|
||||||
add_subdirectory(translations)
|
add_subdirectory(translations)
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|||||||
@@ -151,25 +151,6 @@ RUN set -ex \
|
|||||||
&& make -j${THREADS} install \
|
&& make -j${THREADS} install \
|
||||||
&& rm -rf $(pwd)
|
&& 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 \
|
RUN git clone -b libgpg-error-1.38 --depth 1 git://git.gnupg.org/libgpg-error.git \
|
||||||
&& cd libgpg-error \
|
&& cd libgpg-error \
|
||||||
&& git reset --hard 71d278824c5fe61865f7927a2ed1aa3115f9e439 \
|
&& git reset --hard 71d278824c5fe61865f7927a2ed1aa3115f9e439 \
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
FROM ubuntu:20.04
|
FROM ubuntu:20.04
|
||||||
|
|
||||||
ARG THREADS=1
|
ARG THREADS=1
|
||||||
|
ARG QT_VERSION=5.15.2
|
||||||
|
ENV SOURCE_DATE_EPOCH=1397818193
|
||||||
|
|
||||||
RUN apt update && \
|
RUN apt update && \
|
||||||
DEBIAN_FRONTEND=noninteractive apt install -y build-essential cmake g++-mingw-w64 gettext git libtool pkg-config \
|
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 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 && \
|
RUN git clone git://code.qt.io/qt/qt5.git -b ${QT_VERSION} --depth 1 && \
|
||||||
echo "5ce285209290a157d7f42ec8eb22bf3f1d76f2e03a95fc0b99b553391be01642 qt-everywhere-opensource-src-5.9.9.tar.xz" > hashsum.txt && \
|
cd qt5 && \
|
||||||
sha256sum -c hashsum.txt && \
|
git clone git://code.qt.io/qt/qtbase.git -b ${QT_VERSION} --depth 1 && \
|
||||||
tar -xf qt-everywhere-opensource-src-5.9.9.tar.xz && \
|
git clone git://code.qt.io/qt/qtdeclarative.git -b ${QT_VERSION} --depth 1 && \
|
||||||
rm qt-everywhere-opensource-src-5.9.9.tar.xz && \
|
git clone git://code.qt.io/qt/qtgraphicaleffects.git -b ${QT_VERSION} --depth 1 && \
|
||||||
cd qt-everywhere-opensource-src-5.9.9 && \
|
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++ \
|
./configure --prefix=/depends/x86_64-w64-mingw32 -xplatform win32-g++ \
|
||||||
-device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- \
|
-device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- \
|
||||||
-I $(pwd)/qtbase/src/3rdparty/angle/include \
|
-I $(pwd)/qtbase/src/3rdparty/angle/include \
|
||||||
-opensource -confirm-license -release -static -static-runtime -opengl dynamic -no-angle \
|
-opensource -confirm-license -release -static -static-runtime -opengl dynamic -no-angle \
|
||||||
-no-avx -no-openssl -no-sql-sqlite \
|
-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 \
|
-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 gamepad -skip location -skip qt3d -skip qtactiveqt -skip qtandroidextras \
|
||||||
-skip qtconnectivity -skip qtdatavis3d -skip qtdoc -skip qtgamepad -skip qtlocation -skip qtmacextras \
|
-skip qtcanvas3d -skip qtcharts -skip qtconnectivity -skip qtdatavis3d -skip qtdoc \
|
||||||
-skip qtmultimedia -skip qtnetworkauth -skip qtpurchasing -skip qtscript -skip qtscxml -skip qtsensors \
|
-skip qtgamepad -skip qtlocation -skip qtmacextras -skip qtnetworkauth -skip qtpurchasing \
|
||||||
-skip qtserialbus -skip qtserialport -skip qtspeech -skip qttools -skip qtvirtualkeyboard -skip qtwayland \
|
-skip qtscript -skip qtscxml -skip qtsensors -skip qtserialbus -skip qtserialport \
|
||||||
-skip qtwebchannel -skip qtwebengine -skip qtwebsockets -skip qtwebview -skip qtwinextras -skip qtx11extras \
|
-skip qtspeech -skip qttools -skip qtvirtualkeyboard -skip qtwayland -skip qtwebchannel \
|
||||||
|
-skip qtwebengine -skip qtwebsockets -skip qtwebview -skip qtwinextras -skip qtx11extras \
|
||||||
-skip serialbus -skip webengine \
|
-skip serialbus -skip webengine \
|
||||||
-nomake examples -nomake tests -nomake tools && \
|
-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 && \
|
make -j$THREADS install && \
|
||||||
cd qttools/src/linguist/lrelease && \
|
cd qttools/src/linguist/lrelease && \
|
||||||
../../../../qtbase/bin/qmake && \
|
../../../../qtbase/bin/qmake && \
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -217,13 +217,13 @@ The following instructions will fetch Qt from your distribution's repositories i
|
|||||||
|
|
||||||
- For Ubuntu
|
- For Ubuntu
|
||||||
|
|
||||||
`sudo apt install qtmultimedia5-dev qml-module-qtmultimedia libzbar-dev`
|
`sudo apt install qtmultimedia5-dev qml-module-qtmultimedia`
|
||||||
|
|
||||||
- For Gentoo
|
- For Gentoo
|
||||||
|
|
||||||
The *qml* USE flag must be enabled.
|
The *qml* USE flag must be enabled.
|
||||||
|
|
||||||
`emerge dev-qt/qtmultimedia:5 media-gfx/zbar`
|
`emerge dev-qt/qtmultimedia:5`
|
||||||
|
|
||||||
|
|
||||||
3. Clone repository
|
3. Clone repository
|
||||||
@@ -290,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
|
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.
|
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
|
4. Install Qt5
|
||||||
|
|||||||
@@ -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}")
|
|
||||||
@@ -30,30 +30,26 @@ import QtQuick 2.9
|
|||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
|
import FontAwesome 1.0
|
||||||
|
|
||||||
import "." as MoneroComponents
|
import "." as MoneroComponents
|
||||||
import "./effects/" as MoneroEffects
|
import "./effects/" as MoneroEffects
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: inlineButton
|
id: inlineButton
|
||||||
height: parent.height
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
|
|
||||||
property bool small: false
|
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 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 text: inlineText.text
|
||||||
property alias fontPixelSize: inlineText.font.pixelSize
|
property alias fontPixelSize: inlineText.font.pixelSize
|
||||||
property alias fontFamily: inlineText.font.family
|
property alias fontFamily: inlineText.font.family
|
||||||
|
property bool isFontAwesomeIcon: fontFamily == FontAwesome.fontFamily || fontFamily == FontAwesome.fontFamilySolid
|
||||||
property alias buttonColor: rect.color
|
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()
|
signal clicked()
|
||||||
|
|
||||||
function doClick() {
|
function doClick() {
|
||||||
@@ -64,20 +60,16 @@ Item {
|
|||||||
|
|
||||||
Rectangle{
|
Rectangle{
|
||||||
id: rect
|
id: rect
|
||||||
|
anchors.fill: parent
|
||||||
color: MoneroComponents.Style.buttonInlineBackgroundColor
|
color: MoneroComponents.Style.buttonInlineBackgroundColor
|
||||||
height: 24
|
|
||||||
width: inlineText.text ? (inlineText.width + 16) : inlineButton.icon ? (inlineImage.width + 16) : rect.height
|
|
||||||
radius: 4
|
radius: 4
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 4
|
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
MoneroComponents.TextPlain {
|
||||||
id: inlineText
|
id: inlineText
|
||||||
font.family: MoneroComponents.Style.fontBold.name
|
font.family: MoneroComponents.Style.fontBold.name
|
||||||
font.bold: true
|
font.bold: true
|
||||||
font.pixelSize: inlineButton.fontSize
|
font.pixelSize: inlineButton.isFontAwesomeIcon ? 22 : inlineButton.small ? 14 : 16
|
||||||
color: inlineButton.textColor
|
color: inlineButton.textColor
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
@@ -90,13 +82,6 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
|
||||||
id: inlineImage
|
|
||||||
visible: inlineButton.icon !== ""
|
|
||||||
anchors.centerIn: parent
|
|
||||||
source: inlineButton.icon
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: buttonArea
|
id: buttonArea
|
||||||
cursorShape: rect.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
cursorShape: rect.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
|
|||||||
@@ -29,11 +29,15 @@
|
|||||||
import FontAwesome 1.0
|
import FontAwesome 1.0
|
||||||
import QtQuick 2.9
|
import QtQuick 2.9
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
import "../components" as MoneroComponents
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: item
|
id: item
|
||||||
|
|
||||||
|
default property alias content: inlineButtons.children
|
||||||
|
|
||||||
property alias input: input
|
property alias input: input
|
||||||
property alias text: input.text
|
property alias text: input.text
|
||||||
|
|
||||||
@@ -53,8 +57,6 @@ Item {
|
|||||||
property alias validator: input.validator
|
property alias validator: input.validator
|
||||||
property alias readOnly : input.readOnly
|
property alias readOnly : input.readOnly
|
||||||
property alias cursorPosition: input.cursorPosition
|
property alias cursorPosition: input.cursorPosition
|
||||||
property alias inlineButton: inlineButtonId
|
|
||||||
property alias inlineButtonText: inlineButtonId.text
|
|
||||||
property alias inlineIcon: inlineIcon.visible
|
property alias inlineIcon: inlineIcon.visible
|
||||||
property bool copyButton: false
|
property bool copyButton: false
|
||||||
property alias copyButtonText: copyButtonId.text
|
property alias copyButtonText: copyButtonId.text
|
||||||
@@ -239,6 +241,7 @@ Item {
|
|||||||
onEditingFinished: item.editingFinished()
|
onEditingFinished: item.editingFinished()
|
||||||
onAccepted: item.accepted();
|
onAccepted: item.accepted();
|
||||||
onTextChanged: item.textUpdated()
|
onTextChanged: item.textUpdated()
|
||||||
|
rightPadding: inlineButtons.width + 14
|
||||||
topPadding: 10
|
topPadding: 10
|
||||||
bottomPadding: 10
|
bottomPadding: 10
|
||||||
echoMode: isPasswordHidden() ? TextInput.Password : TextInput.Normal
|
echoMode: isPasswordHidden() ? TextInput.Password : TextInput.Normal
|
||||||
@@ -262,13 +265,15 @@ Item {
|
|||||||
onClicked: passwordToggle()
|
onClicked: passwordToggle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.InlineButton {
|
RowLayout {
|
||||||
id: inlineButtonId
|
id: inlineButtons
|
||||||
visible: item.inlineButtonText ? true : false
|
anchors.bottom: parent.bottom
|
||||||
anchors.right: parent.right
|
anchors.top: parent.top
|
||||||
anchors.rightMargin: 8
|
anchors.right: parent.right
|
||||||
|
anchors.margins: 4
|
||||||
|
spacing: 4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,13 +36,15 @@ ColumnLayout {
|
|||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
default property alias content: inlineButtons.children
|
||||||
|
|
||||||
property alias text: input.text
|
property alias text: input.text
|
||||||
property alias labelText: inputLabel.text
|
property alias labelText: inputLabel.text
|
||||||
property alias labelButtonText: labelButton.text
|
property alias labelButtonText: labelButton.text
|
||||||
property alias placeholderText: placeholderLabel.text
|
property alias placeholderText: placeholderLabel.text
|
||||||
|
|
||||||
property int inputPaddingLeft: 10
|
property int inputPaddingLeft: 10
|
||||||
property int inputPaddingRight: 10
|
property alias inputPaddingRight: input.rightPadding
|
||||||
property int inputPaddingTop: 10
|
property int inputPaddingTop: 10
|
||||||
property int inputPaddingBottom: 10
|
property int inputPaddingBottom: 10
|
||||||
property int inputRadius: 4
|
property int inputRadius: 4
|
||||||
@@ -85,11 +87,6 @@ ColumnLayout {
|
|||||||
property alias addressValidation: input.addressValidation
|
property alias addressValidation: input.addressValidation
|
||||||
property string backgroundColor: "" // mock
|
property string backgroundColor: "" // mock
|
||||||
|
|
||||||
property alias inlineButton: inlineButtonId
|
|
||||||
property bool inlineButtonVisible: false
|
|
||||||
property alias inlineButton2: inlineButton2Id
|
|
||||||
property bool inlineButton2Visible: false
|
|
||||||
|
|
||||||
signal labelButtonClicked();
|
signal labelButtonClicked();
|
||||||
signal inputLabelLinkActivated();
|
signal inputLabelLinkActivated();
|
||||||
signal editingFinished();
|
signal editingFinished();
|
||||||
@@ -166,7 +163,7 @@ ColumnLayout {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
leftPadding: item.inputPaddingLeft
|
leftPadding: item.inputPaddingLeft
|
||||||
rightPadding: item.inputPaddingRight
|
rightPadding: inlineButtons.width + 14
|
||||||
topPadding: item.inputPaddingTop
|
topPadding: item.inputPaddingTop
|
||||||
bottomPadding: item.inputPaddingBottom
|
bottomPadding: item.inputPaddingBottom
|
||||||
|
|
||||||
@@ -202,18 +199,12 @@ ColumnLayout {
|
|||||||
visible: !item.borderDisabled
|
visible: !item.borderDisabled
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.InlineButton {
|
RowLayout {
|
||||||
id: inlineButtonId
|
id: inlineButtons
|
||||||
visible: (inlineButtonId.text || inlineButtonId.icon) && inlineButtonVisible ? true : false
|
anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: 8
|
anchors.margins: 4
|
||||||
}
|
spacing: 4
|
||||||
|
|
||||||
MoneroComponents.InlineButton {
|
|
||||||
id: inlineButton2Id
|
|
||||||
visible: (inlineButton2Id.text || inlineButton2Id.icon) && inlineButton2Visible ? true : false
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: inlineButtonVisible ? 48 : 8
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
7
external/CMakeLists.txt
vendored
Normal file
7
external/CMakeLists.txt
vendored
Normal 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
1
external/quirc
vendored
Submodule
Submodule external/quirc added at 7e7ab596e4
@@ -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
|
; 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
|
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
|
; Mesa, open-source OpenGL implementation; part of "low-level graphics" support
|
||||||
Source: "bin\opengl32sw.dll"; DestDir: "{app}"; Flags: ignoreversion
|
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}\libhidapi-0.dll"
|
||||||
Type: files; Name: "{app}\libeay32.dll"
|
Type: files; Name: "{app}\libeay32.dll"
|
||||||
Type: files; Name: "{app}\ssleay32.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"
|
Type: files; Name: "{group}\Utilities\x (Check Blockchain Folder).lnk"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
2
monero
2
monero
Submodule monero updated: 54a4071473...8fef32e45c
@@ -314,16 +314,16 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inlineButton.text: FontAwesome.qrcode
|
MoneroComponents.InlineButton {
|
||||||
inlineButton.fontPixelSize: 22
|
buttonColor: MoneroComponents.Style.orange
|
||||||
inlineButton.fontFamily: FontAwesome.fontFamily
|
fontFamily: FontAwesome.fontFamily
|
||||||
inlineButton.textColor: MoneroComponents.Style.defaultFontColor
|
text: FontAwesome.qrcode
|
||||||
inlineButton.buttonColor: MoneroComponents.Style.orange
|
visible : appWindow.qrScannerEnabled && !addressLine.text
|
||||||
inlineButton.onClicked: {
|
onClicked: {
|
||||||
cameraUi.state = "Capture"
|
cameraUi.state = "Capture"
|
||||||
cameraUi.qrcode_decoded.connect(root.updateFromQrCode)
|
cameraUi.qrcode_decoded.connect(root.updateFromQrCode)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
inlineButtonVisible : appWindow.qrScannerEnabled && !addressLine.text
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.StandardButton {
|
MoneroComponents.StandardButton {
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ Rectangle {
|
|||||||
addressLine.text = address
|
addressLine.text = address
|
||||||
setPaymentId(payment_id);
|
setPaymentId(payment_id);
|
||||||
amountLine.text = amount
|
amountLine.text = amount
|
||||||
setDescription(recipient_name + " " + tx_description);
|
setDescription((recipient_name ? recipient_name + " " : "") + tx_description);
|
||||||
cameraUi.qrcode_decoded.disconnect(updateFromQrCode)
|
cameraUi.qrcode_decoded.disconnect(updateFromQrCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +172,6 @@ Rectangle {
|
|||||||
id: addressLine
|
id: addressLine
|
||||||
KeyNavigation.tab: amountLine
|
KeyNavigation.tab: amountLine
|
||||||
spacing: 0
|
spacing: 0
|
||||||
inputPaddingRight: inlineButtonVisible && inlineButton2Visible ? 100 : 60
|
|
||||||
fontBold: true
|
fontBold: true
|
||||||
labelText: qsTr("Address") + translationManager.emptyString
|
labelText: qsTr("Address") + translationManager.emptyString
|
||||||
labelButtonText: qsTr("Resolve") + translationManager.emptyString
|
labelButtonText: qsTr("Resolve") + translationManager.emptyString
|
||||||
@@ -196,27 +195,25 @@ Rectangle {
|
|||||||
setDescription(parsed.tx_description);
|
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
|
MoneroComponents.InlineButton {
|
||||||
inlineButton2.buttonHeight: 30
|
fontFamily: FontAwesome.fontFamily
|
||||||
inlineButton2.fontPixelSize: 22
|
text: FontAwesome.addressBook
|
||||||
inlineButton2.fontFamily: FontAwesome.fontFamily
|
onClicked: {
|
||||||
inlineButton2.textColor: MoneroComponents.Style.defaultFontColor
|
middlePanel.addressBookView.selectAndSend = true;
|
||||||
inlineButton2.onClicked: {
|
appWindow.showPageRequest("AddressBook");
|
||||||
cameraUi.state = "Capture"
|
}
|
||||||
cameraUi.qrcode_decoded.connect(updateFromQrCode)
|
}
|
||||||
}
|
|
||||||
inlineButton2Visible: appWindow.qrScannerEnabled
|
MoneroComponents.InlineButton {
|
||||||
|
fontFamily: FontAwesome.fontFamily
|
||||||
|
text: FontAwesome.qrcode
|
||||||
|
visible: appWindow.qrScannerEnabled
|
||||||
|
onClicked: {
|
||||||
|
cameraUi.state = "Capture"
|
||||||
|
cameraUi.qrcode_decoded.connect(updateFromQrCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,10 +292,8 @@ Rectangle {
|
|||||||
placeholderText: "0.00"
|
placeholderText: "0.00"
|
||||||
width: 100
|
width: 100
|
||||||
fontBold: true
|
fontBold: true
|
||||||
inlineButtonText: qsTr("All") + translationManager.emptyString
|
|
||||||
inlineButton.onClicked: amountLine.text = "(all)"
|
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
amountLine.text = amountLine.text.replace(",", ".");
|
amountLine.text = amountLine.text.trim().replace(",", ".");
|
||||||
const match = amountLine.text.match(/^0+(\d.*)/);
|
const match = amountLine.text.match(/^0+(\d.*)/);
|
||||||
if (match) {
|
if (match) {
|
||||||
const cursorPosition = amountLine.cursorPosition;
|
const cursorPosition = amountLine.cursorPosition;
|
||||||
@@ -312,10 +307,14 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
amountLine.error = walletManager.amountFromString(amountLine.text) > appWindow.getUnlockedBalance()
|
amountLine.error = walletManager.amountFromString(amountLine.text) > appWindow.getUnlockedBalance()
|
||||||
}
|
}
|
||||||
|
|
||||||
validator: RegExpValidator {
|
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 {
|
MoneroComponents.TextPlain {
|
||||||
|
|||||||
@@ -55,13 +55,6 @@ if(ENABLE_PASS_STRENGTH_METER)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_SCANNER)
|
|
||||||
file(GLOB QR_CODE_FILES
|
|
||||||
"QR-Code-scanner/*.h"
|
|
||||||
"QR-Code-scanner/*.cpp"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(EXECUTABLE_FLAG)
|
set(EXECUTABLE_FLAG)
|
||||||
if(MINGW)
|
if(MINGW)
|
||||||
set(EXECUTABLE_FLAG WIN32)
|
set(EXECUTABLE_FLAG WIN32)
|
||||||
@@ -84,7 +77,6 @@ endif()
|
|||||||
set(monero_wallet_gui_sources
|
set(monero_wallet_gui_sources
|
||||||
${SOURCE_FILES}
|
${SOURCE_FILES}
|
||||||
${PASS_STRENGTH_FILES}
|
${PASS_STRENGTH_FILES}
|
||||||
${QR_CODE_FILES}
|
|
||||||
${RESOURCES}
|
${RESOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -128,7 +120,6 @@ target_include_directories(monero-wallet-gui PUBLIC
|
|||||||
${X11_INCLUDE_DIR}
|
${X11_INCLUDE_DIR}
|
||||||
${Boost_INCLUDE_DIRS}
|
${Boost_INCLUDE_DIRS}
|
||||||
${OPENSSL_INCLUDE_DIR}
|
${OPENSSL_INCLUDE_DIR}
|
||||||
${ZBAR_INCLUDE_DIR}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_definitions(monero-wallet-gui
|
target_compile_definitions(monero-wallet-gui
|
||||||
@@ -137,6 +128,14 @@ target_compile_definitions(monero-wallet-gui
|
|||||||
${Qt5Qml_DEFINITIONS}
|
${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}")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
|
||||||
|
|
||||||
target_link_libraries(monero-wallet-gui
|
target_link_libraries(monero-wallet-gui
|
||||||
@@ -159,6 +158,7 @@ target_link_libraries(monero-wallet-gui
|
|||||||
${EXTRA_LIBRARIES}
|
${EXTRA_LIBRARIES}
|
||||||
${ICU_LIBRARIES}
|
${ICU_LIBRARIES}
|
||||||
openpgp
|
openpgp
|
||||||
|
qrdecoder
|
||||||
translations
|
translations
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -171,16 +171,14 @@ if(X11_FOUND)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_SCANNER)
|
if(WITH_SCANNER)
|
||||||
if(NOT ANDROID)
|
target_link_libraries(monero-wallet-gui qrscanner)
|
||||||
|
if(LINUX AND NOT ANDROID)
|
||||||
target_link_libraries(monero-wallet-gui
|
target_link_libraries(monero-wallet-gui
|
||||||
${ZBAR_LIBRARIES}
|
|
||||||
jpeg
|
jpeg
|
||||||
v4l2
|
v4l2
|
||||||
v4lconvert
|
v4lconvert
|
||||||
rt
|
rt
|
||||||
)
|
)
|
||||||
else()
|
|
||||||
target_link_libraries(monero-wallet-gui ${ZBAR_LIBRARIES})
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,21 @@
|
|||||||
file(GLOB_RECURSE SRC_SOURCES *.cpp)
|
add_library(qrdecoder STATIC
|
||||||
file(GLOB_RECURSE SRC_HEADERS *.h)
|
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()
|
||||||
|
|||||||
71
src/QR-Code-scanner/Decoder.cpp
Normal file
71
src/QR-Code-scanner/Decoder.cpp
Normal 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;
|
||||||
|
}
|
||||||
21
src/QR-Code-scanner/Decoder.h
Normal file
21
src/QR-Code-scanner/Decoder.h
Normal 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;
|
||||||
|
};
|
||||||
@@ -27,7 +27,6 @@
|
|||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "QrCodeScanner.h"
|
#include "QrCodeScanner.h"
|
||||||
#include <WalletManager.h>
|
|
||||||
#include <QVideoProbe>
|
#include <QVideoProbe>
|
||||||
#include <QCamera>
|
#include <QCamera>
|
||||||
|
|
||||||
@@ -40,7 +39,7 @@ QrCodeScanner::QrCodeScanner(QObject *parent)
|
|||||||
m_probe = new QVideoProbe(this);
|
m_probe = new QVideoProbe(this);
|
||||||
m_thread = new QrScanThread(this);
|
m_thread = new QrScanThread(this);
|
||||||
m_thread->start();
|
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)));
|
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)));
|
connect(m_probe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(processFrame(QVideoFrame)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,8 +56,7 @@ public Q_SLOTS:
|
|||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void enabledChanged();
|
void enabledChanged();
|
||||||
|
|
||||||
void decoded(int type, const QString &data);
|
void decoded(const QString &data);
|
||||||
void decode(int type, const QString &data);
|
|
||||||
void notifyError(const QString &error, bool warning = false);
|
void notifyError(const QString &error, bool warning = false);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -38,62 +38,15 @@ QrScanThread::QrScanThread(QObject *parent)
|
|||||||
: QThread(parent)
|
: QThread(parent)
|
||||||
,m_running(true)
|
,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)
|
void QrScanThread::processQImage(const QImage &qimg)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
m_image = QSharedPointer<zbar::Image>(new zbar::Image());
|
for (const std::string &code : m_decoder.decode(qimg))
|
||||||
if( ! zimageFromQImage(qimg, *m_image) )
|
{
|
||||||
return;
|
emit decoded(QString::fromStdString(code));
|
||||||
processZImage(*m_image);
|
}
|
||||||
}
|
}
|
||||||
catch(std::exception &e) {
|
catch(std::exception &e) {
|
||||||
qDebug() << "ERROR: " << e.what();
|
qDebug() << "ERROR: " << e.what();
|
||||||
|
|||||||
@@ -35,9 +35,10 @@
|
|||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QVideoFrame>
|
#include <QVideoFrame>
|
||||||
#include <QCamera>
|
#include <QCamera>
|
||||||
#include <zbar.h>
|
|
||||||
|
|
||||||
class QrScanThread : public QThread, public zbar::Image::Handler
|
#include "Decoder.h"
|
||||||
|
|
||||||
|
class QrScanThread : public QThread
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@@ -47,20 +48,16 @@ public:
|
|||||||
virtual void stop();
|
virtual void stop();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void decoded(int type, const QString &data);
|
void decoded(const QString &data);
|
||||||
void notifyError(const QString &error, bool warning = false);
|
void notifyError(const QString &error, bool warning = false);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void run();
|
virtual void run();
|
||||||
void processVideoFrame(const QVideoFrame &);
|
void processVideoFrame(const QVideoFrame &);
|
||||||
void processQImage(const QImage &);
|
void processQImage(const QImage &);
|
||||||
void processZImage(zbar::Image &image);
|
|
||||||
virtual void image_callback(zbar::Image &image);
|
|
||||||
bool zimageFromQImage(const QImage&, zbar::Image &);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
zbar::ImageScanner m_scanner;
|
QrDecoder m_decoder;
|
||||||
QSharedPointer<zbar::Image> m_image;
|
|
||||||
bool m_running;
|
bool m_running;
|
||||||
QMutex m_mutex;
|
QMutex m_mutex;
|
||||||
QWaitCondition m_waitCondition;
|
QWaitCondition m_waitCondition;
|
||||||
|
|||||||
@@ -81,13 +81,16 @@ ColumnLayout {
|
|||||||
placeholderText: qsTr("Default") + translationManager.emptyString
|
placeholderText: qsTr("Default") + translationManager.emptyString
|
||||||
placeholderFontSize: 15
|
placeholderFontSize: 15
|
||||||
text: persistentSettings.blockchainDataDir
|
text: persistentSettings.blockchainDataDir
|
||||||
inlineButton.small: true
|
|
||||||
inlineButtonText: qsTr("Browse") + translationManager.emptyString
|
MoneroComponents.InlineButton {
|
||||||
inlineButton.onClicked: {
|
small: true
|
||||||
if(persistentSettings.blockchainDataDir != "");
|
text: qsTr("Browse") + translationManager.emptyString
|
||||||
blockchainFileDialog.folder = "file://" + persistentSettings.blockchainDataDir;
|
onClicked: {
|
||||||
blockchainFileDialog.open();
|
if(persistentSettings.blockchainDataDir != "");
|
||||||
blockchainFolder.focus = true;
|
blockchainFileDialog.folder = "file://" + persistentSettings.blockchainDataDir;
|
||||||
|
blockchainFileDialog.open();
|
||||||
|
blockchainFolder.focus = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ Rectangle {
|
|||||||
anchors.margins: 8
|
anchors.margins: 8
|
||||||
anchors.leftMargin: 10
|
anchors.leftMargin: 10
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
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
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
visible: !seedInput.text
|
visible: !seedInput.text
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,16 +89,19 @@ GridLayout {
|
|||||||
placeholderText: "..."
|
placeholderText: "..."
|
||||||
placeholderFontSize: 16
|
placeholderFontSize: 16
|
||||||
text: appWindow.accountsDir + "/"
|
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: {
|
onTextChanged: {
|
||||||
walletLocation.error = walletLocation.text === "";
|
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 {
|
FileDialog {
|
||||||
|
|||||||
Reference in New Issue
Block a user