From 16d3db95ab9f64152af6ede88b1d725efb4258ce Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Thu, 29 Jun 2023 14:48:36 +0200 Subject: [PATCH 01/22] qt6: update android build container to bookworm --- contrib/android/Dockerfile | 2 +- contrib/android/apt.sources.list | 4 ++-- contrib/freeze_containers_distro.sh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/android/Dockerfile b/contrib/android/Dockerfile index 08e887caf..e87dca32f 100644 --- a/contrib/android/Dockerfile +++ b/contrib/android/Dockerfile @@ -1,6 +1,6 @@ # based on https://github.com/kivy/python-for-android/blob/master/Dockerfile -FROM debian:bullseye@sha256:43ef0c6c3585d5b406caa7a0f232ff5a19c1402aeb415f68bcd1cf9d10180af8 +FROM debian:bookworm@sha256:d568e251e460295a8743e9d5ef7de673c5a8f9027db11f4e666e96fb5bed708e ENV DEBIAN_FRONTEND=noninteractive diff --git a/contrib/android/apt.sources.list b/contrib/android/apt.sources.list index e8c300942..7a9bb8a98 100644 --- a/contrib/android/apt.sources.list +++ b/contrib/android/apt.sources.list @@ -1,2 +1,2 @@ -deb https://snapshot.debian.org/archive/debian/20230317T205011Z/ bullseye main -deb-src https://snapshot.debian.org/archive/debian/20230317T205011Z/ bullseye main \ No newline at end of file +deb https://snapshot.debian.org/archive/debian/20230629T090352Z/ bookworm main +deb-src https://snapshot.debian.org/archive/debian/20230629T090352Z/ bookworm main diff --git a/contrib/freeze_containers_distro.sh b/contrib/freeze_containers_distro.sh index 5566ca491..8095b2826 100755 --- a/contrib/freeze_containers_distro.sh +++ b/contrib/freeze_containers_distro.sh @@ -7,7 +7,7 @@ set -e DEBIAN_SNAPSHOT_BASE="https://snapshot.debian.org/archive/debian/" DEBIAN_APPIMAGE_DISTRO="buster" # should match build-linux/appimage Dockerfile base DEBIAN_WINE_DISTRO="bullseye" # should match build-wine Dockerfile base -DEBIAN_ANDROID_DISTRO="bullseye" # should match android Dockerfile base +DEBIAN_ANDROID_DISTRO="bookworm" # should match android Dockerfile base contrib=$(dirname "$0") From 770a32cf6a9732d8b575938799b3b1c9eb626dee Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Tue, 4 Jul 2023 20:41:48 +0200 Subject: [PATCH 02/22] qt6: update recipe pins, NDK, SDK, Ant, use venv for buildozer/p4a, add tomli recipe --- contrib/android/Dockerfile | 53 ++++++++++++------- contrib/android/build.sh | 1 - contrib/android/buildozer_qml.spec | 12 ++--- contrib/android/make_apk.sh | 10 ++-- .../android/p4a_recipes/Pillow/__init__.py | 4 +- .../android/p4a_recipes/libffi/__init__.py | 4 +- .../android/p4a_recipes/libiconv/__init__.py | 4 +- .../android/p4a_recipes/pyjnius/__init__.py | 6 +-- contrib/android/p4a_recipes/pyqt5/__init__.py | 18 ------- .../android/p4a_recipes/pyqt5sip/__init__.py | 18 ------- contrib/android/p4a_recipes/pyqt6/__init__.py | 18 +++++++ .../android/p4a_recipes/pyqt6sip/__init__.py | 18 +++++++ .../p4a_recipes/pyqt_builder/__init__.py | 4 +- contrib/android/p4a_recipes/qt5/__init__.py | 16 ------ contrib/android/p4a_recipes/qt6/__init__.py | 17 ++++++ contrib/android/p4a_recipes/sip/__init__.py | 6 +-- .../android/p4a_recipes/sqlite3/__init__.py | 4 +- contrib/android/p4a_recipes/tomli/__init__.py | 13 +++++ 18 files changed, 128 insertions(+), 98 deletions(-) delete mode 100644 contrib/android/p4a_recipes/pyqt5/__init__.py delete mode 100644 contrib/android/p4a_recipes/pyqt5sip/__init__.py create mode 100644 contrib/android/p4a_recipes/pyqt6/__init__.py create mode 100644 contrib/android/p4a_recipes/pyqt6sip/__init__.py delete mode 100644 contrib/android/p4a_recipes/qt5/__init__.py create mode 100644 contrib/android/p4a_recipes/qt6/__init__.py create mode 100644 contrib/android/p4a_recipes/tomli/__init__.py diff --git a/contrib/android/Dockerfile b/contrib/android/Dockerfile index e87dca32f..604703819 100644 --- a/contrib/android/Dockerfile +++ b/contrib/android/Dockerfile @@ -31,12 +31,12 @@ RUN apt -y update -qq \ ENV ANDROID_NDK_HOME="${ANDROID_HOME}/android-ndk" -ENV ANDROID_NDK_VERSION="22b" -ENV ANDROID_NDK_HASH="ac3a0421e76f71dd330d0cd55f9d99b9ac864c4c034fc67e0d671d022d4e806b" +ENV ANDROID_NDK_VERSION="23b" +ENV ANDROID_NDK_HASH="c6e97f9c8cfe5b7be0a9e6c15af8e7a179475b7ded23e2d1c1fa0945d6fb4382" ENV ANDROID_NDK_HOME_V="${ANDROID_NDK_HOME}-r${ANDROID_NDK_VERSION}" # get the latest version from https://developer.android.com/ndk/downloads/index.html -ENV ANDROID_NDK_ARCHIVE="android-ndk-r${ANDROID_NDK_VERSION}-linux-x86_64.zip" +ENV ANDROID_NDK_ARCHIVE="android-ndk-r${ANDROID_NDK_VERSION}-linux.zip" ENV ANDROID_NDK_DL_URL="https://dl.google.com/android/repository/${ANDROID_NDK_ARCHIVE}" # download and install Android NDK @@ -53,9 +53,8 @@ RUN curl --location --progress-bar \ ENV ANDROID_SDK_HOME="${ANDROID_HOME}/android-sdk" # get the latest version from https://developer.android.com/studio/index.html -ENV ANDROID_SDK_TOOLS_VERSION="8092744" -ENV ANDROID_SDK_BUILD_TOOLS_VERSION="30.0.3" -ENV ANDROID_SDK_HASH="d71f75333d79c9c6ef5c39d3456c6c58c613de30e6a751ea0dbd433e8f8b9cbf" +ENV ANDROID_SDK_TOOLS_VERSION="9477386" +ENV ANDROID_SDK_HASH="bd1aa17c7ef10066949c88dc6c9c8d536be27f992a1f3b5a584f9bd2ba5646a0" ENV ANDROID_SDK_TOOLS_ARCHIVE="commandlinetools-linux-${ANDROID_SDK_TOOLS_VERSION}_latest.zip" ENV ANDROID_SDK_TOOLS_DL_URL="https://dl.google.com/android/repository/${ANDROID_SDK_TOOLS_ARCHIVE}" ENV ANDROID_SDK_MANAGER="${ANDROID_SDK_HOME}/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_SDK_HOME}" @@ -77,19 +76,22 @@ RUN mkdir --parents "${ANDROID_SDK_HOME}/.android/" \ # accept Android licenses (JDK necessary!) RUN apt -y update -qq \ && apt -y install -qq --no-install-recommends --allow-downgrades \ - openjdk-11-jdk-headless \ + openjdk-17-jdk-headless \ && apt -y autoremove RUN yes | ${ANDROID_SDK_MANAGER} --licenses > /dev/null + +ENV ANDROID_SDK_BUILD_TOOLS_VERSION="31.0.0" + # download platforms, API, build tools -RUN ${ANDROID_SDK_MANAGER} "platforms;android-30" > /dev/null && \ +RUN ${ANDROID_SDK_MANAGER} "platforms;android-31" > /dev/null && \ ${ANDROID_SDK_MANAGER} "build-tools;${ANDROID_SDK_BUILD_TOOLS_VERSION}" > /dev/null && \ ${ANDROID_SDK_MANAGER} "extras;android;m2repository" > /dev/null && \ chmod +x "${ANDROID_SDK_HOME}/cmdline-tools/bin/avdmanager" # download ANT -ENV APACHE_ANT_VERSION="1.9.4" -ENV APACHE_ANT_HASH="66d3edcbb0eba11387705cd89178ffb65e55cd53f13ca35c1bb983c0f9992540" +ENV APACHE_ANT_VERSION="1.10.13" +ENV APACHE_ANT_HASH="776be4a5704158f00ef3f23c0327546e38159389bc8f39abbfe114913f88bab1" ENV APACHE_ANT_ARCHIVE="apache-ant-${APACHE_ANT_VERSION}-bin.tar.gz" ENV APACHE_ANT_DL_URL="https://archive.apache.org/dist/ant/binaries/${APACHE_ANT_ARCHIVE}" ENV APACHE_ANT_HOME="${ANDROID_HOME}/apache-ant" @@ -139,6 +141,15 @@ RUN apt -y update -qq \ && apt -y autoremove \ && apt -y clean +# cross compile deps for Qt6 +RUN apt -y update -qq \ + && apt -y install -qq --no-install-recommends --allow-downgrades \ + libopengl-dev \ + libegl-dev \ + dos2unix \ + && apt -y autoremove \ + && apt -y clean + # create new user to avoid using root; but with sudo access and no password for convenience. ARG UID=1000 @@ -154,12 +165,16 @@ RUN chown --recursive ${USER} ${WORK_DIR} ${ANDROID_SDK_HOME} RUN chown ${USER} /opt USER ${USER} +# venv, VIRTUAL_ENV is used by buildozer to indicate a venv environemnt +ENV VIRTUAL_ENV=/opt/venv +RUN python3 -m venv ${VIRTUAL_ENV} +ENV PATH="${VIRTUAL_ENV}/bin:${PATH}" COPY contrib/deterministic-build/requirements-build-base.txt /opt/deterministic-build/ COPY contrib/deterministic-build/requirements-build-android.txt /opt/deterministic-build/ -RUN python3 -m pip install --no-build-isolation --no-dependencies --user \ +RUN /opt/venv/bin/python3 -m pip install --no-build-isolation --no-dependencies \ -r /opt/deterministic-build/requirements-build-base.txt -RUN python3 -m pip install --no-build-isolation --no-dependencies --no-binary :all: --user \ +RUN /opt/venv/bin/python3 -m pip install --no-build-isolation --no-dependencies --no-binary :all: \ -r /opt/deterministic-build/requirements-build-android.txt # install buildozer @@ -168,9 +183,10 @@ RUN cd /opt \ && cd buildozer \ && git remote add sombernight https://github.com/SomberNight/buildozer \ && git fetch --all \ - # commit: from branch sombernight/electrum_20210421 (note: careful with force-pushing! see #8162) - && git checkout "6f03256e8312f8d1e5a6da3a2a1bf06e2738325e^{commit}" \ - && python3 -m pip install --no-build-isolation --no-dependencies --user -e . + # commit: from branch sombernight/electrum_20210421 (note: careful with force-pushing! see #8162) \ + # no, this is master + && git checkout "10f9c8b789f4f4cb020356bdb50607eceae10493^{commit}" \ + && /opt/venv/bin/python3 -m pip install --no-build-isolation --no-dependencies -e . # install python-for-android RUN cd /opt \ @@ -179,9 +195,10 @@ RUN cd /opt \ && git remote add sombernight https://github.com/SomberNight/python-for-android \ && git remote add accumulator https://github.com/accumulator/python-for-android \ && git fetch --all \ - # commit: from branch accumulator/electrum_20210421d (note: careful with force-pushing! see #8162) - && git checkout "052b9f7945bae557347fa4a4b418040d9da9eaff^{commit}" \ - && python3 -m pip install --no-build-isolation --no-dependencies --user -e . + # commit: from branch accumulator/electrum_20210421d (note: careful with force-pushing! see #8162) \ + # + && git checkout "710cc81d9cdcdcef910547074f031e8a3f102d63^{commit}" \ + && /opt/venv/bin/python3 -m pip install --no-build-isolation --no-dependencies -e . # build env vars ENV USE_SDK_WRAPPER=1 diff --git a/contrib/android/build.sh b/contrib/android/build.sh index 5dea8ede0..be1514ba7 100755 --- a/contrib/android/build.sh +++ b/contrib/android/build.sh @@ -48,7 +48,6 @@ docker build \ --file "$CONTRIB_ANDROID/Dockerfile" \ "$PROJECT_ROOT" - # maybe do fresh clone if [ ! -z "$ELECBUILD_COMMIT" ] ; then info "ELECBUILD_COMMIT=$ELECBUILD_COMMIT. doing fresh clone and git checkout." diff --git a/contrib/android/buildozer_qml.spec b/contrib/android/buildozer_qml.spec index 655b9ae88..111e02ce7 100644 --- a/contrib/android/buildozer_qml.spec +++ b/contrib/android/buildozer_qml.spec @@ -55,8 +55,8 @@ requirements = libffi, libsecp256k1, cryptography, - pyqt5sip, - pyqt5, + pyqt6sip, + pyqt6, pillow, libzbar @@ -84,7 +84,7 @@ android.permissions = INTERNET, CAMERA, WRITE_EXTERNAL_STORAGE # (int) Android API to use (compileSdkVersion) # note: when changing, Dockerfile also needs to be changed to install corresponding build tools -android.api = 30 +android.api = 31 # (int) Android targetSdkVersion android.target_sdk_version = 31 @@ -93,13 +93,13 @@ android.target_sdk_version = 31 android.minapi = 21 # (str) Android NDK version to use -android.ndk = 22b +android.ndk = 23b # (int) Android NDK API to use (optional). This is the minimum API your app will support. android.ndk_api = 21 # (bool) Use --private data storage (True) or --dir public storage (False) -android.private_storage = True +#android.private_storage = True # (str) Android NDK directory (if empty, it will be automatically downloaded.) android.ndk_path = /opt/android/android-ndk @@ -199,7 +199,7 @@ p4a.local_recipes = %(source.dir)s/contrib/android/p4a_recipes/ #p4a.hook = # (str) Bootstrap to use for android builds -p4a.bootstrap = qt5 +p4a.bootstrap = qt6 # (int) port number to specify an explicit --port= p4a argument (eg for bootstrap flask) #p4a.port = diff --git a/contrib/android/make_apk.sh b/contrib/android/make_apk.sh index 7f2a34890..977148bfb 100755 --- a/contrib/android/make_apk.sh +++ b/contrib/android/make_apk.sh @@ -90,16 +90,16 @@ fi if [[ "$2" == "all" ]] ; then # build all apks # FIXME failures are not propagated out: we should fail the script if any arch build fails - export APP_ANDROID_ARCH=armeabi-v7a + export APP_ANDROID_ARCHS=armeabi-v7a make $TARGET - export APP_ANDROID_ARCH=arm64-v8a + export APP_ANDROID_ARCHS=arm64-v8a make $TARGET - #export APP_ANDROID_ARCH=x86 + #export APP_ANDROID_ARCHS=x86 #make $TARGET - export APP_ANDROID_ARCH=x86_64 + export APP_ANDROID_ARCHS=x86_64 make $TARGET else - export APP_ANDROID_ARCH=$2 + export APP_ANDROID_ARCHS=$2 make $TARGET fi diff --git a/contrib/android/p4a_recipes/Pillow/__init__.py b/contrib/android/p4a_recipes/Pillow/__init__.py index a08cd3b28..fd9a91ea7 100644 --- a/contrib/android/p4a_recipes/Pillow/__init__.py +++ b/contrib/android/p4a_recipes/Pillow/__init__.py @@ -6,13 +6,13 @@ from pythonforandroid.util import load_source util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) -assert PillowRecipe._version == "7.0.0" +assert PillowRecipe._version == "8.4.0" assert PillowRecipe.depends == ['png', 'jpeg', 'freetype', 'setuptools', 'python3'] assert PillowRecipe.python_depends == [] class PillowRecipePinned(util.InheritedRecipeMixin, PillowRecipe): - sha512sum = "187173a525d4f3f01b4898633263b53a311f337aa7b159c64f79ba8c7006fd44798a058e7cc5d8f1116bad008e4142ff303456692329fe73b0e115ef5c225d73" + sha512sum = "d395f69ccb37c52a3b6f45836700ffbc3173afae31848cc61d7b47db88ca1594541023beb9a14fd9067aca664e182c7d6e3300ab3e3095c31afe8dcbc6e08233" recipe = PillowRecipePinned() diff --git a/contrib/android/p4a_recipes/libffi/__init__.py b/contrib/android/p4a_recipes/libffi/__init__.py index 4867cc031..e2aad27cb 100644 --- a/contrib/android/p4a_recipes/libffi/__init__.py +++ b/contrib/android/p4a_recipes/libffi/__init__.py @@ -6,13 +6,13 @@ from pythonforandroid.util import load_source util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) -assert LibffiRecipe._version == "v3.3" +assert LibffiRecipe._version == "v3.4.2" assert LibffiRecipe.depends == [] assert LibffiRecipe.python_depends == [] class LibffiRecipePinned(util.InheritedRecipeMixin, LibffiRecipe): - sha512sum = "62798fb31ba65fa2a0e1f71dd3daca30edcf745dc562c6f8e7126e54db92572cc63f5aa36d927dd08375bb6f38a2380ebe6c5735f35990681878fc78fc9dbc83" + sha512sum = "d399319efcca375fe901b05722e25eca31d11a4261c6a5d5079480bbc552d4e4b42de2026912689d3b2f886ebb3c8bebbea47102e38a2f6acbc526b8d5bba388" recipe = LibffiRecipePinned() diff --git a/contrib/android/p4a_recipes/libiconv/__init__.py b/contrib/android/p4a_recipes/libiconv/__init__.py index 4d0ba2f59..552f42f1c 100644 --- a/contrib/android/p4a_recipes/libiconv/__init__.py +++ b/contrib/android/p4a_recipes/libiconv/__init__.py @@ -6,13 +6,13 @@ from pythonforandroid.util import load_source util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) -assert LibIconvRecipe._version == "1.15" +assert LibIconvRecipe._version == "1.16" assert LibIconvRecipe.depends == [] assert LibIconvRecipe.python_depends == [] class LibIconvRecipePinned(util.InheritedRecipeMixin, LibIconvRecipe): - sha512sum = "1233fe3ca09341b53354fd4bfe342a7589181145a1232c9919583a8c9979636855839049f3406f253a9d9829908816bb71fd6d34dd544ba290d6f04251376b1a" + sha512sum = "365dac0b34b4255a0066e8033a8b3db4bdb94b9b57a9dca17ebf2d779139fe935caf51a465d17fd8ae229ec4b926f3f7025264f37243432075e5583925bb77b7" recipe = LibIconvRecipePinned() diff --git a/contrib/android/p4a_recipes/pyjnius/__init__.py b/contrib/android/p4a_recipes/pyjnius/__init__.py index 536cbde49..a8a415c82 100644 --- a/contrib/android/p4a_recipes/pyjnius/__init__.py +++ b/contrib/android/p4a_recipes/pyjnius/__init__.py @@ -6,13 +6,13 @@ from pythonforandroid.util import load_source util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) -assert PyjniusRecipe._version == "1.3.0" -assert PyjniusRecipe.depends == [('genericndkbuild', 'sdl2', 'qt5'), 'six', 'python3'] +assert PyjniusRecipe._version == "1.5.0" +assert PyjniusRecipe.depends == [('genericndkbuild', 'sdl2', 'qt6'), 'six', 'python3'] assert PyjniusRecipe.python_depends == [] class PyjniusRecipePinned(util.InheritedRecipeMixin, PyjniusRecipe): - sha512sum = "5a3475afcda5afbef6e1a67bab508e3c24bd564efda5ac38ae7669d39b4bfdbfaaa83f435f26d39b3d849d3a167a9c136c9ac6b2bfcc0bda09ef1c00aa66cf25" + sha512sum = "e47ff08bdcda8fc9ef9617fc84515a85404d77cfce3ede3e190ae21221837a4275840e14976271f38eb5d514682d22eab5d83d8ca94dbf3a6b47d4effa109790" recipe = PyjniusRecipePinned() diff --git a/contrib/android/p4a_recipes/pyqt5/__init__.py b/contrib/android/p4a_recipes/pyqt5/__init__.py deleted file mode 100644 index c21caaa69..000000000 --- a/contrib/android/p4a_recipes/pyqt5/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -import os - -from pythonforandroid.recipes.pyqt5 import PyQt5Recipe -from pythonforandroid.util import load_source - -util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) - - -assert PyQt5Recipe._version == "5.15.9" -assert PyQt5Recipe.depends == ['qt5', 'pyjnius', 'setuptools', 'pyqt5sip', 'hostpython3', 'pyqt_builder'] -assert PyQt5Recipe.python_depends == [] - - -class PyQt5RecipePinned(util.InheritedRecipeMixin, PyQt5Recipe): - sha512sum = "1c07d93aefe1c24e80851eb4631b80a99e7ba06e823181325456edb90285d3d22417a9f7d4c3ff9c6195bd801e7dc2bbabf0587af844a5e4b0a410c4611d119e" - - -recipe = PyQt5RecipePinned() diff --git a/contrib/android/p4a_recipes/pyqt5sip/__init__.py b/contrib/android/p4a_recipes/pyqt5sip/__init__.py deleted file mode 100644 index 8150bed4e..000000000 --- a/contrib/android/p4a_recipes/pyqt5sip/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -import os - -from pythonforandroid.recipes.pyqt5sip import PyQt5SipRecipe -from pythonforandroid.util import load_source - -util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) - - -assert PyQt5SipRecipe._version == "12.11.1" -assert PyQt5SipRecipe.depends == ['setuptools', 'python3'] -assert PyQt5SipRecipe.python_depends == [] - - -class PyQt5SipRecipePinned(util.InheritedRecipeMixin, PyQt5SipRecipe): - sha512sum = "9a24b6e8356fdb1070672ee37e5f4259d72a75bb60376ad0946274331ae29a6cceb98a6c5a278bf5e8015a3d493c925bacab8593ef02c310ff3773bd3ee46a5d" - - -recipe = PyQt5SipRecipePinned() diff --git a/contrib/android/p4a_recipes/pyqt6/__init__.py b/contrib/android/p4a_recipes/pyqt6/__init__.py new file mode 100644 index 000000000..37b2a2119 --- /dev/null +++ b/contrib/android/p4a_recipes/pyqt6/__init__.py @@ -0,0 +1,18 @@ +import os + +from pythonforandroid.recipes.pyqt6 import PyQt6Recipe +from pythonforandroid.util import load_source + +util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) + + +assert PyQt6Recipe._version == "6.4.2" +assert PyQt6Recipe.depends == ['qt6', 'pyjnius', 'setuptools', 'pyqt6sip', 'hostpython3', 'pyqt_builder'] +assert PyQt6Recipe.python_depends == [] + + +class PyQt6RecipePinned(util.InheritedRecipeMixin, PyQt6Recipe): + sha512sum = "51e5f0d028ee7984876da1653cb135d61e2c402f18b939a92477888cc7c86d3bc2889477403dee6b3d9f66519ee3236d344323493b4c2c2e658e1637b10e53bf" + + +recipe = PyQt6RecipePinned() diff --git a/contrib/android/p4a_recipes/pyqt6sip/__init__.py b/contrib/android/p4a_recipes/pyqt6sip/__init__.py new file mode 100644 index 000000000..301c15762 --- /dev/null +++ b/contrib/android/p4a_recipes/pyqt6sip/__init__.py @@ -0,0 +1,18 @@ +import os + +from pythonforandroid.recipes.pyqt6sip import PyQt6SipRecipe +from pythonforandroid.util import load_source + +util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) + + +assert PyQt6SipRecipe._version == "13.5.1" +assert PyQt6SipRecipe.depends == ['setuptools', 'python3'] +assert PyQt6SipRecipe.python_depends == [] + + +class PyQt6SipRecipePinned(util.InheritedRecipeMixin, PyQt6SipRecipe): + sha512sum = "1e4170d167a326afe6df86e4a35e209299548054981cb2e5d56da234ef9db4d8594bcb05b6be363c3bc6252776ae9de63d589a3d9f33fba8250d39cdb5e9061a" + + +recipe = PyQt6SipRecipePinned() diff --git a/contrib/android/p4a_recipes/pyqt_builder/__init__.py b/contrib/android/p4a_recipes/pyqt_builder/__init__.py index b43a1208d..6b6a67488 100644 --- a/contrib/android/p4a_recipes/pyqt_builder/__init__.py +++ b/contrib/android/p4a_recipes/pyqt_builder/__init__.py @@ -1,13 +1,13 @@ from pythonforandroid.recipes.pyqt_builder import PyQtBuilderRecipe -assert PyQtBuilderRecipe._version == "1.14.1" +assert PyQtBuilderRecipe._version == "1.15.1" assert PyQtBuilderRecipe.depends == ["sip", "packaging", "python3"] assert PyQtBuilderRecipe.python_depends == [] class PyQtBuilderRecipePinned(PyQtBuilderRecipe): - sha512sum = "4de9be2c42f38fbc22d46a31dd6da37c02620bb112a674ef846a4eb7f862715852e1d7328da1e0d0e33f78475166fe3c690e710e18bfeb48f840f137831a2182" + sha512sum = "61ee73b6bb922c04739da60025ab50d35d345d2e298943305fcbd3926cda31d732cc5e5b0dbfc39f5eb85c0f0b091b8c3f5fee00dcc240d7849c5c4191c1368a" recipe = PyQtBuilderRecipePinned() diff --git a/contrib/android/p4a_recipes/qt5/__init__.py b/contrib/android/p4a_recipes/qt5/__init__.py deleted file mode 100644 index 562b21832..000000000 --- a/contrib/android/p4a_recipes/qt5/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -import os - -from pythonforandroid.recipes.qt5 import Qt5Recipe - -from pythonforandroid.util import load_source - -util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) - -assert Qt5Recipe._version == "95254e52c658729e80f741324045034c15ce9cb0" -assert Qt5Recipe.depends == ['python3'] -assert Qt5Recipe.python_depends == [] - -class Qt5RecipePinned(util.InheritedRecipeMixin, Qt5Recipe): - pass - -recipe = Qt5RecipePinned() diff --git a/contrib/android/p4a_recipes/qt6/__init__.py b/contrib/android/p4a_recipes/qt6/__init__.py new file mode 100644 index 000000000..b5a709d5d --- /dev/null +++ b/contrib/android/p4a_recipes/qt6/__init__.py @@ -0,0 +1,17 @@ +import os + +from pythonforandroid.recipes.qt6 import Qt6Recipe + +from pythonforandroid.util import load_source + +util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) + +assert Qt6Recipe._version == "6.4.3" +assert Qt6Recipe.depends == ['python3', 'hostqt6'] +assert Qt6Recipe.python_depends == [] + +class Qt6RecipePinned(util.InheritedRecipeMixin, Qt6Recipe): + sha512sum = "767d2d388dab64ba314743841b9b2dbd68996876d15621e0ae97688e2ef1300c70f96b417bf111f119c87699a3d7014c70aec3a80b5216212bb5d35979230db7" + + +recipe = Qt6RecipePinned() diff --git a/contrib/android/p4a_recipes/sip/__init__.py b/contrib/android/p4a_recipes/sip/__init__.py index ee4f44956..d1aea65e4 100644 --- a/contrib/android/p4a_recipes/sip/__init__.py +++ b/contrib/android/p4a_recipes/sip/__init__.py @@ -1,13 +1,13 @@ from pythonforandroid.recipes.sip import SipRecipe -assert SipRecipe._version == "6.7.7" -assert SipRecipe.depends == ["setuptools", "packaging", "toml", "ply", "python3"], SipRecipe.depends +assert SipRecipe._version == "6.7.9" +assert SipRecipe.depends == ["setuptools", "packaging", "tomli", "ply", "python3"], SipRecipe.depends assert SipRecipe.python_depends == [] class SipRecipePinned(SipRecipe): - sha512sum = "b41a1e53e8bad1fca08eda2c89b8a7cabe6cb9e54d0ddeba0c718499b0288633fb6b90128d54f3df2420e20bb217d3df224750d30e865487d2b0a640fba82444" + sha512sum = "bb9d0d0d92002b6fd33f7e8ebe8cd62456dacc16b5734b73760b1ba14fb9b1f2b9b6640b40196c6cf5f345e1afde48bdef39675c4d3480041771325d4cf3c233" recipe = SipRecipePinned() diff --git a/contrib/android/p4a_recipes/sqlite3/__init__.py b/contrib/android/p4a_recipes/sqlite3/__init__.py index 70b6bd932..d7e604f46 100644 --- a/contrib/android/p4a_recipes/sqlite3/__init__.py +++ b/contrib/android/p4a_recipes/sqlite3/__init__.py @@ -6,13 +6,13 @@ from pythonforandroid.util import load_source util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) -assert Sqlite3Recipe._version == "3.34.1" +assert Sqlite3Recipe._version == "3.35.5" assert Sqlite3Recipe.depends == [] assert Sqlite3Recipe.python_depends == [] class Sqlite3RecipePinned(util.InheritedRecipeMixin, Sqlite3Recipe): - sha512sum = "8a936f1c34fc9036cadf5bd53f9ee594135c2efdef1d2c82bd4fdf3e0218afde710fc4c436cfc992687d008e6086a697da0487352ed88809d677e05d824940dd" + sha512sum = "9684fee89224f0c975c280cb6b2c64adb040334bc5517dfe0e354b0557459fa3ae642c4289a7a5265f65b3ad5b6747db8068a1e5172fbb8edec7f6d964ecbb20" recipe = Sqlite3RecipePinned() diff --git a/contrib/android/p4a_recipes/tomli/__init__.py b/contrib/android/p4a_recipes/tomli/__init__.py new file mode 100644 index 000000000..2798afd5d --- /dev/null +++ b/contrib/android/p4a_recipes/tomli/__init__.py @@ -0,0 +1,13 @@ +from pythonforandroid.recipes.tomli import TomliRecipe + + +assert TomliRecipe._version == "2.0.1" +assert TomliRecipe.depends == ["setuptools", "python3"] +assert TomliRecipe.python_depends == [] + + +class TomliRecipePinned(TomliRecipe): + sha512sum = "fd410039e255e2b3359e999d69a5a2d38b9b89b77e8557f734f2621dfbd5e1207e13aecc11589197ec22594c022f07f41b4cfe486a3a719281a595c95fd19ecf" + + +recipe = TomliRecipePinned() From bf6163b4f8b140638e4722eb1193801d5f528084 Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Fri, 7 Jul 2023 15:09:27 +0200 Subject: [PATCH 03/22] android: update p4a ref to 3b3733dbf5f461e197ba83887ac0d3b6d0f1c396 buildozer ref to 698b48136c55b2495128207c5e98dccc128bb6c2 --- contrib/android/Dockerfile | 9 +++++---- contrib/android/p4a_recipes/qt6/__init__.py | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/contrib/android/Dockerfile b/contrib/android/Dockerfile index 604703819..53db8ab67 100644 --- a/contrib/android/Dockerfile +++ b/contrib/android/Dockerfile @@ -182,10 +182,11 @@ RUN cd /opt \ && git clone https://github.com/kivy/buildozer \ && cd buildozer \ && git remote add sombernight https://github.com/SomberNight/buildozer \ + && git remote add accumulator https://github.com/accumulator/buildozer \ && git fetch --all \ - # commit: from branch sombernight/electrum_20210421 (note: careful with force-pushing! see #8162) \ + # commit: from branch master (note: careful with force-pushing! see #8162) \ # no, this is master - && git checkout "10f9c8b789f4f4cb020356bdb50607eceae10493^{commit}" \ + && git checkout "698b48136c55b2495128207c5e98dccc128bb6c2^{commit}" \ && /opt/venv/bin/python3 -m pip install --no-build-isolation --no-dependencies -e . # install python-for-android @@ -195,9 +196,9 @@ RUN cd /opt \ && git remote add sombernight https://github.com/SomberNight/python-for-android \ && git remote add accumulator https://github.com/accumulator/python-for-android \ && git fetch --all \ - # commit: from branch accumulator/electrum_20210421d (note: careful with force-pushing! see #8162) \ + # commit: from branch accumulator/qt6-wip (note: careful with force-pushing! see #8162) \ # - && git checkout "710cc81d9cdcdcef910547074f031e8a3f102d63^{commit}" \ + && git checkout "3b3733dbf5f461e197ba83887ac0d3b6d0f1c396^{commit}" \ && /opt/venv/bin/python3 -m pip install --no-build-isolation --no-dependencies -e . # build env vars diff --git a/contrib/android/p4a_recipes/qt6/__init__.py b/contrib/android/p4a_recipes/qt6/__init__.py index b5a709d5d..312f459b3 100644 --- a/contrib/android/p4a_recipes/qt6/__init__.py +++ b/contrib/android/p4a_recipes/qt6/__init__.py @@ -11,7 +11,7 @@ assert Qt6Recipe.depends == ['python3', 'hostqt6'] assert Qt6Recipe.python_depends == [] class Qt6RecipePinned(util.InheritedRecipeMixin, Qt6Recipe): - sha512sum = "767d2d388dab64ba314743841b9b2dbd68996876d15621e0ae97688e2ef1300c70f96b417bf111f119c87699a3d7014c70aec3a80b5216212bb5d35979230db7" + sha512sum = "0bdbe8b9a43390c98cf19e851ec5394bc78438d227cf9d0d7a3748aee9a32a7f14fc46f52d4fa283819f21413567080aee7225c566af5278557f5e1992674da3" recipe = Qt6RecipePinned() From 0441cb0ad5bf4eecadc729afdcf43ceb89171719 Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Thu, 6 Jul 2023 20:32:17 +0200 Subject: [PATCH 04/22] qml: exclude payserver plugin for qml --- contrib/android/buildozer_qml.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/android/buildozer_qml.spec b/contrib/android/buildozer_qml.spec index 111e02ce7..2f85c3eb0 100644 --- a/contrib/android/buildozer_qml.spec +++ b/contrib/android/buildozer_qml.spec @@ -24,6 +24,7 @@ source.exclude_dirs = bin, build, dist, contrib, env, electrum/www, electrum/gui/qt, electrum/gui/kivy, + electrum/plugins/payserver, packages/qdarkstyle, packages/qtpy, packages/bin, From 6270eae5c9dcc32868e74f25bb0c7d903dab2a29 Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Fri, 14 Jul 2023 13:51:08 +0200 Subject: [PATCH 05/22] qml: port PyQt5 to PyQt6 --- electrum/gui/common_qt/plugins.py | 2 +- electrum/gui/default_lang.py | 2 +- electrum/gui/qml/__init__.py | 25 +++---- electrum/gui/qml/auth.py | 2 +- electrum/gui/qml/components/Constants.qml | 6 +- electrum/gui/qml/components/Wallets.qml | 7 +- .../controls/HistoryItemDelegate.qml | 2 +- .../components/controls/InvoiceDelegate.qml | 4 +- .../OnchainNetworkStatusIndicator.qml | 4 +- .../gui/qml/components/controls/QRScan.qml | 62 +++++++++------- electrum/gui/qml/components/main.qml | 71 ++++++++++--------- electrum/gui/qml/qeaddressdetails.py | 2 +- electrum/gui/qml/qeaddresslistmodel.py | 8 +-- electrum/gui/qml/qeapp.py | 37 +++++++--- electrum/gui/qml/qebip39recovery.py | 14 ++-- electrum/gui/qml/qebitcoin.py | 2 +- electrum/gui/qml/qechanneldetails.py | 8 +-- electrum/gui/qml/qechannellistmodel.py | 8 +-- electrum/gui/qml/qechannelopener.py | 2 +- electrum/gui/qml/qeconfig.py | 2 +- electrum/gui/qml/qedaemon.py | 8 +-- electrum/gui/qml/qefx.py | 2 +- electrum/gui/qml/qeinvoice.py | 12 ++-- electrum/gui/qml/qeinvoicelistmodel.py | 8 +-- electrum/gui/qml/qelnpaymentdetails.py | 2 +- electrum/gui/qml/qemodelfilter.py | 2 +- electrum/gui/qml/qenetwork.py | 2 +- electrum/gui/qml/qeqr.py | 8 +-- electrum/gui/qml/qerequestdetails.py | 8 +-- electrum/gui/qml/qeserverlistmodel.py | 8 +-- electrum/gui/qml/qeswaphelper.py | 8 +-- electrum/gui/qml/qetransactionlistmodel.py | 8 +-- electrum/gui/qml/qetxdetails.py | 2 +- electrum/gui/qml/qetxfinalizer.py | 2 +- electrum/gui/qml/qetypes.py | 2 +- electrum/gui/qml/qewallet.py | 2 +- electrum/gui/qml/qewizard.py | 2 +- electrum/gui/qml/util.py | 2 +- electrum/plugins/labels/qml.py | 2 +- electrum/plugins/trustedcoin/common_qt.py | 2 +- electrum/plugins/trustedcoin/qml.py | 1 + 41 files changed, 200 insertions(+), 163 deletions(-) diff --git a/electrum/gui/common_qt/plugins.py b/electrum/gui/common_qt/plugins.py index ba2189dd2..3403be027 100644 --- a/electrum/gui/common_qt/plugins.py +++ b/electrum/gui/common_qt/plugins.py @@ -1,4 +1,4 @@ -from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject +from PyQt6.QtCore import pyqtSignal, pyqtProperty, QObject # TODO: common code, Qt5/Qt6 mismatch! from electrum.logging import get_logger diff --git a/electrum/gui/default_lang.py b/electrum/gui/default_lang.py index e8a3e9b8e..aacf8112f 100644 --- a/electrum/gui/default_lang.py +++ b/electrum/gui/default_lang.py @@ -24,7 +24,7 @@ def get_default_language(*, gui_name: Optional[str] = None) -> str: name = QLocale.system().name() return name if name in languages else "en_UK" elif gui_name == "qml": - from PyQt5.QtCore import QLocale + from PyQt6.QtCore import QLocale # On Android QLocale does not return the system locale try: name = str(jLocale.getDefault().toString()) diff --git a/electrum/gui/qml/__init__.py b/electrum/gui/qml/__init__.py index 68c2ca40c..08894eb67 100644 --- a/electrum/gui/qml/__init__.py +++ b/electrum/gui/qml/__init__.py @@ -5,17 +5,17 @@ import threading from typing import TYPE_CHECKING try: - import PyQt5 + import PyQt6 except Exception: - sys.exit("Error: Could not import PyQt5 on Linux systems, you may try 'sudo apt-get install python3-pyqt5'") + sys.exit("Error: Could not import PyQt6 on Linux systems, you may try 'sudo apt-get install python3-pyqt6'") try: - import PyQt5.QtQml + import PyQt6.QtQml except Exception: - sys.exit("Error: Could not import PyQt5.QtQml on Linux systems, you may try 'sudo apt-get install python3-pyqt5.qtquick'") + sys.exit("Error: Could not import PyQt6.QtQml on Linux systems, you may try 'sudo apt-get install python3-pyqt6.qtquick'") -from PyQt5.QtCore import (Qt, QCoreApplication, QLocale, QTranslator, QTimer, QT_VERSION_STR, PYQT_VERSION_STR) -from PyQt5.QtGui import QGuiApplication +from PyQt6.QtCore import (Qt, QCoreApplication, QLocale, QTranslator, QTimer, QT_VERSION_STR, PYQT_VERSION_STR) +from PyQt6.QtGui import QGuiApplication from electrum.i18n import _ from electrum.plugin import run_hook @@ -40,7 +40,6 @@ class ElectrumTranslator(QTranslator): class ElectrumGui(BaseElectrumGui, Logger): - @profiler def __init__(self, config: 'SimpleConfig', daemon: 'Daemon', plugins: 'Plugins'): BaseElectrumGui.__init__(self, config=config, daemon=daemon, plugins=plugins) @@ -63,13 +62,11 @@ class ElectrumGui(BaseElectrumGui, Logger): # GC-ed when windows are closed #network.add_jobs([DebugMem([Abstract_Wallet, SPV, Synchronizer, # ElectrumWindow], interval=5)]) - QCoreApplication.setAttribute(Qt.AA_X11InitThreads) + if hasattr(Qt, "AA_ShareOpenGLContexts"): QCoreApplication.setAttribute(Qt.AA_ShareOpenGLContexts) if hasattr(QGuiApplication, 'setDesktopFileName'): QGuiApplication.setDesktopFileName('electrum.desktop') - if hasattr(Qt, "AA_EnableHighDpiScaling"): - QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) if "QT_QUICK_CONTROLS_STYLE" not in os.environ: os.environ["QT_QUICK_CONTROLS_STYLE"] = "Material" @@ -100,10 +97,14 @@ class ElectrumGui(BaseElectrumGui, Logger): return self.timer.start() - signal.signal(signal.SIGINT, lambda *args: self.stop()) + signal.signal(signal.SIGINT, lambda *args: self._handle_sigint()) self.logger.info('Entering main loop') - self.app.exec_() + self.app.exec() + + def _handle_sigint(self): + self.app.appController.wantClose = True + self.stop() def stop(self): self.logger.info('closing GUI') diff --git a/electrum/gui/qml/auth.py b/electrum/gui/qml/auth.py index 137e0fd31..3a7500815 100644 --- a/electrum/gui/qml/auth.py +++ b/electrum/gui/qml/auth.py @@ -1,6 +1,6 @@ from functools import wraps, partial -from PyQt5.QtCore import pyqtSignal, pyqtSlot +from PyQt6.QtCore import pyqtSignal, pyqtSlot from electrum.logging import get_logger diff --git a/electrum/gui/qml/components/Constants.qml b/electrum/gui/qml/components/Constants.qml index a701a9f1d..b9bdac1ff 100644 --- a/electrum/gui/qml/components/Constants.qml +++ b/electrum/gui/qml/components/Constants.qml @@ -1,8 +1,8 @@ -import QtQuick 2.6 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material Item { - readonly property int paddingTiny: 4 //deprecated readonly property int paddingXXSmall: 4 readonly property int paddingXSmall: 6 readonly property int paddingSmall: 8 diff --git a/electrum/gui/qml/components/Wallets.qml b/electrum/gui/qml/components/Wallets.qml index b8dcf5f18..da762a1e3 100644 --- a/electrum/gui/qml/components/Wallets.qml +++ b/electrum/gui/qml/components/Wallets.qml @@ -27,12 +27,11 @@ Pane { ColumnLayout { id: rootLayout - width: parent.width - height: parent.height + anchors.fill: parent spacing: 0 ColumnLayout { - Layout.preferredWidth: parent.width + Layout.fillWidth: true Layout.margins: constants.paddingLarge Heading { @@ -41,7 +40,7 @@ Pane { Frame { id: detailsFrame - Layout.preferredWidth: parent.width + Layout.fillWidth: true Layout.fillHeight: true verticalPadding: 0 horizontalPadding: 0 diff --git a/electrum/gui/qml/components/controls/HistoryItemDelegate.qml b/electrum/gui/qml/components/controls/HistoryItemDelegate.qml index 3eec740b3..9d230536d 100644 --- a/electrum/gui/qml/components/controls/HistoryItemDelegate.qml +++ b/electrum/gui/qml/components/controls/HistoryItemDelegate.qml @@ -121,7 +121,7 @@ Item { visible: delegate.ListView.section == delegate.ListView.nextSection Layout.preferredWidth: parent.width * 2/3 Layout.alignment: Qt.AlignHCenter - Layout.preferredHeight: constants.paddingTiny + Layout.preferredHeight: constants.paddingXXSmall color: Material.background } diff --git a/electrum/gui/qml/components/controls/InvoiceDelegate.qml b/electrum/gui/qml/components/controls/InvoiceDelegate.qml index 18b3055d1..7ff214f68 100644 --- a/electrum/gui/qml/components/controls/InvoiceDelegate.qml +++ b/electrum/gui/qml/components/controls/InvoiceDelegate.qml @@ -31,7 +31,7 @@ ItemDelegate { Rectangle { Layout.columnSpan: 2 Layout.fillWidth: true - Layout.preferredHeight: constants.paddingTiny + Layout.preferredHeight: constants.paddingXXSmall color: 'transparent' } @@ -133,7 +133,7 @@ ItemDelegate { Rectangle { Layout.columnSpan: 2 Layout.fillWidth: true - Layout.preferredHeight: constants.paddingTiny + Layout.preferredHeight: constants.paddingXXSmall color: 'transparent' } diff --git a/electrum/gui/qml/components/controls/OnchainNetworkStatusIndicator.qml b/electrum/gui/qml/components/controls/OnchainNetworkStatusIndicator.qml index 7a575f4f4..739ef2ab3 100644 --- a/electrum/gui/qml/components/controls/OnchainNetworkStatusIndicator.qml +++ b/electrum/gui/qml/components/controls/OnchainNetworkStatusIndicator.qml @@ -13,7 +13,7 @@ Image { property bool proxy: connected && 'mode' in Network.proxy && Network.proxy.mode // ?: in order to keep this a binding.. - source: !connected + source: Qt.resolvedUrl(!connected ? '../../../icons/status_disconnected.png' : syncing ? '../../../icons/status_waiting.png' @@ -27,7 +27,7 @@ Image { : '../../../icons/status_connected_fork.png' : proxy ? '../../../icons/status_connected_proxy.png' - : '../../../icons/status_connected.png' + : '../../../icons/status_connected.png') states: [ diff --git a/electrum/gui/qml/components/controls/QRScan.qml b/electrum/gui/qml/components/controls/QRScan.qml index 75f8224c4..2ca1fbabe 100644 --- a/electrum/gui/qml/components/controls/QRScan.qml +++ b/electrum/gui/qml/components/controls/QRScan.qml @@ -1,6 +1,6 @@ import QtQuick 2.12 import QtQuick.Controls 2.0 -import QtMultimedia 5.6 +import QtMultimedia import org.electrum 1.0 @@ -25,7 +25,7 @@ Item { VideoOutput { id: vo anchors.fill: parent - source: camera + // source: camera fillMode: VideoOutput.PreserveAspectCrop Rectangle { @@ -114,31 +114,41 @@ Item { } } - Camera { - id: camera - deviceId: QtMultimedia.defaultCamera.deviceId - viewfinder.resolution: "640x480" - - focus { - focusMode: Camera.FocusContinuous - focusPointMode: Camera.FocusPointCustom - customFocusPoint: Qt.point(0.5, 0.5) - } + MediaDevices { + id: mediaDevices + } - function dumpstats() { - console.log(camera.viewfinder.resolution) - console.log(camera.viewfinder.minimumFrameRate) - console.log(camera.viewfinder.maximumFrameRate) - var resolutions = camera.supportedViewfinderResolutions() - resolutions.forEach(function(item, i) { - console.log('' + item.width + 'x' + item.height) - }) - // TODO - // pick a suitable resolution from the available resolutions - // problem: some cameras have no supportedViewfinderResolutions - // but still error out when an invalid resolution is set. - // 640x480 seems to be universally available, but this needs to - // be checked across a range of phone models. + CaptureSession { + videoOutput: VideoOutput + + camera: Camera { + id: camera + // deviceId: QtMultimedia.defaultCamera.deviceId + cameraDevice: mediaDevices.defaultVideoInput + // TODO QT6 + // viewfinder.resolution: "640x480" + + // focus { + // focusMode: Camera.FocusContinuous + // focusPointMode: Camera.FocusPointCustom + // customFocusPoint: Qt.point(0.5, 0.5) + // } + + function dumpstats() { + console.log(camera.viewfinder.resolution) + console.log(camera.viewfinder.minimumFrameRate) + console.log(camera.viewfinder.maximumFrameRate) + var resolutions = camera.supportedViewfinderResolutions() + resolutions.forEach(function(item, i) { + console.log('' + item.width + 'x' + item.height) + }) + // TODO + // pick a suitable resolution from the available resolutions + // problem: some cameras have no supportedViewfinderResolutions + // but still error out when an invalid resolution is set. + // 640x480 seems to be universally available, but this needs to + // be checked across a range of phone models. + } } } diff --git a/electrum/gui/qml/components/main.qml b/electrum/gui/qml/components/main.qml index fd2e59653..69f13da86 100644 --- a/electrum/gui/qml/components/main.qml +++ b/electrum/gui/qml/components/main.qml @@ -1,12 +1,13 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.12 -import QtQuick.Window 2.15 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Basic +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl +import QtQuick.Window -import QtQml 2.6 -import QtMultimedia 5.6 +import QtQml +import QtMultimedia import org.electrum 1.0 @@ -27,14 +28,13 @@ ApplicationWindow Material.accent: Material.LightBlue font.pixelSize: constants.fontSizeMedium - property Item constants: appconstants + property QtObject constants: appconstants Constants { id: appconstants } property alias stack: mainStackView property variant activeDialogs: [] - property bool _wantClose: false property var _exceptionDialog property QtObject appMenu: Menu { @@ -105,7 +105,8 @@ ApplicationWindow ColumnLayout { spacing: 0 - width: parent.width + anchors.left: parent.left + anchors.right: parent.right height: toolbar.height RowLayout { @@ -171,7 +172,6 @@ ApplicationWindow RowLayout { id: statusIconsLayout anchors.verticalCenter: parent.verticalCenter - Item { Layout.preferredWidth: constants.paddingLarge Layout.preferredHeight: 1 @@ -207,9 +207,12 @@ ApplicationWindow } } - WalletSummary { - id: walletSummary - Layout.preferredWidth: app.width + // hack to force relayout of toolbar + // since qt6 watchOnlyIndicator.visible doesn't trigger relayout(?) + Item { + Layout.preferredHeight: 1 + Layout.topMargin: -1 + Layout.preferredWidth: watchOnlyIndicator.visible ? app.width : 1 } } } @@ -218,7 +221,9 @@ ApplicationWindow id: mainStackView width: parent.width height: keyboardFreeZone.height - header.height - initialItem: Qt.resolvedUrl('WalletMainView.qml') + initialItem: Component { + WalletMainView {} + } function getRoot() { return mainStackView.get(0) @@ -454,7 +459,13 @@ ApplicationWindow } } - onClosing: { + onClosing: (close) => { + if (AppController.wantClose) { + // destroy most GUI components so that we don't dump so many null reference warnings on exit + app.header.visible = false + mainStackView.clear() + return + } if (activeDialogs.length > 0) { var activeDialog = activeDialogs[activeDialogs.length - 1] if (activeDialog.allowClose) { @@ -469,22 +480,16 @@ ApplicationWindow close.accepted = false stack.pop() } else { - // destroy most GUI components so that we don't dump so many null reference warnings on exit - if (app._wantClose) { - app.header.visible = false - mainStackView.clear() - } else { - var dialog = app.messageDialog.createObject(app, { - title: qsTr('Close Electrum?'), - yesno: true - }) - dialog.accepted.connect(function() { - app._wantClose = true - app.close() - }) - dialog.open() - close.accepted = false - } + var dialog = app.messageDialog.createObject(app, { + title: qsTr('Close Electrum?'), + yesno: true + }) + dialog.accepted.connect(function() { + AppController.wantClose = true + app.close() + }) + dialog.open() + close.accepted = false } } diff --git a/electrum/gui/qml/qeaddressdetails.py b/electrum/gui/qml/qeaddressdetails.py index f09cbb630..1c399cddc 100644 --- a/electrum/gui/qml/qeaddressdetails.py +++ b/electrum/gui/qml/qeaddressdetails.py @@ -1,4 +1,4 @@ -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.logging import get_logger diff --git a/electrum/gui/qml/qeaddresslistmodel.py b/electrum/gui/qml/qeaddresslistmodel.py index d87b027ee..3fee9350b 100644 --- a/electrum/gui/qml/qeaddresslistmodel.py +++ b/electrum/gui/qml/qeaddresslistmodel.py @@ -1,7 +1,7 @@ from typing import TYPE_CHECKING, List -from PyQt5.QtCore import pyqtSlot, QSortFilterProxyModel, pyqtSignal, pyqtProperty -from PyQt5.QtCore import Qt, QAbstractListModel, QModelIndex +from PyQt6.QtCore import pyqtSlot, QSortFilterProxyModel, pyqtSignal, pyqtProperty +from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex from electrum.logging import get_logger from electrum.util import Satoshis @@ -107,7 +107,7 @@ class QEAddressCoinListModel(QAbstractListModel): # define listmodel rolemap _ROLE_NAMES=('type', 'addridx', 'address', 'label', 'balance', 'numtx', 'held', 'height', 'amount', 'outpoint', 'short_outpoint', 'short_id', 'txid') - _ROLE_KEYS = range(Qt.UserRole, Qt.UserRole + len(_ROLE_NAMES)) + _ROLE_KEYS = range(Qt.ItemDataRole.UserRole, Qt.ItemDataRole.UserRole + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) _ROLE_RMAP = dict(zip(_ROLE_NAMES, _ROLE_KEYS)) @@ -128,7 +128,7 @@ class QEAddressCoinListModel(QAbstractListModel): def data(self, index, role): address = self._items[index.row()] - role_index = role - Qt.UserRole + role_index = role - Qt.ItemDataRole.UserRole try: value = address[self._ROLE_NAMES[role_index]] except KeyError: diff --git a/electrum/gui/qml/qeapp.py b/electrum/gui/qml/qeapp.py index a28522f3e..37805f340 100644 --- a/electrum/gui/qml/qeapp.py +++ b/electrum/gui/qml/qeapp.py @@ -7,10 +7,10 @@ import html import threading from typing import TYPE_CHECKING, Set -from PyQt5.QtCore import (pyqtSlot, pyqtSignal, pyqtProperty, QObject, +from PyQt6.QtCore import (pyqtSlot, pyqtSignal, pyqtProperty, QObject, qInstallMessageHandler, QTimer, QSortFilterProxyModel) -from PyQt5.QtGui import QGuiApplication, QFontDatabase -from PyQt5.QtQml import qmlRegisterType, qmlRegisterUncreatableType, QQmlApplicationEngine +from PyQt6.QtGui import QGuiApplication, QFontDatabase +from PyQt6.QtQml import qmlRegisterType, qmlRegisterUncreatableType, QQmlApplicationEngine from electrum import version, constants from electrum.i18n import _ @@ -69,6 +69,7 @@ class QEAppController(BaseCrashReporter, QObject): sendingBugreportSuccess = pyqtSignal(str) sendingBugreportFailure = pyqtSignal(str) secureWindowChanged = pyqtSignal() + wantCloseChanged = pyqtSignal() def __init__(self, qeapp: 'ElectrumQmlApplication', qedaemon: 'QEDaemon', plugins: 'Plugins'): BaseCrashReporter.__init__(self, None, None, None) @@ -100,6 +101,8 @@ class QEAppController(BaseCrashReporter, QObject): if self.isAndroid(): self.bindIntent() + self._want_close = False + def on_wallet_loaded(self): qewallet = self._qedaemon.currentWallet if not qewallet: @@ -179,6 +182,16 @@ class QEAppController(BaseCrashReporter, QObject): if self._intent: self.on_new_intent(self._intent) + @pyqtProperty(bool, notify=wantCloseChanged) + def wantClose(self): + return self._want_close + + @wantClose.setter + def wantClose(self, want_close): + if want_close != self._want_close: + self._want_close = want_close + self.wantCloseChanged.emit() + @pyqtSlot(str, str) def doShare(self, data, title): if not self.isAndroid(): @@ -330,6 +343,13 @@ class ElectrumQmlApplication(QGuiApplication): ElectrumQmlApplication._daemon = daemon + # TODO QT6 order of declaration is important now? + qmlRegisterType(QEAmount, 'org.electrum', 1, 0, 'Amount') + qmlRegisterType(QENewWalletWizard, 'org.electrum', 1, 0, 'QNewWalletWizard') + qmlRegisterType(QEServerConnectWizard, 'org.electrum', 1, 0, 'QServerConnectWizard') + qmlRegisterType(QEFilterProxyModel, 'org.electrum', 1, 0, 'FilterProxyModel') + qmlRegisterType(QSortFilterProxyModel, 'org.electrum', 1, 0, 'QSortFilterProxyModel') + qmlRegisterType(QEWallet, 'org.electrum', 1, 0, 'Wallet') qmlRegisterType(QEBitcoin, 'org.electrum', 1, 0, 'Bitcoin') qmlRegisterType(QEQRParser, 'org.electrum', 1, 0, 'QRParser') @@ -349,11 +369,12 @@ class ElectrumQmlApplication(QGuiApplication): qmlRegisterType(QETxCanceller, 'org.electrum', 1, 0, 'TxCanceller') qmlRegisterType(QEBip39RecoveryListModel, 'org.electrum', 1, 0, 'Bip39RecoveryListModel') - qmlRegisterUncreatableType(QEAmount, 'org.electrum', 1, 0, 'Amount', 'Amount can only be used as property') - qmlRegisterUncreatableType(QENewWalletWizard, 'org.electrum', 1, 0, 'QNewWalletWizard', 'QNewWalletWizard can only be used as property') - qmlRegisterUncreatableType(QEServerConnectWizard, 'org.electrum', 1, 0, 'QServerConnectWizard', 'QServerConnectWizard can only be used as property') - qmlRegisterUncreatableType(QEFilterProxyModel, 'org.electrum', 1, 0, 'FilterProxyModel', 'FilterProxyModel can only be used as property') - qmlRegisterUncreatableType(QSortFilterProxyModel, 'org.electrum', 1, 0, 'QSortFilterProxyModel', 'QSortFilterProxyModel can only be used as property') + # TODO QT6 + # qmlRegisterUncreatableType(QEAmount, 'org.electrum', 1, 0, 'Amount', 'Amount can only be used as property') + # qmlRegisterUncreatableType(QENewWalletWizard, 'org.electrum', 1, 0, 'QNewWalletWizard', 'QNewWalletWizard can only be used as property') + # qmlRegisterUncreatableType(QEServerConnectWizard, 'org.electrum', 1, 0, 'QServerConnectWizard', 'QServerConnectWizard can only be used as property') + # qmlRegisterUncreatableType(QEFilterProxyModel, 'org.electrum', 1, 0, 'FilterProxyModel', 'FilterProxyModel can only be used as property') + # qmlRegisterUncreatableType(QSortFilterProxyModel, 'org.electrum', 1, 0, 'QSortFilterProxyModel', 'QSortFilterProxyModel can only be used as property') self.engine = QQmlApplicationEngine(parent=self) diff --git a/electrum/gui/qml/qebip39recovery.py b/electrum/gui/qml/qebip39recovery.py index 713bfad27..90d1831f8 100644 --- a/electrum/gui/qml/qebip39recovery.py +++ b/electrum/gui/qml/qebip39recovery.py @@ -1,8 +1,9 @@ import asyncio import concurrent +from enum import IntEnum -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot -from PyQt5.QtCore import Qt, QAbstractListModel, QModelIndex, Q_ENUMS +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, pyqtEnum +from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex from electrum import Network, keystore from electrum.bip32 import BIP32Node @@ -15,21 +16,20 @@ from .util import TaskThread class QEBip39RecoveryListModel(QAbstractListModel): _logger = get_logger(__name__) - class State: + @pyqtEnum + class State(IntEnum): Idle = -1 Scanning = 0 Success = 1 Failed = 2 Cancelled = 3 - Q_ENUMS(State) - recoveryFailed = pyqtSignal() stateChanged = pyqtSignal() # define listmodel rolemap _ROLE_NAMES=('description', 'derivation_path', 'script_type') - _ROLE_KEYS = range(Qt.UserRole, Qt.UserRole + len(_ROLE_NAMES)) + _ROLE_KEYS = range(Qt.ItemDataRole.UserRole, Qt.ItemDataRole.UserRole + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) def __init__(self, config, parent=None): @@ -47,7 +47,7 @@ class QEBip39RecoveryListModel(QAbstractListModel): def data(self, index, role): account = self._accounts[index.row()] - role_index = role - Qt.UserRole + role_index = role - Qt.ItemDataRole.UserRole value = account[self._ROLE_NAMES[role_index]] if isinstance(value, (bool, list, int, str)) or value is None: return value diff --git a/electrum/gui/qml/qebitcoin.py b/electrum/gui/qml/qebitcoin.py index f63e752fd..3c4b2264b 100644 --- a/electrum/gui/qml/qebitcoin.py +++ b/electrum/gui/qml/qebitcoin.py @@ -1,6 +1,6 @@ import asyncio -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum import mnemonic from electrum import keystore diff --git a/electrum/gui/qml/qechanneldetails.py b/electrum/gui/qml/qechanneldetails.py index 58d5857e7..cf1adb97d 100644 --- a/electrum/gui/qml/qechanneldetails.py +++ b/electrum/gui/qml/qechanneldetails.py @@ -1,6 +1,7 @@ import threading +from enum import IntEnum -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, Q_ENUMS +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, pyqtEnum from electrum.i18n import _ from electrum.gui import messages @@ -17,12 +18,11 @@ from .util import QtEventListener, event_listener class QEChannelDetails(AuthMixin, QObject, QtEventListener): _logger = get_logger(__name__) - class State: # subset, only ones we currently need in UI + @pyqtEnum + class State(IntEnum): # subset, only ones we currently need in UI Closed = ChannelState.CLOSED Redeemed = ChannelState.REDEEMED - Q_ENUMS(State) - channelChanged = pyqtSignal() channelCloseSuccess = pyqtSignal() channelCloseFailed = pyqtSignal([str], arguments=['message']) diff --git a/electrum/gui/qml/qechannellistmodel.py b/electrum/gui/qml/qechannellistmodel.py index ccf69ef28..b3bf4586e 100644 --- a/electrum/gui/qml/qechannellistmodel.py +++ b/electrum/gui/qml/qechannellistmodel.py @@ -1,5 +1,5 @@ -from PyQt5.QtCore import Qt, QAbstractListModel, QModelIndex -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot +from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot from electrum.lnchannel import ChannelState from electrum.lnutil import LOCAL, REMOTE @@ -20,7 +20,7 @@ class QEChannelListModel(QAbstractListModel, QtEventListener): 'can_receive', 'l_csv_delay', 'r_csv_delay', 'send_frozen', 'receive_frozen', 'type', 'node_id', 'node_alias', 'short_cid', 'funding_tx', 'is_trampoline', 'is_backup', 'is_imported', 'local_capacity', 'remote_capacity') - _ROLE_KEYS = range(Qt.UserRole, Qt.UserRole + len(_ROLE_NAMES)) + _ROLE_KEYS = range(Qt.ItemDataRole.UserRole, Qt.ItemDataRole.UserRole + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) _ROLE_RMAP = dict(zip(_ROLE_NAMES, _ROLE_KEYS)) @@ -70,7 +70,7 @@ class QEChannelListModel(QAbstractListModel, QtEventListener): def data(self, index, role): tx = self._channels[index.row()] - role_index = role - Qt.UserRole + role_index = role - Qt.ItemDataRole.UserRole value = tx[self._ROLE_NAMES[role_index]] if isinstance(value, (bool, list, int, str, QEAmount)) or value is None: return value diff --git a/electrum/gui/qml/qechannelopener.py b/electrum/gui/qml/qechannelopener.py index f8f6f7231..d5c2fd327 100644 --- a/electrum/gui/qml/qechannelopener.py +++ b/electrum/gui/qml/qechannelopener.py @@ -3,7 +3,7 @@ from concurrent.futures import CancelledError from asyncio.exceptions import TimeoutError from typing import TYPE_CHECKING, Optional -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.i18n import _ from electrum.gui import messages diff --git a/electrum/gui/qml/qeconfig.py b/electrum/gui/qml/qeconfig.py index c34796e27..99ebc1d41 100644 --- a/electrum/gui/qml/qeconfig.py +++ b/electrum/gui/qml/qeconfig.py @@ -2,7 +2,7 @@ import copy from decimal import Decimal from typing import TYPE_CHECKING -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRegularExpression +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRegularExpression from electrum.bitcoin import TOTAL_COIN_SUPPLY_LIMIT_IN_BTC from electrum.i18n import set_language, languages diff --git a/electrum/gui/qml/qedaemon.py b/electrum/gui/qml/qedaemon.py index cc448171e..6b44933cc 100644 --- a/electrum/gui/qml/qedaemon.py +++ b/electrum/gui/qml/qedaemon.py @@ -3,8 +3,8 @@ import os import threading from typing import TYPE_CHECKING -from PyQt5.QtCore import Qt, QAbstractListModel, QModelIndex -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.i18n import _ from electrum.logging import get_logger @@ -32,7 +32,7 @@ class QEWalletListModel(QAbstractListModel): # define listmodel rolemap _ROLE_NAMES= ('name', 'path', 'active') - _ROLE_KEYS = range(Qt.UserRole, Qt.UserRole + len(_ROLE_NAMES)) + _ROLE_KEYS = range(Qt.ItemDataRole.UserRole, Qt.ItemDataRole.UserRole + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) def __init__(self, daemon, parent=None): @@ -49,7 +49,7 @@ class QEWalletListModel(QAbstractListModel): def data(self, index, role): (wallet_name, wallet_path) = self._wallets[index.row()] - role_index = role - Qt.UserRole + role_index = role - Qt.ItemDataRole.UserRole role_name = self._ROLE_NAMES[role_index] if role_name == 'name': return wallet_name diff --git a/electrum/gui/qml/qefx.py b/electrum/gui/qml/qefx.py index 22e1ecbaa..fcb7316da 100644 --- a/electrum/gui/qml/qefx.py +++ b/electrum/gui/qml/qefx.py @@ -1,7 +1,7 @@ from datetime import datetime from decimal import Decimal -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRegularExpression +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRegularExpression from electrum.bitcoin import COIN from electrum.exchange_rate import FxThread diff --git a/electrum/gui/qml/qeinvoice.py b/electrum/gui/qml/qeinvoice.py index 3a4d9df47..6d1580a0a 100644 --- a/electrum/gui/qml/qeinvoice.py +++ b/electrum/gui/qml/qeinvoice.py @@ -1,7 +1,8 @@ +from enum import IntEnum from typing import Optional, Dict, Any from urllib.parse import urlparse -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, Q_ENUMS, QTimer +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, pyqtEnum, QTimer from electrum.i18n import _ from electrum.logging import get_logger @@ -18,13 +19,15 @@ from .util import status_update_timer_interval, QtEventListener, event_listener class QEInvoice(QObject, QtEventListener): - class Type: + @pyqtEnum + class Type(IntEnum): Invalid = -1 OnchainInvoice = 0 LightningInvoice = 1 LNURLPayRequest = 2 - class Status: + @pyqtEnum + class Status(IntEnum): Unpaid = PR_UNPAID Expired = PR_EXPIRED Unknown = PR_UNKNOWN @@ -34,9 +37,6 @@ class QEInvoice(QObject, QtEventListener): Routing = PR_ROUTING Unconfirmed = PR_UNCONFIRMED - Q_ENUMS(Type) - Q_ENUMS(Status) - _logger = get_logger(__name__) invoiceChanged = pyqtSignal() diff --git a/electrum/gui/qml/qeinvoicelistmodel.py b/electrum/gui/qml/qeinvoicelistmodel.py index d946cb97f..e97611e0d 100644 --- a/electrum/gui/qml/qeinvoicelistmodel.py +++ b/electrum/gui/qml/qeinvoicelistmodel.py @@ -1,8 +1,8 @@ from abc import abstractmethod from typing import TYPE_CHECKING, List, Dict, Any -from PyQt5.QtCore import pyqtSlot, QTimer -from PyQt5.QtCore import Qt, QAbstractListModel, QModelIndex +from PyQt6.QtCore import pyqtSlot, QTimer +from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex from electrum.logging import get_logger from electrum.util import Satoshis, format_time @@ -22,7 +22,7 @@ class QEAbstractInvoiceListModel(QAbstractListModel): _ROLE_NAMES=('key', 'is_lightning', 'timestamp', 'date', 'message', 'amount', 'status', 'status_str', 'address', 'expiry', 'type', 'onchain_fallback', 'lightning_invoice') - _ROLE_KEYS = range(Qt.UserRole, Qt.UserRole + len(_ROLE_NAMES)) + _ROLE_KEYS = range(Qt.ItemDataRole.UserRole, Qt.ItemDataRole.UserRole + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) _ROLE_RMAP = dict(zip(_ROLE_NAMES, _ROLE_KEYS)) @@ -49,7 +49,7 @@ class QEAbstractInvoiceListModel(QAbstractListModel): def data(self, index, role): invoice = self._invoices[index.row()] - role_index = role - Qt.UserRole + role_index = role - Qt.ItemDataRole.UserRole value = invoice[self._ROLE_NAMES[role_index]] if isinstance(value, (bool, list, int, str, QEAmount)) or value is None: diff --git a/electrum/gui/qml/qelnpaymentdetails.py b/electrum/gui/qml/qelnpaymentdetails.py index 545f7877c..190a0ef06 100644 --- a/electrum/gui/qml/qelnpaymentdetails.py +++ b/electrum/gui/qml/qelnpaymentdetails.py @@ -1,4 +1,4 @@ -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.logging import get_logger from electrum.util import bfh, format_time diff --git a/electrum/gui/qml/qemodelfilter.py b/electrum/gui/qml/qemodelfilter.py index d5bd75af2..e6bbcdaad 100644 --- a/electrum/gui/qml/qemodelfilter.py +++ b/electrum/gui/qml/qemodelfilter.py @@ -1,4 +1,4 @@ -from PyQt5.QtCore import pyqtSignal, pyqtProperty, QSortFilterProxyModel, QModelIndex, pyqtSlot +from PyQt6.QtCore import pyqtSignal, pyqtProperty, QSortFilterProxyModel, QModelIndex, pyqtSlot from electrum.logging import get_logger diff --git a/electrum/gui/qml/qenetwork.py b/electrum/gui/qml/qenetwork.py index 1cfeb3c58..93d9db7af 100644 --- a/electrum/gui/qml/qenetwork.py +++ b/electrum/gui/qml/qenetwork.py @@ -1,6 +1,6 @@ from typing import TYPE_CHECKING -from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, QObject from electrum.logging import get_logger from electrum import constants diff --git a/electrum/gui/qml/qeqr.py b/electrum/gui/qml/qeqr.py index 1eaa90306..a102461bd 100644 --- a/electrum/gui/qml/qeqr.py +++ b/electrum/gui/qml/qeqr.py @@ -7,9 +7,9 @@ import urllib from PIL import Image, ImageQt -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRect, QPoint -from PyQt5.QtGui import QImage, QColor -from PyQt5.QtQuick import QQuickImageProvider +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRect, QPoint +from PyQt6.QtGui import QImage, QColor +from PyQt6.QtQuick import QQuickImageProvider from electrum.logging import get_logger from electrum.qrreader import get_qr_reader @@ -123,7 +123,7 @@ class QEQRParser(QObject): class QEQRImageProvider(QQuickImageProvider): def __init__(self, max_size, parent=None): - super().__init__(QQuickImageProvider.Image) + super().__init__(QQuickImageProvider.ImageType.Image) self._max_size = max_size self.qimg = None diff --git a/electrum/gui/qml/qerequestdetails.py b/electrum/gui/qml/qerequestdetails.py index 9d07d54e1..ef259ec2a 100644 --- a/electrum/gui/qml/qerequestdetails.py +++ b/electrum/gui/qml/qerequestdetails.py @@ -1,6 +1,7 @@ +from enum import IntEnum from typing import Optional -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, Q_ENUMS +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, pyqtEnum from electrum.logging import get_logger from electrum.invoices import (PR_UNPAID, PR_EXPIRED, PR_UNKNOWN, PR_PAID, PR_INFLIGHT, @@ -13,7 +14,8 @@ from .util import QtEventListener, event_listener, status_update_timer_interval class QERequestDetails(QObject, QtEventListener): - class Status: + @pyqtEnum + class Status(IntEnum): Unpaid = PR_UNPAID Expired = PR_EXPIRED Unknown = PR_UNKNOWN @@ -23,8 +25,6 @@ class QERequestDetails(QObject, QtEventListener): Routing = PR_ROUTING Unconfirmed = PR_UNCONFIRMED - Q_ENUMS(Status) - _logger = get_logger(__name__) detailsChanged = pyqtSignal() # generic request properties changed signal diff --git a/electrum/gui/qml/qeserverlistmodel.py b/electrum/gui/qml/qeserverlistmodel.py index 040c0efea..4863a3789 100644 --- a/electrum/gui/qml/qeserverlistmodel.py +++ b/electrum/gui/qml/qeserverlistmodel.py @@ -1,5 +1,5 @@ -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot -from PyQt5.QtCore import Qt, QAbstractListModel, QModelIndex +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot +from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex from electrum.logging import get_logger from electrum.util import Satoshis @@ -14,7 +14,7 @@ class QEServerListModel(QAbstractListModel, QtEventListener): # define listmodel rolemap _ROLE_NAMES=('name', 'address', 'is_connected', 'is_primary', 'is_tor', 'chain', 'height') - _ROLE_KEYS = range(Qt.UserRole, Qt.UserRole + len(_ROLE_NAMES)) + _ROLE_KEYS = range(Qt.ItemDataRole.UserRole, Qt.ItemDataRole.UserRole + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) _ROLE_RMAP = dict(zip(_ROLE_NAMES, _ROLE_KEYS)) @@ -52,7 +52,7 @@ class QEServerListModel(QAbstractListModel, QtEventListener): def data(self, index, role): server = self._servers[index.row()] - role_index = role - Qt.UserRole + role_index = role - Qt.ItemDataRole.UserRole value = server[self._ROLE_NAMES[role_index]] if isinstance(value, (bool, list, int, str)) or value is None: diff --git a/electrum/gui/qml/qeswaphelper.py b/electrum/gui/qml/qeswaphelper.py index 846401fcb..78c4b0f04 100644 --- a/electrum/gui/qml/qeswaphelper.py +++ b/electrum/gui/qml/qeswaphelper.py @@ -1,9 +1,10 @@ import asyncio import concurrent import threading +from enum import IntEnum from typing import Union -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, Q_ENUMS +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, pyqtEnum from electrum.i18n import _ from electrum.bitcoin import DummyAddress @@ -23,7 +24,8 @@ class InvalidSwapParameters(Exception): pass class QESwapHelper(AuthMixin, QObject, QtEventListener): _logger = get_logger(__name__) - class State: + @pyqtEnum + class State(IntEnum): Initialized = 0 ServiceReady = 1 Started = 2 @@ -31,8 +33,6 @@ class QESwapHelper(AuthMixin, QObject, QtEventListener): Success = 4 Cancelled = 5 - Q_ENUMS(State) - confirm = pyqtSignal([str], arguments=['message']) error = pyqtSignal([str], arguments=['message']) diff --git a/electrum/gui/qml/qetransactionlistmodel.py b/electrum/gui/qml/qetransactionlistmodel.py index 3ecb40e7c..52250c8d4 100644 --- a/electrum/gui/qml/qetransactionlistmodel.py +++ b/electrum/gui/qml/qetransactionlistmodel.py @@ -1,8 +1,8 @@ from datetime import datetime, timedelta from typing import TYPE_CHECKING, Dict, Any -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot -from PyQt5.QtCore import Qt, QAbstractListModel, QModelIndex +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot +from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex from electrum.logging import get_logger from electrum.util import Satoshis, TxMinedInfo @@ -22,7 +22,7 @@ class QETransactionListModel(QAbstractListModel, QtEventListener): _ROLE_NAMES=('txid', 'fee_sat', 'height', 'confirmations', 'timestamp', 'monotonic_timestamp', 'incoming', 'value', 'date', 'label', 'txpos_in_block', 'fee', 'inputs', 'outputs', 'section', 'type', 'lightning', 'payment_hash', 'key', 'complete') - _ROLE_KEYS = range(Qt.UserRole, Qt.UserRole + len(_ROLE_NAMES)) + _ROLE_KEYS = range(Qt.ItemDataRole.UserRole, Qt.ItemDataRole.UserRole + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) _ROLE_RMAP = dict(zip(_ROLE_NAMES, _ROLE_KEYS)) @@ -95,7 +95,7 @@ class QETransactionListModel(QAbstractListModel, QtEventListener): def data(self, index, role): tx = self.tx_history[index.row()] - role_index = role - Qt.UserRole + role_index = role - Qt.ItemDataRole.UserRole try: value = tx[self._ROLE_NAMES[role_index]] diff --git a/electrum/gui/qml/qetxdetails.py b/electrum/gui/qml/qetxdetails.py index 26c71e35a..c2e7775da 100644 --- a/electrum/gui/qml/qetxdetails.py +++ b/electrum/gui/qml/qetxdetails.py @@ -1,6 +1,6 @@ from typing import Optional -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.i18n import _ from electrum.logging import get_logger diff --git a/electrum/gui/qml/qetxfinalizer.py b/electrum/gui/qml/qetxfinalizer.py index 6e2fd3f3d..e4d12ef6c 100644 --- a/electrum/gui/qml/qetxfinalizer.py +++ b/electrum/gui/qml/qetxfinalizer.py @@ -2,7 +2,7 @@ from decimal import Decimal from typing import Optional, TYPE_CHECKING from functools import partial -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.logging import get_logger from electrum.i18n import _ diff --git a/electrum/gui/qml/qetypes.py b/electrum/gui/qml/qetypes.py index d787b6e93..84a9056c7 100644 --- a/electrum/gui/qml/qetypes.py +++ b/electrum/gui/qml/qetypes.py @@ -1,4 +1,4 @@ -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.logging import get_logger from electrum.i18n import _ diff --git a/electrum/gui/qml/qewallet.py b/electrum/gui/qml/qewallet.py index f21985384..12f714b7c 100644 --- a/electrum/gui/qml/qewallet.py +++ b/electrum/gui/qml/qewallet.py @@ -6,7 +6,7 @@ import time from typing import TYPE_CHECKING, Callable from functools import partial -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer from electrum.i18n import _ from electrum.invoices import InvoiceError, PR_PAID, PR_BROADCASTING, PR_BROADCAST diff --git a/electrum/gui/qml/qewizard.py b/electrum/gui/qml/qewizard.py index e9aa95107..3bd12fb21 100644 --- a/electrum/gui/qml/qewizard.py +++ b/electrum/gui/qml/qewizard.py @@ -1,7 +1,7 @@ import os from typing import TYPE_CHECKING -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.logging import get_logger from electrum import mnemonic diff --git a/electrum/gui/qml/util.py b/electrum/gui/qml/util.py index 7d3442eeb..bebc62320 100644 --- a/electrum/gui/qml/util.py +++ b/electrum/gui/qml/util.py @@ -5,7 +5,7 @@ from functools import wraps from time import time from typing import Callable, Optional, NamedTuple -from PyQt5.QtCore import pyqtSignal, QThread +from PyQt6.QtCore import pyqtSignal, QThread from electrum.logging import Logger from electrum.util import EventListener, event_listener diff --git a/electrum/plugins/labels/qml.py b/electrum/plugins/labels/qml.py index ffd970fdb..b6045d8a0 100644 --- a/electrum/plugins/labels/qml.py +++ b/electrum/plugins/labels/qml.py @@ -1,6 +1,6 @@ import threading -from PyQt5.QtCore import pyqtSignal, pyqtSlot +from PyQt6.QtCore import pyqtSignal, pyqtSlot from electrum.i18n import _ from electrum.plugin import hook diff --git a/electrum/plugins/trustedcoin/common_qt.py b/electrum/plugins/trustedcoin/common_qt.py index 1638666ef..c960d5240 100644 --- a/electrum/plugins/trustedcoin/common_qt.py +++ b/electrum/plugins/trustedcoin/common_qt.py @@ -3,7 +3,7 @@ import socket import base64 from typing import TYPE_CHECKING -from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot +from PyQt6.QtCore import pyqtSignal, pyqtProperty, pyqtSlot # TODO: common code, Qt5/Qt6 mismatch! from electrum.i18n import _ from electrum.bip32 import BIP32Node diff --git a/electrum/plugins/trustedcoin/qml.py b/electrum/plugins/trustedcoin/qml.py index 56a03b401..00c44fc16 100644 --- a/electrum/plugins/trustedcoin/qml.py +++ b/electrum/plugins/trustedcoin/qml.py @@ -15,6 +15,7 @@ if TYPE_CHECKING: from electrum.wizard import NewWalletWizard + class Plugin(TrustedCoinPlugin): def __init__(self, *args): From 8b567ae4476a74d7bfcb51598bf4dfe82188cb31 Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Mon, 17 Jul 2023 10:49:06 +0200 Subject: [PATCH 06/22] qml: remove all QML imports version numbers --- electrum/gui/qml/components/About.qml | 8 ++++---- electrum/gui/qml/components/AddressDetails.qml | 8 ++++---- electrum/gui/qml/components/Addresses.qml | 10 +++++----- electrum/gui/qml/components/BIP39RecoveryDialog.qml | 8 ++++---- electrum/gui/qml/components/BalanceDetails.qml | 8 ++++---- electrum/gui/qml/components/ChannelBackups.qml | 8 ++++---- electrum/gui/qml/components/ChannelDetails.qml | 8 ++++---- .../gui/qml/components/ChannelOpenProgressDialog.qml | 8 ++++---- electrum/gui/qml/components/Channels.qml | 8 ++++---- electrum/gui/qml/components/CloseChannelDialog.qml | 8 ++++---- electrum/gui/qml/components/ConfirmTxDialog.qml | 8 ++++---- electrum/gui/qml/components/CpfpBumpFeeDialog.qml | 8 ++++---- electrum/gui/qml/components/ExceptionDialog.qml | 10 +++++----- electrum/gui/qml/components/ExportTxDialog.qml | 8 ++++---- electrum/gui/qml/components/GenericShareDialog.qml | 8 ++++---- electrum/gui/qml/components/History.qml | 10 +++++----- .../gui/qml/components/ImportAddressesKeysDialog.qml | 6 +++--- .../gui/qml/components/ImportChannelBackupDialog.qml | 6 +++--- electrum/gui/qml/components/InvoiceDialog.qml | 8 ++++---- electrum/gui/qml/components/Invoices.qml | 12 ++++++------ .../gui/qml/components/LightningPaymentDetails.qml | 8 ++++---- .../components/LightningPaymentProgressDialog.qml | 8 ++++---- .../gui/qml/components/LnurlPayRequestDialog.qml | 8 ++++---- electrum/gui/qml/components/LoadingWalletDialog.qml | 8 ++++---- electrum/gui/qml/components/MessageDialog.qml | 8 ++++---- electrum/gui/qml/components/NetworkOverview.qml | 8 ++++---- electrum/gui/qml/components/NewWalletWizard.qml | 6 +++--- electrum/gui/qml/components/NotificationPopup.qml | 10 +++++----- electrum/gui/qml/components/OpenChannelDialog.qml | 8 ++++---- electrum/gui/qml/components/OpenWalletDialog.qml | 8 ++++---- electrum/gui/qml/components/OtpDialog.qml | 8 ++++---- electrum/gui/qml/components/PasswordDialog.qml | 8 ++++---- electrum/gui/qml/components/Pin.qml | 8 ++++---- electrum/gui/qml/components/Preferences.qml | 8 ++++---- electrum/gui/qml/components/ProxyConfigDialog.qml | 8 ++++---- electrum/gui/qml/components/RbfBumpFeeDialog.qml | 8 ++++---- electrum/gui/qml/components/RbfCancelDialog.qml | 8 ++++---- electrum/gui/qml/components/ReceiveDetailsDialog.qml | 10 +++++----- electrum/gui/qml/components/ReceiveDialog.qml | 10 +++++----- electrum/gui/qml/components/ReceiveRequests.qml | 12 ++++++------ electrum/gui/qml/components/ScanDialog.qml | 6 +++--- electrum/gui/qml/components/SendDialog.qml | 8 ++++---- electrum/gui/qml/components/ServerConfigDialog.qml | 8 ++++---- electrum/gui/qml/components/ServerConnectWizard.qml | 6 +++--- .../gui/qml/components/SignVerifyMessageDialog.qml | 8 ++++---- electrum/gui/qml/components/SwapDialog.qml | 8 ++++---- electrum/gui/qml/components/TxDetails.qml | 8 ++++---- electrum/gui/qml/components/WalletDetails.qml | 8 ++++---- electrum/gui/qml/components/WalletMainView.qml | 10 +++++----- electrum/gui/qml/components/WalletSummary.qml | 8 ++++---- electrum/gui/qml/components/Wallets.qml | 8 ++++---- .../gui/qml/components/controls/AddressDelegate.qml | 8 ++++---- .../gui/qml/components/controls/BalanceSummary.qml | 8 ++++---- electrum/gui/qml/components/controls/BtcField.qml | 4 ++-- .../gui/qml/components/controls/ButtonContainer.qml | 8 ++++---- electrum/gui/qml/components/controls/ChannelBar.qml | 8 ++++---- .../gui/qml/components/controls/ChannelDelegate.qml | 8 ++++---- electrum/gui/qml/components/controls/ElComboBox.qml | 4 ++-- electrum/gui/qml/components/controls/ElDialog.qml | 8 ++++---- .../qml/components/controls/FeeMethodComboBox.qml | 4 ++-- electrum/gui/qml/components/controls/FiatField.qml | 4 ++-- electrum/gui/qml/components/controls/FlatButton.qml | 10 +++++----- .../gui/qml/components/controls/FormattedAmount.qml | 8 ++++---- electrum/gui/qml/components/controls/Heading.qml | 6 +++--- .../qml/components/controls/HistoryItemDelegate.qml | 8 ++++---- .../gui/qml/components/controls/InfoTextArea.qml | 8 ++++---- .../gui/qml/components/controls/InvoiceDelegate.qml | 8 ++++---- .../controls/LightningNetworkStatusIndicator.qml | 2 +- .../controls/OnchainNetworkStatusIndicator.qml | 2 +- .../qml/components/controls/PaneInsetBackground.qml | 4 ++-- .../gui/qml/components/controls/PasswordField.qml | 6 +++--- electrum/gui/qml/components/controls/Piechart.qml | 2 +- .../gui/qml/components/controls/PrefsHeading.qml | 6 +++--- electrum/gui/qml/components/controls/ProxyConfig.qml | 6 +++--- electrum/gui/qml/components/controls/QRImage.qml | 4 ++-- electrum/gui/qml/components/controls/QRScan.qml | 4 ++-- .../components/controls/RequestExpiryComboBox.qml | 4 ++-- .../gui/qml/components/controls/SeedKeyboard.qml | 8 ++++---- .../gui/qml/components/controls/SeedKeyboardKey.qml | 8 ++++---- .../gui/qml/components/controls/SeedTextArea.qml | 8 ++++---- .../gui/qml/components/controls/ServerConfig.qml | 8 ++++---- .../gui/qml/components/controls/ServerDelegate.qml | 8 ++++---- electrum/gui/qml/components/controls/Tag.qml | 8 ++++---- .../qml/components/controls/TextHighlightPane.qml | 8 ++++---- electrum/gui/qml/components/controls/Toaster.qml | 8 ++++---- electrum/gui/qml/components/controls/TxOutput.qml | 8 ++++---- electrum/gui/qml/components/wizard/WCAutoConnect.qml | 6 +++--- electrum/gui/qml/components/wizard/WCConfirmSeed.qml | 6 +++--- .../gui/qml/components/wizard/WCCosignerKeystore.qml | 8 ++++---- electrum/gui/qml/components/wizard/WCCreateSeed.qml | 6 +++--- .../gui/qml/components/wizard/WCHaveMasterKey.qml | 8 ++++---- electrum/gui/qml/components/wizard/WCHaveSeed.qml | 8 ++++---- electrum/gui/qml/components/wizard/WCImport.qml | 6 +++--- .../gui/qml/components/wizard/WCKeystoreType.qml | 6 +++--- electrum/gui/qml/components/wizard/WCMultisig.qml | 6 +++--- electrum/gui/qml/components/wizard/WCProxyAsk.qml | 8 ++++---- electrum/gui/qml/components/wizard/WCProxyConfig.qml | 6 +++--- .../qml/components/wizard/WCScriptAndDerivation.qml | 8 ++++---- .../gui/qml/components/wizard/WCServerConfig.qml | 6 +++--- .../gui/qml/components/wizard/WCShowMasterPubkey.qml | 6 +++--- electrum/gui/qml/components/wizard/WCWalletName.qml | 6 +++--- .../gui/qml/components/wizard/WCWalletPassword.qml | 6 +++--- electrum/gui/qml/components/wizard/WCWalletType.qml | 6 +++--- electrum/gui/qml/components/wizard/Wizard.qml | 6 +++--- .../gui/qml/components/wizard/WizardComponent.qml | 6 +++--- 105 files changed, 384 insertions(+), 384 deletions(-) diff --git a/electrum/gui/qml/components/About.qml b/electrum/gui/qml/components/About.qml index 18d5e0c9d..60f14126f 100644 --- a/electrum/gui/qml/components/About.qml +++ b/electrum/gui/qml/components/About.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material Pane { objectName: 'About' diff --git a/electrum/gui/qml/components/AddressDetails.qml b/electrum/gui/qml/components/AddressDetails.qml index f2537532d..8cbbb2230 100644 --- a/electrum/gui/qml/components/AddressDetails.qml +++ b/electrum/gui/qml/components/AddressDetails.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/Addresses.qml b/electrum/gui/qml/components/Addresses.qml index 8bc9eaaed..26e5b2158 100644 --- a/electrum/gui/qml/components/Addresses.qml +++ b/electrum/gui/qml/components/Addresses.qml @@ -1,8 +1,8 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Material 2.0 -import QtQml.Models 2.2 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQml.Models import org.electrum 1.0 diff --git a/electrum/gui/qml/components/BIP39RecoveryDialog.qml b/electrum/gui/qml/components/BIP39RecoveryDialog.qml index 89b23061d..cda047a78 100644 --- a/electrum/gui/qml/components/BIP39RecoveryDialog.qml +++ b/electrum/gui/qml/components/BIP39RecoveryDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/BalanceDetails.qml b/electrum/gui/qml/components/BalanceDetails.qml index accd6d7c6..6da321b35 100644 --- a/electrum/gui/qml/components/BalanceDetails.qml +++ b/electrum/gui/qml/components/BalanceDetails.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/ChannelBackups.qml b/electrum/gui/qml/components/ChannelBackups.qml index 73003a77a..1291b6939 100644 --- a/electrum/gui/qml/components/ChannelBackups.qml +++ b/electrum/gui/qml/components/ChannelBackups.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/ChannelDetails.qml b/electrum/gui/qml/components/ChannelDetails.qml index e2b2ee060..242321d55 100644 --- a/electrum/gui/qml/components/ChannelDetails.qml +++ b/electrum/gui/qml/components/ChannelDetails.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/ChannelOpenProgressDialog.qml b/electrum/gui/qml/components/ChannelOpenProgressDialog.qml index 199b4cdd0..6179dd4c0 100644 --- a/electrum/gui/qml/components/ChannelOpenProgressDialog.qml +++ b/electrum/gui/qml/components/ChannelOpenProgressDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/Channels.qml b/electrum/gui/qml/components/Channels.qml index 522c2229b..1faed65c5 100644 --- a/electrum/gui/qml/components/Channels.qml +++ b/electrum/gui/qml/components/Channels.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/CloseChannelDialog.qml b/electrum/gui/qml/components/CloseChannelDialog.qml index 9231db77e..f05e710e6 100644 --- a/electrum/gui/qml/components/CloseChannelDialog.qml +++ b/electrum/gui/qml/components/CloseChannelDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/ConfirmTxDialog.qml b/electrum/gui/qml/components/ConfirmTxDialog.qml index 14fcc3a38..cecf21fec 100644 --- a/electrum/gui/qml/components/ConfirmTxDialog.qml +++ b/electrum/gui/qml/components/ConfirmTxDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/CpfpBumpFeeDialog.qml b/electrum/gui/qml/components/CpfpBumpFeeDialog.qml index a7a8a34a0..35db7132a 100644 --- a/electrum/gui/qml/components/CpfpBumpFeeDialog.qml +++ b/electrum/gui/qml/components/CpfpBumpFeeDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/ExceptionDialog.qml b/electrum/gui/qml/components/ExceptionDialog.qml index 5c325f2f6..e445f559d 100644 --- a/electrum/gui/qml/components/ExceptionDialog.qml +++ b/electrum/gui/qml/components/ExceptionDialog.qml @@ -1,9 +1,9 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material -import QtQml 2.6 +import QtQml import "controls" diff --git a/electrum/gui/qml/components/ExportTxDialog.qml b/electrum/gui/qml/components/ExportTxDialog.qml index 63c362e92..4b770dfea 100644 --- a/electrum/gui/qml/components/ExportTxDialog.qml +++ b/electrum/gui/qml/components/ExportTxDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import "controls" diff --git a/electrum/gui/qml/components/GenericShareDialog.qml b/electrum/gui/qml/components/GenericShareDialog.qml index 423d6819c..b68837aef 100644 --- a/electrum/gui/qml/components/GenericShareDialog.qml +++ b/electrum/gui/qml/components/GenericShareDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import "controls" diff --git a/electrum/gui/qml/components/History.qml b/electrum/gui/qml/components/History.qml index c1e9bd73e..7aded966f 100644 --- a/electrum/gui/qml/components/History.qml +++ b/electrum/gui/qml/components/History.qml @@ -1,8 +1,8 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Material 2.0 -import QtQml.Models 2.2 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQml.Models import org.electrum 1.0 diff --git a/electrum/gui/qml/components/ImportAddressesKeysDialog.qml b/electrum/gui/qml/components/ImportAddressesKeysDialog.qml index 09cdfb7af..7ed2f6f2a 100644 --- a/electrum/gui/qml/components/ImportAddressesKeysDialog.qml +++ b/electrum/gui/qml/components/ImportAddressesKeysDialog.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import org.electrum 1.0 diff --git a/electrum/gui/qml/components/ImportChannelBackupDialog.qml b/electrum/gui/qml/components/ImportChannelBackupDialog.qml index 709022d31..3a86360ac 100644 --- a/electrum/gui/qml/components/ImportChannelBackupDialog.qml +++ b/electrum/gui/qml/components/ImportChannelBackupDialog.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import org.electrum 1.0 diff --git a/electrum/gui/qml/components/InvoiceDialog.qml b/electrum/gui/qml/components/InvoiceDialog.qml index 48f9c1a83..8c5467f93 100644 --- a/electrum/gui/qml/components/InvoiceDialog.qml +++ b/electrum/gui/qml/components/InvoiceDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.12 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/Invoices.qml b/electrum/gui/qml/components/Invoices.qml index 5403a7baa..e57223fd9 100644 --- a/electrum/gui/qml/components/Invoices.qml +++ b/electrum/gui/qml/components/Invoices.qml @@ -1,9 +1,9 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 -import QtQml.Models 2.1 -import QtQml 2.6 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQml.Models +import QtQml import "controls" diff --git a/electrum/gui/qml/components/LightningPaymentDetails.qml b/electrum/gui/qml/components/LightningPaymentDetails.qml index e3b15db71..beef2a5af 100644 --- a/electrum/gui/qml/components/LightningPaymentDetails.qml +++ b/electrum/gui/qml/components/LightningPaymentDetails.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/LightningPaymentProgressDialog.qml b/electrum/gui/qml/components/LightningPaymentProgressDialog.qml index db771afdf..1f82380a0 100644 --- a/electrum/gui/qml/components/LightningPaymentProgressDialog.qml +++ b/electrum/gui/qml/components/LightningPaymentProgressDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/LnurlPayRequestDialog.qml b/electrum/gui/qml/components/LnurlPayRequestDialog.qml index c920f71cd..974fd1818 100644 --- a/electrum/gui/qml/components/LnurlPayRequestDialog.qml +++ b/electrum/gui/qml/components/LnurlPayRequestDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/LoadingWalletDialog.qml b/electrum/gui/qml/components/LoadingWalletDialog.qml index ee2ac8c98..f40327f1d 100644 --- a/electrum/gui/qml/components/LoadingWalletDialog.qml +++ b/electrum/gui/qml/components/LoadingWalletDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/MessageDialog.qml b/electrum/gui/qml/components/MessageDialog.qml index 91f3721e2..e80d4bb88 100644 --- a/electrum/gui/qml/components/MessageDialog.qml +++ b/electrum/gui/qml/components/MessageDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import "controls" diff --git a/electrum/gui/qml/components/NetworkOverview.qml b/electrum/gui/qml/components/NetworkOverview.qml index f30fcb747..b690da12b 100644 --- a/electrum/gui/qml/components/NetworkOverview.qml +++ b/electrum/gui/qml/components/NetworkOverview.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import "controls" diff --git a/electrum/gui/qml/components/NewWalletWizard.qml b/electrum/gui/qml/components/NewWalletWizard.qml index e7f5e53d3..1bd7158fa 100644 --- a/electrum/gui/qml/components/NewWalletWizard.qml +++ b/electrum/gui/qml/components/NewWalletWizard.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import org.electrum 1.0 diff --git a/electrum/gui/qml/components/NotificationPopup.qml b/electrum/gui/qml/components/NotificationPopup.qml index 543268042..a455a5dc2 100644 --- a/electrum/gui/qml/components/NotificationPopup.qml +++ b/electrum/gui/qml/components/NotificationPopup.qml @@ -1,8 +1,8 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.12 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl Item { id: root diff --git a/electrum/gui/qml/components/OpenChannelDialog.qml b/electrum/gui/qml/components/OpenChannelDialog.qml index 63b293119..1ec3a61dd 100644 --- a/electrum/gui/qml/components/OpenChannelDialog.qml +++ b/electrum/gui/qml/components/OpenChannelDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/OpenWalletDialog.qml b/electrum/gui/qml/components/OpenWalletDialog.qml index f177d4b71..f248c61c0 100644 --- a/electrum/gui/qml/components/OpenWalletDialog.qml +++ b/electrum/gui/qml/components/OpenWalletDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/OtpDialog.qml b/electrum/gui/qml/components/OtpDialog.qml index feb961d4e..cfd80bda0 100644 --- a/electrum/gui/qml/components/OtpDialog.qml +++ b/electrum/gui/qml/components/OtpDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/PasswordDialog.qml b/electrum/gui/qml/components/PasswordDialog.qml index 4b3cef5e4..07a788830 100644 --- a/electrum/gui/qml/components/PasswordDialog.qml +++ b/electrum/gui/qml/components/PasswordDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/Pin.qml b/electrum/gui/qml/components/Pin.qml index 591e4795a..cb9356495 100644 --- a/electrum/gui/qml/components/Pin.qml +++ b/electrum/gui/qml/components/Pin.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/Preferences.qml b/electrum/gui/qml/components/Preferences.qml index 893333e13..8804876de 100644 --- a/electrum/gui/qml/components/Preferences.qml +++ b/electrum/gui/qml/components/Preferences.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/ProxyConfigDialog.qml b/electrum/gui/qml/components/ProxyConfigDialog.qml index 73a85416c..b6a16403c 100644 --- a/electrum/gui/qml/components/ProxyConfigDialog.qml +++ b/electrum/gui/qml/components/ProxyConfigDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/RbfBumpFeeDialog.qml b/electrum/gui/qml/components/RbfBumpFeeDialog.qml index 144fd1c92..c8ed4239b 100644 --- a/electrum/gui/qml/components/RbfBumpFeeDialog.qml +++ b/electrum/gui/qml/components/RbfBumpFeeDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/RbfCancelDialog.qml b/electrum/gui/qml/components/RbfCancelDialog.qml index 315a36362..9f4076baf 100644 --- a/electrum/gui/qml/components/RbfCancelDialog.qml +++ b/electrum/gui/qml/components/RbfCancelDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/ReceiveDetailsDialog.qml b/electrum/gui/qml/components/ReceiveDetailsDialog.qml index 0f663fb73..02499722c 100644 --- a/electrum/gui/qml/components/ReceiveDetailsDialog.qml +++ b/electrum/gui/qml/components/ReceiveDetailsDialog.qml @@ -1,8 +1,8 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 -import QtQml.Models 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQml.Models import org.electrum 1.0 diff --git a/electrum/gui/qml/components/ReceiveDialog.qml b/electrum/gui/qml/components/ReceiveDialog.qml index 5967161a2..70f713bd8 100644 --- a/electrum/gui/qml/components/ReceiveDialog.qml +++ b/electrum/gui/qml/components/ReceiveDialog.qml @@ -1,8 +1,8 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 -import QtQml.Models 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQml.Models import org.electrum 1.0 diff --git a/electrum/gui/qml/components/ReceiveRequests.qml b/electrum/gui/qml/components/ReceiveRequests.qml index 879e3b928..c6792fdd1 100644 --- a/electrum/gui/qml/components/ReceiveRequests.qml +++ b/electrum/gui/qml/components/ReceiveRequests.qml @@ -1,9 +1,9 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 -import QtQml.Models 2.1 -import QtQml 2.6 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQml.Models +import QtQml import org.electrum 1.0 diff --git a/electrum/gui/qml/components/ScanDialog.qml b/electrum/gui/qml/components/ScanDialog.qml index 3a8f6ed21..2ced89a5f 100644 --- a/electrum/gui/qml/components/ScanDialog.qml +++ b/electrum/gui/qml/components/ScanDialog.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Controls 2.0 -import QtQuick.Layouts 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts import "controls" diff --git a/electrum/gui/qml/components/SendDialog.qml b/electrum/gui/qml/components/SendDialog.qml index d54d2a385..d042fbb71 100644 --- a/electrum/gui/qml/components/SendDialog.qml +++ b/electrum/gui/qml/components/SendDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Controls 2.14 -import QtQuick.Layouts 1.0 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/ServerConfigDialog.qml b/electrum/gui/qml/components/ServerConfigDialog.qml index 0fa56d4d1..ecabc4753 100644 --- a/electrum/gui/qml/components/ServerConfigDialog.qml +++ b/electrum/gui/qml/components/ServerConfigDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/ServerConnectWizard.qml b/electrum/gui/qml/components/ServerConnectWizard.qml index 725388f34..aec958705 100644 --- a/electrum/gui/qml/components/ServerConnectWizard.qml +++ b/electrum/gui/qml/components/ServerConnectWizard.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import "wizard" diff --git a/electrum/gui/qml/components/SignVerifyMessageDialog.qml b/electrum/gui/qml/components/SignVerifyMessageDialog.qml index d4e82d8c0..03a6d9825 100644 --- a/electrum/gui/qml/components/SignVerifyMessageDialog.qml +++ b/electrum/gui/qml/components/SignVerifyMessageDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/SwapDialog.qml b/electrum/gui/qml/components/SwapDialog.qml index 8c3f64a85..30a3fd46e 100644 --- a/electrum/gui/qml/components/SwapDialog.qml +++ b/electrum/gui/qml/components/SwapDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.0 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/TxDetails.qml b/electrum/gui/qml/components/TxDetails.qml index 139ec1646..9667fe525 100644 --- a/electrum/gui/qml/components/TxDetails.qml +++ b/electrum/gui/qml/components/TxDetails.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/WalletDetails.qml b/electrum/gui/qml/components/WalletDetails.qml index 15a277774..d5e2b22ee 100644 --- a/electrum/gui/qml/components/WalletDetails.qml +++ b/electrum/gui/qml/components/WalletDetails.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/WalletMainView.qml b/electrum/gui/qml/components/WalletMainView.qml index c0fa08ac4..6b130d8b4 100644 --- a/electrum/gui/qml/components/WalletMainView.qml +++ b/electrum/gui/qml/components/WalletMainView.qml @@ -1,8 +1,8 @@ -import QtQuick 2.6 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.0 -import QtQuick.Controls.Material 2.0 -import QtQml 2.6 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material +import QtQml import org.electrum 1.0 diff --git a/electrum/gui/qml/components/WalletSummary.qml b/electrum/gui/qml/components/WalletSummary.qml index 131899444..baddd0645 100644 --- a/electrum/gui/qml/components/WalletSummary.qml +++ b/electrum/gui/qml/components/WalletSummary.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.5 -import QtQuick.Controls 2.12 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/Wallets.qml b/electrum/gui/qml/components/Wallets.qml index da762a1e3..52dc31720 100644 --- a/electrum/gui/qml/components/Wallets.qml +++ b/electrum/gui/qml/components/Wallets.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/controls/AddressDelegate.qml b/electrum/gui/qml/components/controls/AddressDelegate.qml index 6b8d235ec..ebd88015a 100644 --- a/electrum/gui/qml/components/controls/AddressDelegate.qml +++ b/electrum/gui/qml/components/controls/AddressDelegate.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Controls 2.0 -import QtQuick.Layouts 1.0 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/controls/BalanceSummary.qml b/electrum/gui/qml/components/controls/BalanceSummary.qml index ec266c896..103159405 100644 --- a/electrum/gui/qml/components/controls/BalanceSummary.qml +++ b/electrum/gui/qml/components/controls/BalanceSummary.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material Item { id: root diff --git a/electrum/gui/qml/components/controls/BtcField.qml b/electrum/gui/qml/components/controls/BtcField.qml index 4414dd709..53b0e61c5 100644 --- a/electrum/gui/qml/components/controls/BtcField.qml +++ b/electrum/gui/qml/components/controls/BtcField.qml @@ -1,5 +1,5 @@ -import QtQuick 2.15 -import QtQuick.Controls 2.0 +import QtQuick +import QtQuick.Controls import org.electrum 1.0 diff --git a/electrum/gui/qml/components/controls/ButtonContainer.qml b/electrum/gui/qml/components/controls/ButtonContainer.qml index 644d40088..0783614c2 100644 --- a/electrum/gui/qml/components/controls/ButtonContainer.qml +++ b/electrum/gui/qml/components/controls/ButtonContainer.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.15 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material Container { id: root diff --git a/electrum/gui/qml/components/controls/ChannelBar.qml b/electrum/gui/qml/components/controls/ChannelBar.qml index 9dcf66c0c..8635356f7 100644 --- a/electrum/gui/qml/components/controls/ChannelBar.qml +++ b/electrum/gui/qml/components/controls/ChannelBar.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Controls 2.0 -import QtQuick.Layouts 1.0 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/controls/ChannelDelegate.qml b/electrum/gui/qml/components/controls/ChannelDelegate.qml index 299b7433b..66db0ed37 100644 --- a/electrum/gui/qml/components/controls/ChannelDelegate.qml +++ b/electrum/gui/qml/components/controls/ChannelDelegate.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Controls 2.0 -import QtQuick.Layouts 1.0 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/controls/ElComboBox.qml b/electrum/gui/qml/components/controls/ElComboBox.qml index 48366956f..e1ab08d7d 100644 --- a/electrum/gui/qml/components/controls/ElComboBox.qml +++ b/electrum/gui/qml/components/controls/ElComboBox.qml @@ -1,5 +1,5 @@ -import QtQuick 2.15 -import QtQuick.Controls 2.15 +import QtQuick +import QtQuick.Controls ComboBox { id: cb diff --git a/electrum/gui/qml/components/controls/ElDialog.qml b/electrum/gui/qml/components/controls/ElDialog.qml index b1c80eb73..f4e74e058 100644 --- a/electrum/gui/qml/components/controls/ElDialog.qml +++ b/electrum/gui/qml/components/controls/ElDialog.qml @@ -1,7 +1,7 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material Dialog { id: abstractdialog diff --git a/electrum/gui/qml/components/controls/FeeMethodComboBox.qml b/electrum/gui/qml/components/controls/FeeMethodComboBox.qml index b2ca188f7..53ac4eaa2 100644 --- a/electrum/gui/qml/components/controls/FeeMethodComboBox.qml +++ b/electrum/gui/qml/components/controls/FeeMethodComboBox.qml @@ -1,5 +1,5 @@ -import QtQuick 2.6 -import QtQuick.Controls 2.0 +import QtQuick +import QtQuick.Controls import org.electrum 1.0 diff --git a/electrum/gui/qml/components/controls/FiatField.qml b/electrum/gui/qml/components/controls/FiatField.qml index 47cb53694..750aa9024 100644 --- a/electrum/gui/qml/components/controls/FiatField.qml +++ b/electrum/gui/qml/components/controls/FiatField.qml @@ -1,5 +1,5 @@ -import QtQuick 2.15 -import QtQuick.Controls 2.0 +import QtQuick +import QtQuick.Controls import org.electrum 1.0 diff --git a/electrum/gui/qml/components/controls/FlatButton.qml b/electrum/gui/qml/components/controls/FlatButton.qml index 703e385b6..1f1e8acd4 100644 --- a/electrum/gui/qml/components/controls/FlatButton.qml +++ b/electrum/gui/qml/components/controls/FlatButton.qml @@ -1,8 +1,8 @@ -import QtQuick 2.6 -import QtQuick.Controls 2.15 -import QtQuick.Controls.Material 2.15 -import QtQuick.Controls.impl 2.15 -import QtQuick.Controls.Material.impl 2.15 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Controls.impl +import QtQuick.Controls.Material.impl TabButton { id: control diff --git a/electrum/gui/qml/components/controls/FormattedAmount.qml b/electrum/gui/qml/components/controls/FormattedAmount.qml index ac5e375b9..b33880ad3 100644 --- a/electrum/gui/qml/components/controls/FormattedAmount.qml +++ b/electrum/gui/qml/components/controls/FormattedAmount.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Controls 2.0 -import QtQuick.Layouts 1.0 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/controls/Heading.qml b/electrum/gui/qml/components/controls/Heading.qml index d67bcbfd5..7a4c47e74 100644 --- a/electrum/gui/qml/components/controls/Heading.qml +++ b/electrum/gui/qml/components/controls/Heading.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls RowLayout { id: root diff --git a/electrum/gui/qml/components/controls/HistoryItemDelegate.qml b/electrum/gui/qml/components/controls/HistoryItemDelegate.qml index 9d230536d..79e40b4fd 100644 --- a/electrum/gui/qml/components/controls/HistoryItemDelegate.qml +++ b/electrum/gui/qml/components/controls/HistoryItemDelegate.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/controls/InfoTextArea.qml b/electrum/gui/qml/components/controls/InfoTextArea.qml index c3a6a27f6..7f70c3cf5 100644 --- a/electrum/gui/qml/components/controls/InfoTextArea.qml +++ b/electrum/gui/qml/components/controls/InfoTextArea.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material TextHighlightPane { enum IconStyle { diff --git a/electrum/gui/qml/components/controls/InvoiceDelegate.qml b/electrum/gui/qml/components/controls/InvoiceDelegate.qml index 7ff214f68..bc053b07b 100644 --- a/electrum/gui/qml/components/controls/InvoiceDelegate.qml +++ b/electrum/gui/qml/components/controls/InvoiceDelegate.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Controls 2.0 -import QtQuick.Layouts 1.0 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material ItemDelegate { id: root diff --git a/electrum/gui/qml/components/controls/LightningNetworkStatusIndicator.qml b/electrum/gui/qml/components/controls/LightningNetworkStatusIndicator.qml index d83dd5aef..a90e3cbcc 100644 --- a/electrum/gui/qml/components/controls/LightningNetworkStatusIndicator.qml +++ b/electrum/gui/qml/components/controls/LightningNetworkStatusIndicator.qml @@ -1,4 +1,4 @@ -import QtQuick 2.6 +import QtQuick import org.electrum 1.0 diff --git a/electrum/gui/qml/components/controls/OnchainNetworkStatusIndicator.qml b/electrum/gui/qml/components/controls/OnchainNetworkStatusIndicator.qml index 739ef2ab3..1c3bc4c1e 100644 --- a/electrum/gui/qml/components/controls/OnchainNetworkStatusIndicator.qml +++ b/electrum/gui/qml/components/controls/OnchainNetworkStatusIndicator.qml @@ -1,4 +1,4 @@ -import QtQuick 2.6 +import QtQuick Image { id: root diff --git a/electrum/gui/qml/components/controls/PaneInsetBackground.qml b/electrum/gui/qml/components/controls/PaneInsetBackground.qml index d22259c9a..9762e4101 100644 --- a/electrum/gui/qml/components/controls/PaneInsetBackground.qml +++ b/electrum/gui/qml/components/controls/PaneInsetBackground.qml @@ -1,5 +1,5 @@ -import QtQuick 2.6 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Controls.Material Rectangle { property color baseColor: Material.background diff --git a/electrum/gui/qml/components/controls/PasswordField.qml b/electrum/gui/qml/components/controls/PasswordField.qml index 8aedfa76d..e9fc0e10d 100644 --- a/electrum/gui/qml/components/controls/PasswordField.qml +++ b/electrum/gui/qml/components/controls/PasswordField.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls RowLayout { id: root diff --git a/electrum/gui/qml/components/controls/Piechart.qml b/electrum/gui/qml/components/controls/Piechart.qml index 16dc69ed0..5960ce23c 100644 --- a/electrum/gui/qml/components/controls/Piechart.qml +++ b/electrum/gui/qml/components/controls/Piechart.qml @@ -1,4 +1,4 @@ -import QtQuick 2.6 +import QtQuick Canvas { id: piechart diff --git a/electrum/gui/qml/components/controls/PrefsHeading.qml b/electrum/gui/qml/components/controls/PrefsHeading.qml index 2389a1311..a833d04c8 100644 --- a/electrum/gui/qml/components/controls/PrefsHeading.qml +++ b/electrum/gui/qml/components/controls/PrefsHeading.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls Heading { id: root diff --git a/electrum/gui/qml/components/controls/ProxyConfig.qml b/electrum/gui/qml/components/controls/ProxyConfig.qml index 09cf941ba..dea20a9ca 100644 --- a/electrum/gui/qml/components/controls/ProxyConfig.qml +++ b/electrum/gui/qml/components/controls/ProxyConfig.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls Item { id: pc diff --git a/electrum/gui/qml/components/controls/QRImage.qml b/electrum/gui/qml/components/controls/QRImage.qml index a28febb53..1e544b8e2 100644 --- a/electrum/gui/qml/components/controls/QRImage.qml +++ b/electrum/gui/qml/components/controls/QRImage.qml @@ -1,5 +1,5 @@ -import QtQuick 2.6 -import QtQuick.Controls 2.15 +import QtQuick +import QtQuick.Controls Item { id: root diff --git a/electrum/gui/qml/components/controls/QRScan.qml b/electrum/gui/qml/components/controls/QRScan.qml index 2ca1fbabe..34c023fac 100644 --- a/electrum/gui/qml/components/controls/QRScan.qml +++ b/electrum/gui/qml/components/controls/QRScan.qml @@ -1,5 +1,5 @@ -import QtQuick 2.12 -import QtQuick.Controls 2.0 +import QtQuick +import QtQuick.Controls import QtMultimedia import org.electrum 1.0 diff --git a/electrum/gui/qml/components/controls/RequestExpiryComboBox.qml b/electrum/gui/qml/components/controls/RequestExpiryComboBox.qml index 00cb8912f..ef7711410 100644 --- a/electrum/gui/qml/components/controls/RequestExpiryComboBox.qml +++ b/electrum/gui/qml/components/controls/RequestExpiryComboBox.qml @@ -1,5 +1,5 @@ -import QtQuick 2.6 -import QtQuick.Controls 2.3 +import QtQuick +import QtQuick.Controls import org.electrum 1.0 diff --git a/electrum/gui/qml/components/controls/SeedKeyboard.qml b/electrum/gui/qml/components/controls/SeedKeyboard.qml index 7f444dcc6..e27c68f85 100644 --- a/electrum/gui/qml/components/controls/SeedKeyboard.qml +++ b/electrum/gui/qml/components/controls/SeedKeyboard.qml @@ -1,7 +1,7 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.15 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material Item { id: root diff --git a/electrum/gui/qml/components/controls/SeedKeyboardKey.qml b/electrum/gui/qml/components/controls/SeedKeyboardKey.qml index 748e1dce8..fa5fcc9f9 100644 --- a/electrum/gui/qml/components/controls/SeedKeyboardKey.qml +++ b/electrum/gui/qml/components/controls/SeedKeyboardKey.qml @@ -1,7 +1,7 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.15 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material Pane { id: root diff --git a/electrum/gui/qml/components/controls/SeedTextArea.qml b/electrum/gui/qml/components/controls/SeedTextArea.qml index a0f866ed9..aef9314ab 100644 --- a/electrum/gui/qml/components/controls/SeedTextArea.qml +++ b/electrum/gui/qml/components/controls/SeedTextArea.qml @@ -1,7 +1,7 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.15 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/controls/ServerConfig.qml b/electrum/gui/qml/components/controls/ServerConfig.qml index 32f1e0384..523da5ef3 100644 --- a/electrum/gui/qml/components/controls/ServerConfig.qml +++ b/electrum/gui/qml/components/controls/ServerConfig.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/controls/ServerDelegate.qml b/electrum/gui/qml/components/controls/ServerDelegate.qml index 21eb5639e..1b52fa50f 100644 --- a/electrum/gui/qml/components/controls/ServerDelegate.qml +++ b/electrum/gui/qml/components/controls/ServerDelegate.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Controls 2.0 -import QtQuick.Layouts 1.0 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/controls/Tag.qml b/electrum/gui/qml/components/controls/Tag.qml index 84e408de6..005d9072e 100644 --- a/electrum/gui/qml/components/controls/Tag.qml +++ b/electrum/gui/qml/components/controls/Tag.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material Rectangle { id: root diff --git a/electrum/gui/qml/components/controls/TextHighlightPane.qml b/electrum/gui/qml/components/controls/TextHighlightPane.qml index a2d92f685..fe6e07167 100644 --- a/electrum/gui/qml/components/controls/TextHighlightPane.qml +++ b/electrum/gui/qml/components/controls/TextHighlightPane.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material Pane { padding: constants.paddingSmall diff --git a/electrum/gui/qml/components/controls/Toaster.qml b/electrum/gui/qml/components/controls/Toaster.qml index c8f3a8ea7..12f37b8cf 100644 --- a/electrum/gui/qml/components/controls/Toaster.qml +++ b/electrum/gui/qml/components/controls/Toaster.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.14 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import ".." diff --git a/electrum/gui/qml/components/controls/TxOutput.qml b/electrum/gui/qml/components/controls/TxOutput.qml index 918b92028..741837bbb 100644 --- a/electrum/gui/qml/components/controls/TxOutput.qml +++ b/electrum/gui/qml/components/controls/TxOutput.qml @@ -1,7 +1,7 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/wizard/WCAutoConnect.qml b/electrum/gui/qml/components/wizard/WCAutoConnect.qml index 2e52718cc..c6700da83 100644 --- a/electrum/gui/qml/components/wizard/WCAutoConnect.qml +++ b/electrum/gui/qml/components/wizard/WCAutoConnect.qml @@ -1,6 +1,6 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import "../controls" diff --git a/electrum/gui/qml/components/wizard/WCConfirmSeed.qml b/electrum/gui/qml/components/wizard/WCConfirmSeed.qml index 17d262e5d..514f60fad 100644 --- a/electrum/gui/qml/components/wizard/WCConfirmSeed.qml +++ b/electrum/gui/qml/components/wizard/WCConfirmSeed.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import org.electrum 1.0 diff --git a/electrum/gui/qml/components/wizard/WCCosignerKeystore.qml b/electrum/gui/qml/components/wizard/WCCosignerKeystore.qml index 46801a9b5..40ef1cb22 100644 --- a/electrum/gui/qml/components/wizard/WCCosignerKeystore.qml +++ b/electrum/gui/qml/components/wizard/WCCosignerKeystore.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/wizard/WCCreateSeed.qml b/electrum/gui/qml/components/wizard/WCCreateSeed.qml index 83b43f2ff..8ca1679e6 100644 --- a/electrum/gui/qml/components/wizard/WCCreateSeed.qml +++ b/electrum/gui/qml/components/wizard/WCCreateSeed.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import org.electrum 1.0 diff --git a/electrum/gui/qml/components/wizard/WCHaveMasterKey.qml b/electrum/gui/qml/components/wizard/WCHaveMasterKey.qml index 5882102ac..4aafd0d8f 100644 --- a/electrum/gui/qml/components/wizard/WCHaveMasterKey.qml +++ b/electrum/gui/qml/components/wizard/WCHaveMasterKey.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/wizard/WCHaveSeed.qml b/electrum/gui/qml/components/wizard/WCHaveSeed.qml index 86da1d924..9fea691c0 100644 --- a/electrum/gui/qml/components/wizard/WCHaveSeed.qml +++ b/electrum/gui/qml/components/wizard/WCHaveSeed.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/wizard/WCImport.qml b/electrum/gui/qml/components/wizard/WCImport.qml index 879a5c652..ce5de51a6 100644 --- a/electrum/gui/qml/components/wizard/WCImport.qml +++ b/electrum/gui/qml/components/wizard/WCImport.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import org.electrum 1.0 diff --git a/electrum/gui/qml/components/wizard/WCKeystoreType.qml b/electrum/gui/qml/components/wizard/WCKeystoreType.qml index 4d48bb2eb..f33cd2c00 100644 --- a/electrum/gui/qml/components/wizard/WCKeystoreType.qml +++ b/electrum/gui/qml/components/wizard/WCKeystoreType.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import "../controls" diff --git a/electrum/gui/qml/components/wizard/WCMultisig.qml b/electrum/gui/qml/components/wizard/WCMultisig.qml index 0ed56ffaf..96c6a2be1 100644 --- a/electrum/gui/qml/components/wizard/WCMultisig.qml +++ b/electrum/gui/qml/components/wizard/WCMultisig.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import org.electrum 1.0 diff --git a/electrum/gui/qml/components/wizard/WCProxyAsk.qml b/electrum/gui/qml/components/wizard/WCProxyAsk.qml index 84e4c4c06..7b49a0e23 100644 --- a/electrum/gui/qml/components/wizard/WCProxyAsk.qml +++ b/electrum/gui/qml/components/wizard/WCProxyAsk.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import "../controls" diff --git a/electrum/gui/qml/components/wizard/WCProxyConfig.qml b/electrum/gui/qml/components/wizard/WCProxyConfig.qml index 3bf1abd64..b58e29f45 100644 --- a/electrum/gui/qml/components/wizard/WCProxyConfig.qml +++ b/electrum/gui/qml/components/wizard/WCProxyConfig.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import "../controls" diff --git a/electrum/gui/qml/components/wizard/WCScriptAndDerivation.qml b/electrum/gui/qml/components/wizard/WCScriptAndDerivation.qml index d87e33031..c3a30fbd1 100644 --- a/electrum/gui/qml/components/wizard/WCScriptAndDerivation.qml +++ b/electrum/gui/qml/components/wizard/WCScriptAndDerivation.qml @@ -1,7 +1,7 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material import org.electrum 1.0 diff --git a/electrum/gui/qml/components/wizard/WCServerConfig.qml b/electrum/gui/qml/components/wizard/WCServerConfig.qml index 4b76fb255..b2829caae 100644 --- a/electrum/gui/qml/components/wizard/WCServerConfig.qml +++ b/electrum/gui/qml/components/wizard/WCServerConfig.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import "../controls" diff --git a/electrum/gui/qml/components/wizard/WCShowMasterPubkey.qml b/electrum/gui/qml/components/wizard/WCShowMasterPubkey.qml index f5e0497e3..0bc9746e4 100644 --- a/electrum/gui/qml/components/wizard/WCShowMasterPubkey.qml +++ b/electrum/gui/qml/components/wizard/WCShowMasterPubkey.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import org.electrum 1.0 diff --git a/electrum/gui/qml/components/wizard/WCWalletName.qml b/electrum/gui/qml/components/wizard/WCWalletName.qml index 3da936ee1..c4da33c81 100644 --- a/electrum/gui/qml/components/wizard/WCWalletName.qml +++ b/electrum/gui/qml/components/wizard/WCWalletName.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import org.electrum 1.0 diff --git a/electrum/gui/qml/components/wizard/WCWalletPassword.qml b/electrum/gui/qml/components/wizard/WCWalletPassword.qml index 2e41d1309..af9241684 100644 --- a/electrum/gui/qml/components/wizard/WCWalletPassword.qml +++ b/electrum/gui/qml/components/wizard/WCWalletPassword.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import "../controls" diff --git a/electrum/gui/qml/components/wizard/WCWalletType.qml b/electrum/gui/qml/components/wizard/WCWalletType.qml index f4af39415..21d6bf0c4 100644 --- a/electrum/gui/qml/components/wizard/WCWalletType.qml +++ b/electrum/gui/qml/components/wizard/WCWalletType.qml @@ -1,6 +1,6 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import "../controls" diff --git a/electrum/gui/qml/components/wizard/Wizard.qml b/electrum/gui/qml/components/wizard/Wizard.qml index 89a2aba0b..85c9ed2ef 100644 --- a/electrum/gui/qml/components/wizard/Wizard.qml +++ b/electrum/gui/qml/components/wizard/Wizard.qml @@ -1,6 +1,6 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.1 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import org.electrum 1.0 diff --git a/electrum/gui/qml/components/wizard/WizardComponent.qml b/electrum/gui/qml/components/wizard/WizardComponent.qml index 87084ca03..4f2eca587 100644 --- a/electrum/gui/qml/components/wizard/WizardComponent.qml +++ b/electrum/gui/qml/components/wizard/WizardComponent.qml @@ -1,6 +1,6 @@ -import QtQuick 2.15 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material Pane { id: root From ae446377f8dd8609d1413076a9c442b9b339ae7c Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Wed, 19 Jul 2023 14:14:24 +0200 Subject: [PATCH 07/22] qml: work around toolbar layout not right-aligning indicators when indicators toggle visibility --- electrum/gui/qml/components/main.qml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/electrum/gui/qml/components/main.qml b/electrum/gui/qml/components/main.qml index 69f13da86..588f8c24b 100644 --- a/electrum/gui/qml/components/main.qml +++ b/electrum/gui/qml/components/main.qml @@ -201,8 +201,10 @@ ApplicationWindow } } - LightningNetworkStatusIndicator {} - OnchainNetworkStatusIndicator {} + LightningNetworkStatusIndicator { + id: lnnsi + } + OnchainNetworkStatusIndicator { } } } } @@ -212,7 +214,11 @@ ApplicationWindow Item { Layout.preferredHeight: 1 Layout.topMargin: -1 - Layout.preferredWidth: watchOnlyIndicator.visible ? app.width : 1 + Layout.preferredWidth: watchOnlyIndicator.visible + ? 1 + : lnnsi.visible + ? 2 + : 3 } } } From 65d41ccc49be44e1c3a393af97dfbb39296272cd Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Wed, 27 Sep 2023 21:05:26 +0200 Subject: [PATCH 08/22] qml: qualify all signal handler parameters --- .../gui/qml/components/AddressDetails.qml | 2 +- .../gui/qml/components/CloseChannelDialog.qml | 4 +-- .../gui/qml/components/OpenChannelDialog.qml | 17 ++++++---- electrum/gui/qml/components/TxDetails.qml | 2 +- .../gui/qml/components/WalletMainView.qml | 34 +++++++++++++------ electrum/gui/qml/components/main.qml | 9 +++-- 6 files changed, 44 insertions(+), 24 deletions(-) diff --git a/electrum/gui/qml/components/AddressDetails.qml b/electrum/gui/qml/components/AddressDetails.qml index 8cbbb2230..2c7ab2ef4 100644 --- a/electrum/gui/qml/components/AddressDetails.qml +++ b/electrum/gui/qml/components/AddressDetails.qml @@ -310,7 +310,7 @@ Pane { address: root.address onFrozenChanged: addressDetailsChanged() onLabelChanged: addressDetailsChanged() - onAuthRequired: { + onAuthRequired: (method, authMessage) => { app.handleAuthRequired(addressdetails, method, authMessage) } } diff --git a/electrum/gui/qml/components/CloseChannelDialog.qml b/electrum/gui/qml/components/CloseChannelDialog.qml index f05e710e6..8172da48f 100644 --- a/electrum/gui/qml/components/CloseChannelDialog.qml +++ b/electrum/gui/qml/components/CloseChannelDialog.qml @@ -202,7 +202,7 @@ ElDialog { wallet: Daemon.currentWallet channelid: dialog.channelid - onAuthRequired: { + onAuthRequired: (method, authMessage) => { app.handleAuthRequired(channeldetails, method, authMessage) } @@ -228,7 +228,7 @@ ElDialog { dialog.close() } - onChannelCloseFailed: { + onChannelCloseFailed: (message) => { errorText.text = message } } diff --git a/electrum/gui/qml/components/OpenChannelDialog.qml b/electrum/gui/qml/components/OpenChannelDialog.qml index 1ec3a61dd..d1730e465 100644 --- a/electrum/gui/qml/components/OpenChannelDialog.qml +++ b/electrum/gui/qml/components/OpenChannelDialog.qml @@ -212,16 +212,19 @@ ElDialog { ChannelOpener { id: channelopener wallet: Daemon.currentWallet - onAuthRequired: { + onAuthRequired: (method, authMessage) => { app.handleAuthRequired(channelopener, method, authMessage) } - onValidationError: { + onValidationError: (code, message) => { if (code == 'invalid_nodeid') { - var dialog = app.messageDialog.createObject(app, { title: qsTr('Error'), 'text': message }) + var dialog = app.messageDialog.createObject(app, { + title: qsTr('Error'), + text: message + }) dialog.open() } } - onConflictingBackup: { + onConflictingBackup: (message) => { var dialog = app.messageDialog.createObject(app, { 'text': message, 'yesno': true }) dialog.open() dialog.accepted.connect(function() { @@ -237,17 +240,17 @@ ElDialog { }) dialog.open() } - onChannelOpening: { + onChannelOpening: (peer) => { console.log('Channel is opening') app.channelOpenProgressDialog.reset() app.channelOpenProgressDialog.peer = peer app.channelOpenProgressDialog.open() } - onChannelOpenError: { + onChannelOpenError: (message) => { app.channelOpenProgressDialog.state = 'failed' app.channelOpenProgressDialog.error = message } - onChannelOpenSuccess: { + onChannelOpenSuccess: (cid, has_onchain_backup, min_depth, tx_complete) => { var message = qsTr('Channel established.') + ' ' + qsTr('This channel will be usable after %1 confirmations').arg(min_depth) if (!tx_complete) { diff --git a/electrum/gui/qml/components/TxDetails.qml b/electrum/gui/qml/components/TxDetails.qml index 9667fe525..577eb12e8 100644 --- a/electrum/gui/qml/components/TxDetails.qml +++ b/electrum/gui/qml/components/TxDetails.qml @@ -399,7 +399,7 @@ Pane { id: txdetails wallet: Daemon.currentWallet onLabelChanged: root.detailsChanged() - onConfirmRemoveLocalTx: { + onConfirmRemoveLocalTx: (message) => { var dialog = app.messageDialog.createObject(app, { text: message, yesno: true }) dialog.accepted.connect(function() { txdetails.removeLocalTx(true) diff --git a/electrum/gui/qml/components/WalletMainView.qml b/electrum/gui/qml/components/WalletMainView.qml index 6b130d8b4..f12cfb122 100644 --- a/electrum/gui/qml/components/WalletMainView.qml +++ b/electrum/gui/qml/components/WalletMainView.qml @@ -264,16 +264,20 @@ Item { InvoiceParser { id: invoiceParser wallet: Daemon.currentWallet - onValidationError: { - var dialog = app.messageDialog.createObject(app, { text: message }) + onValidationError: (code, message) => { + var dialog = app.messageDialog.createObject(app, { + text: message + }) dialog.closed.connect(function() { restartSendDialog() }) dialog.open() } - onValidationWarning: { + onValidationWarning: (code, message) => { if (code == 'no_channels') { - var dialog = app.messageDialog.createObject(app, { text: message }) + var dialog = app.messageDialog.createObject(app, { + text: message + }) dialog.closed.connect(function() { restartSendDialog() }) @@ -284,18 +288,28 @@ Item { } onValidationSuccess: { closeSendDialog() - var dialog = invoiceDialog.createObject(app, { invoice: invoiceParser, payImmediately: invoiceParser.isLnurlPay }) + var dialog = invoiceDialog.createObject(app, { + invoice: invoiceParser, + payImmediately: invoiceParser.isLnurlPay + }) dialog.open() } - onInvoiceCreateError: console.log(code + ' ' + message) + onInvoiceCreateError: (code, message) => { + console.log(code + ' ' + message) + } onLnurlRetrieved: { closeSendDialog() - var dialog = lnurlPayDialog.createObject(app, { invoiceParser: invoiceParser }) + var dialog = lnurlPayDialog.createObject(app, { + invoiceParser: invoiceParser + }) dialog.open() } - onLnurlError: { - var dialog = app.messageDialog.createObject(app, { title: qsTr('Error'), text: message }) + onLnurlError: (code, message) => { + var dialog = app.messageDialog.createObject(app, { + title: qsTr('Error'), + text: message } + ) dialog.open() } } @@ -477,7 +491,7 @@ Item { finalizer: TxFinalizer { wallet: Daemon.currentWallet canRbf: true - onFinished: { + onFinished: (signed, saved, complete) => { if (!complete) { var msg if (wallet.isWatchOnly) { diff --git a/electrum/gui/qml/components/main.qml b/electrum/gui/qml/components/main.qml index 588f8c24b..c44f5fb61 100644 --- a/electrum/gui/qml/components/main.qml +++ b/electrum/gui/qml/components/main.qml @@ -405,11 +405,14 @@ ApplicationWindow swaphelper: SwapHelper { id: _swaphelper wallet: Daemon.currentWallet - onAuthRequired: { + onAuthRequired: (method, authMessage) => { app.handleAuthRequired(_swaphelper, method, authMessage) } - onError: { - var dialog = app.messageDialog.createObject(app, { title: qsTr('Error'), text: message }) + onError: (message) => { + var dialog = app.messageDialog.createObject(app, { + title: qsTr('Error'), + text: message + }) dialog.open() } } From a77ff9943a501a45548a2568a279b6e4fd6939d4 Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Wed, 19 Jul 2023 14:13:10 +0200 Subject: [PATCH 09/22] qml: refactor qr scan to qt6 As the method of capturing frames is totally different, the animation when a QR is found has been removed. --- contrib/android/p4a_recipes/qt6/__init__.py | 2 + electrum/gui/qml/__init__.py | 4 +- electrum/gui/qml/components/ScanDialog.qml | 6 + electrum/gui/qml/components/SendDialog.qml | 17 +- .../gui/qml/components/WalletMainView.qml | 2 +- .../gui/qml/components/controls/QRScan.qml | 248 ++++++++---------- electrum/gui/qml/components/main.qml | 1 + electrum/gui/qml/qeapp.py | 9 +- electrum/gui/qml/qeqr.py | 127 +++++---- 9 files changed, 206 insertions(+), 210 deletions(-) diff --git a/contrib/android/p4a_recipes/qt6/__init__.py b/contrib/android/p4a_recipes/qt6/__init__.py index 312f459b3..1a91e0bf3 100644 --- a/contrib/android/p4a_recipes/qt6/__init__.py +++ b/contrib/android/p4a_recipes/qt6/__init__.py @@ -7,11 +7,13 @@ from pythonforandroid.util import load_source util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py')) assert Qt6Recipe._version == "6.4.3" +# assert Qt6Recipe._version == "6.5.3" assert Qt6Recipe.depends == ['python3', 'hostqt6'] assert Qt6Recipe.python_depends == [] class Qt6RecipePinned(util.InheritedRecipeMixin, Qt6Recipe): sha512sum = "0bdbe8b9a43390c98cf19e851ec5394bc78438d227cf9d0d7a3748aee9a32a7f14fc46f52d4fa283819f21413567080aee7225c566af5278557f5e1992674da3" + # sha512sum = "ca8ea3b81c121886636988275f7fa8ae6d19f7be02669e63ab19b4285b611057a41279db9532c25ae87baa3904b010e1db68b899cd0eda17a5a8d3d87098b4d5" recipe = Qt6RecipePinned() diff --git a/electrum/gui/qml/__init__.py b/electrum/gui/qml/__init__.py index 08894eb67..53e87c2e5 100644 --- a/electrum/gui/qml/__init__.py +++ b/electrum/gui/qml/__init__.py @@ -7,12 +7,12 @@ from typing import TYPE_CHECKING try: import PyQt6 except Exception: - sys.exit("Error: Could not import PyQt6 on Linux systems, you may try 'sudo apt-get install python3-pyqt6'") + sys.exit("Error: Could not import PyQt6. On Linux systems, you may try 'sudo apt-get install python3-pyqt6'") try: import PyQt6.QtQml except Exception: - sys.exit("Error: Could not import PyQt6.QtQml on Linux systems, you may try 'sudo apt-get install python3-pyqt6.qtquick'") + sys.exit("Error: Could not import PyQt6.QtQml. On Linux systems, you may try 'sudo apt-get install python3-pyqt6.qtquick'") from PyQt6.QtCore import (Qt, QCoreApplication, QLocale, QTranslator, QTimer, QT_VERSION_STR, PYQT_VERSION_STR) from PyQt6.QtGui import QGuiApplication diff --git a/electrum/gui/qml/components/ScanDialog.qml b/electrum/gui/qml/components/ScanDialog.qml index 2ced89a5f..933dcd7e5 100644 --- a/electrum/gui/qml/components/ScanDialog.qml +++ b/electrum/gui/qml/components/ScanDialog.qml @@ -20,11 +20,17 @@ ElDialog { header: null topPadding: 0 // dialog needs topPadding override + function doClose() { + qrscan.stop() + Qt.callLater(doReject) + } + ColumnLayout { anchors.fill: parent spacing: 0 QRScan { + id: qrscan Layout.fillWidth: true Layout.fillHeight: true hint: scanDialog.hint diff --git a/electrum/gui/qml/components/SendDialog.qml b/electrum/gui/qml/components/SendDialog.qml index d042fbb71..d1bb235f3 100644 --- a/electrum/gui/qml/components/SendDialog.qml +++ b/electrum/gui/qml/components/SendDialog.qml @@ -19,6 +19,11 @@ ElDialog { padding: 0 topPadding: 0 + onAboutToHide: { + console.log('about to hide') + qrscan.stop() + } + function restart() { qrscan.restart() } @@ -34,6 +39,13 @@ ElDialog { } } + // override + function doClose() { + console.log('SendDialog doClose override') // doesn't trigger when going back?? + qrscan.stop() + Qt.callLater(doReject) + } + ColumnLayout { anchors.fill: parent spacing: 0 @@ -55,7 +67,10 @@ ElDialog { Layout.preferredWidth: 1 icon.source: '../../icons/copy_bw.png' text: qsTr('Paste') - onClicked: dialog.dispatch(AppController.clipboardToText()) + onClicked: { + qrscan.stop() + dialog.dispatch(AppController.clipboardToText()) + } } } diff --git a/electrum/gui/qml/components/WalletMainView.qml b/electrum/gui/qml/components/WalletMainView.qml index f12cfb122..0b2a70740 100644 --- a/electrum/gui/qml/components/WalletMainView.qml +++ b/electrum/gui/qml/components/WalletMainView.qml @@ -40,7 +40,7 @@ Item { function closeSendDialog() { if (_sendDialog) { - _sendDialog.close() + _sendDialog.doClose() _sendDialog = null } } diff --git a/electrum/gui/qml/components/controls/QRScan.qml b/electrum/gui/qml/components/controls/QRScan.qml index 34c023fac..66ce7c17f 100644 --- a/electrum/gui/qml/components/controls/QRScan.qml +++ b/electrum/gui/qml/components/controls/QRScan.qml @@ -1,6 +1,7 @@ import QtQuick import QtQuick.Controls import QtMultimedia +import QtQml import org.electrum 1.0 @@ -12,73 +13,125 @@ Item { property string scanData property string hint - property bool _pointsVisible - signal found function restart() { - still.source = '' - _pointsVisible = false - active = true + console.log('qrscan.restart') + scanData = '' + qr.reset() + start() + } + + function start() { + console.log('qrscan.start') + loader.item.startTimer.start() } - VideoOutput { - id: vo + function stop() { + console.log('qrscan.stop') + scanner.active = false + } + + Item { + id: points + z: 100 anchors.fill: parent - // source: camera - fillMode: VideoOutput.PreserveAspectCrop + } - Rectangle { - width: parent.width - height: (parent.height - parent.width) / 2 - visible: camera.cameraStatus == Camera.ActiveStatus - anchors.top: parent.top - color: Qt.rgba(0,0,0,0.5) - } - Rectangle { - width: parent.width - height: (parent.height - parent.width) / 2 - visible: camera.cameraStatus == Camera.ActiveStatus - anchors.bottom: parent.bottom - color: Qt.rgba(0,0,0,0.5) - } - InfoTextArea { - visible: scanner.hint - background.opacity: 0.5 - iconStyle: InfoTextArea.IconStyle.None - anchors { - top: parent.top - topMargin: constants.paddingXLarge - left: parent.left - leftMargin: constants.paddingXXLarge - right: parent.right - rightMargin: constants.paddingXXLarge + Loader { + id: loader + anchors.fill: parent + sourceComponent: scancomp + onStatusChanged: { + if (loader.status == Loader.Ready) { + console.log('camera loaded') + } else if (loader.status == Loader.Error) { + console.log('camera load error') } - text: scanner.hint } } - Image { - id: still - anchors.fill: vo - } + Component { + id: scancomp + + Item { + property alias vo: _vo + property alias ic: _ic + property alias startTimer: _startTimer - SequentialAnimation { - id: foundAnimation - PropertyAction { target: scanner; property: '_pointsVisible'; value: true} - PauseAnimation { duration: 80 } - PropertyAction { target: scanner; property: '_pointsVisible'; value: false} - PauseAnimation { duration: 80 } - PropertyAction { target: scanner; property: '_pointsVisible'; value: true} - PauseAnimation { duration: 80 } - PropertyAction { target: scanner; property: '_pointsVisible'; value: false} - PauseAnimation { duration: 80 } - PropertyAction { target: scanner; property: '_pointsVisible'; value: true} - PauseAnimation { duration: 80 } - PropertyAction { target: scanner; property: '_pointsVisible'; value: false} - PauseAnimation { duration: 80 } - PropertyAction { target: scanner; property: '_pointsVisible'; value: true} - onFinished: found() + VideoOutput { + id: _vo + anchors.fill: parent + + fillMode: VideoOutput.PreserveAspectCrop + + Rectangle { + width: parent.width + height: (parent.height - parent.width) / 2 + anchors.top: parent.top + color: Qt.rgba(0,0,0,0.5) + } + Rectangle { + width: parent.width + height: (parent.height - parent.width) / 2 + anchors.bottom: parent.bottom + color: Qt.rgba(0,0,0,0.5) + } + InfoTextArea { + visible: scanner.hint + background.opacity: 0.5 + iconStyle: InfoTextArea.IconStyle.None + anchors { + top: parent.top + topMargin: constants.paddingXLarge + left: parent.left + leftMargin: constants.paddingXXLarge + right: parent.right + rightMargin: constants.paddingXXLarge + } + text: scanner.hint + } + + Component.onCompleted: { + startTimer.start() + } + } + + ImageCapture { + id: _ic + + } + + MediaDevices { + id: mediaDevices + } + + Camera { + id: camera + cameraDevice: mediaDevices.defaultVideoInput + active: scanner.active + focusMode: Camera.FocusModeAutoNear + customFocusPoint: Qt.point(0.5, 0.5) + + onErrorOccurred: { + console.log('camera error: ' + errorString) + } + } + + CaptureSession { + videoOutput: _vo + imageCapture: _ic + camera: camera + } + + Timer { + id: _startTimer + interval: 500 + repeat: false + onTriggered: scanner.active = true + } + + } } Component { @@ -98,95 +151,16 @@ Item { Connections { target: qr function onDataChanged() { - console.log(qr.data) + console.log('QR DATA: ' + qr.data) scanner.active = false scanner.scanData = qr.data - still.source = scanner.url - - var sx = still.width/still.sourceSize.width - var sy = still.height/still.sourceSize.height - r.createObject(scanner, {cx: qr.points[0].x * sx, cy: qr.points[0].y * sy, color: 'yellow'}) - r.createObject(scanner, {cx: qr.points[1].x * sx, cy: qr.points[1].y * sy, color: 'yellow'}) - r.createObject(scanner, {cx: qr.points[2].x * sx, cy: qr.points[2].y * sy, color: 'yellow'}) - r.createObject(scanner, {cx: qr.points[3].x * sx, cy: qr.points[3].y * sy, color: 'yellow'}) - - foundAnimation.start() - } - } - - MediaDevices { - id: mediaDevices - } - - CaptureSession { - videoOutput: VideoOutput - - camera: Camera { - id: camera - // deviceId: QtMultimedia.defaultCamera.deviceId - cameraDevice: mediaDevices.defaultVideoInput - // TODO QT6 - // viewfinder.resolution: "640x480" - - // focus { - // focusMode: Camera.FocusContinuous - // focusPointMode: Camera.FocusPointCustom - // customFocusPoint: Qt.point(0.5, 0.5) - // } - - function dumpstats() { - console.log(camera.viewfinder.resolution) - console.log(camera.viewfinder.minimumFrameRate) - console.log(camera.viewfinder.maximumFrameRate) - var resolutions = camera.supportedViewfinderResolutions() - resolutions.forEach(function(item, i) { - console.log('' + item.width + 'x' + item.height) - }) - // TODO - // pick a suitable resolution from the available resolutions - // problem: some cameras have no supportedViewfinderResolutions - // but still error out when an invalid resolution is set. - // 640x480 seems to be universally available, but this needs to - // be checked across a range of phone models. - } - } - } - - Timer { - id: scanTimer - interval: 200 - repeat: true - running: scanner.active - onTriggered: { - if (qr.busy) - return - vo.grabToImage(function(result) { - if (result.image !== undefined) { - scanner.url = result.url - qr.scanImage(result.image) - } else { - console.log('image grab returned null') - } - }) + scanner.found() } } QRParser { id: qr + videoSink: loader.item.vo.videoSink } - Component.onCompleted: { - console.log('enumerating cameras') - QtMultimedia.availableCameras.forEach(function(item) { - console.log('cam found, id=' + item.deviceId + ' name=' + item.displayName) - console.log('pos=' + item.position + ' orientation=' + item.orientation) - if (QtMultimedia.defaultCamera.deviceId == item.deviceId) { - vo.orientation = item.orientation - } - - camera.dumpstats() - }) - - active = true - } } diff --git a/electrum/gui/qml/components/main.qml b/electrum/gui/qml/components/main.qml index c44f5fb61..0821952bc 100644 --- a/electrum/gui/qml/components/main.qml +++ b/electrum/gui/qml/components/main.qml @@ -478,6 +478,7 @@ ApplicationWindow if (activeDialogs.length > 0) { var activeDialog = activeDialogs[activeDialogs.length - 1] if (activeDialog.allowClose) { + console.log('main: dialog.doClose') activeDialog.doClose() } else { console.log('dialog disallowed close') diff --git a/electrum/gui/qml/qeapp.py b/electrum/gui/qml/qeapp.py index 37805f340..4bd8194d8 100644 --- a/electrum/gui/qml/qeapp.py +++ b/electrum/gui/qml/qeapp.py @@ -9,7 +9,7 @@ from typing import TYPE_CHECKING, Set from PyQt6.QtCore import (pyqtSlot, pyqtSignal, pyqtProperty, QObject, qInstallMessageHandler, QTimer, QSortFilterProxyModel) -from PyQt6.QtGui import QGuiApplication, QFontDatabase +from PyQt6.QtGui import QGuiApplication, QFontDatabase, QScreen from PyQt6.QtQml import qmlRegisterType, qmlRegisterUncreatableType, QQmlApplicationEngine from electrum import version, constants @@ -369,7 +369,7 @@ class ElectrumQmlApplication(QGuiApplication): qmlRegisterType(QETxCanceller, 'org.electrum', 1, 0, 'TxCanceller') qmlRegisterType(QEBip39RecoveryListModel, 'org.electrum', 1, 0, 'Bip39RecoveryListModel') - # TODO QT6 + # TODO QT6: these were declared as uncreatable, but that doesn't seem to work for pyqt6 # qmlRegisterUncreatableType(QEAmount, 'org.electrum', 1, 0, 'Amount', 'Amount can only be used as property') # qmlRegisterUncreatableType(QENewWalletWizard, 'org.electrum', 1, 0, 'QNewWalletWizard', 'QNewWalletWizard can only be used as property') # qmlRegisterUncreatableType(QEServerConnectWizard, 'org.electrum', 1, 0, 'QServerConnectWizard', 'QServerConnectWizard can only be used as property') @@ -380,9 +380,10 @@ class ElectrumQmlApplication(QGuiApplication): screensize = self.primaryScreen().size() - self.qr_ip = QEQRImageProvider((7/8)*min(screensize.width(), screensize.height())) + qr_size = min(screensize.width(), screensize.height()) * 7/8 + self.qr_ip = QEQRImageProvider(qr_size) self.engine.addImageProvider('qrgen', self.qr_ip) - self.qr_ip_h = QEQRImageProviderHelper((7/8)*min(screensize.width(), screensize.height())) + self.qr_ip_h = QEQRImageProviderHelper(qr_size) # add a monospace font as we can't rely on device having one self.fixedFont = 'PT Mono' diff --git a/electrum/gui/qml/qeqr.py b/electrum/gui/qml/qeqr.py index a102461bd..d268fa9cd 100644 --- a/electrum/gui/qml/qeqr.py +++ b/electrum/gui/qml/qeqr.py @@ -5,11 +5,12 @@ from qrcode.exceptions import DataOverflowError import math import urllib -from PIL import Image, ImageQt +from PIL import ImageQt -from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRect, QPoint +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRect from PyQt6.QtGui import QImage, QColor from PyQt6.QtQuick import QQuickImageProvider +from PyQt6.QtMultimedia import QVideoSink from electrum.logging import get_logger from electrum.qrreader import get_qr_reader @@ -22,103 +23,99 @@ class QEQRParser(QObject): busyChanged = pyqtSignal() dataChanged = pyqtSignal() - imageChanged = pyqtSignal() + sizeChanged = pyqtSignal() + videoSinkChanged = pyqtSignal() def __init__(self, text=None, parent=None): super().__init__(parent) self._busy = False - self._image = None self._data = None + self._video_sink = None self._text = text self.qrreader = get_qr_reader() if not self.qrreader: raise Exception(_("The platform QR detection library is not available.")) - @pyqtSlot('QImage') - def scanImage(self, image=None): - if self._busy: - self._logger.warning("Already processing an image. Check 'busy' property before calling scanImage") - return + @pyqtProperty(QVideoSink, notify=videoSinkChanged) + def videoSink(self): + return self._video_sink + + @videoSink.setter + def videoSink(self, sink: QVideoSink): + if self._video_sink != sink: + self._video_sink = sink + self._video_sink.videoFrameChanged.connect(self.onVideoFrame) - if image is None: - self._logger.warning("No image to decode") + def onVideoFrame(self, videoframe): + if self._busy or self._data: return self._busy = True self.busyChanged.emit() - # self.logImageStats(image) - self._parseQR(image) - - def logImageStats(self, image): - self._logger.info(f'width: {image.width()} height: {image.height()} depth: {image.depth()} format: {image.format()}') - - def _parseQR(self, image): - self.w = image.width() - self.h = image.height() - img_crop_rect = self._get_crop(image, 360) - frame_cropped = image.copy(img_crop_rect) + if not videoframe.isValid(): + self._logger.debug('invalid frame') + return - async def co_parse_qr(image): - # Convert to Y800 / GREY FourCC (single 8-bit channel) - # This creates a copy, so we don't need to keep the frame around anymore - frame_y800 = image.convertToFormat(QImage.Format_Grayscale8) + async def co_parse_qr(frame): + image = frame.toImage() + self._parseQR(image) - self.frame_id = 0 - # Read the QR codes from the frame - self.qrreader_res = self.qrreader.read_qr_code( - frame_y800.constBits().__int__(), - frame_y800.byteCount(), - frame_y800.bytesPerLine(), - frame_y800.width(), - frame_y800.height(), - self.frame_id - ) + asyncio.run_coroutine_threadsafe(co_parse_qr(videoframe), get_asyncio_loop()) - if len(self.qrreader_res) > 0: - result = self.qrreader_res[0] - self._data = result - self.dataChanged.emit() + def _parseQR(self, image: QImage): + self._size = min(image.width(), image.height()) + self.sizeChanged.emit() + img_crop_rect = self._get_crop(image, self._size) + frame_cropped = image.copy(img_crop_rect) - self._busy = False - self.busyChanged.emit() + # Convert to Y800 / GREY FourCC (single 8-bit channel) + frame_y800 = frame_cropped.convertToFormat(QImage.Format.Format_Grayscale8) + self.frame_id = 0 + # Read the QR codes from the frame + self.qrreader_res = self.qrreader.read_qr_code( + frame_y800.constBits().__int__(), + frame_y800.sizeInBytes(), + frame_y800.bytesPerLine(), + frame_y800.width(), + frame_y800.height(), + self.frame_id + ) + + if len(self.qrreader_res) > 0: + result = self.qrreader_res[0] + self._data = result + self.dataChanged.emit() - asyncio.run_coroutine_threadsafe(co_parse_qr(frame_cropped), get_asyncio_loop()) + self._busy = False + self.busyChanged.emit() def _get_crop(self, image: QImage, scan_size: int) -> QRect: - """ - Returns a QRect that is scan_size x scan_size in the middle of the resolution - """ - self.scan_pos_x = (image.width() - scan_size) // 2 - self.scan_pos_y = (image.height() - scan_size) // 2 - return QRect(self.scan_pos_x, self.scan_pos_y, scan_size, scan_size) + """Returns a QRect that is scan_size x scan_size in the middle of the resolution""" + scan_pos_x = (image.width() - scan_size) // 2 + scan_pos_y = (image.height() - scan_size) // 2 + return QRect(scan_pos_x, scan_pos_y, scan_size, scan_size) @pyqtProperty(bool, notify=busyChanged) def busy(self): return self._busy - @pyqtProperty('QImage', notify=imageChanged) - def image(self): - return self._image + @pyqtProperty(int, notify=sizeChanged) + def size(self): + return self._size @pyqtProperty(str, notify=dataChanged) def data(self): + if not self._data: + return '' return self._data.data - @pyqtProperty('QPoint', notify=dataChanged) - def center(self): - (x,y) = self._data.center - return QPoint(x+self.scan_pos_x, y+self.scan_pos_y) - - @pyqtProperty('QVariant', notify=dataChanged) - def points(self): - result = [] - for item in self._data.points: - (x,y) = item - result.append(QPoint(x+self.scan_pos_x, y+self.scan_pos_y)) - return result + @pyqtSlot() + def reset(self): + self._data = None + self.dataChanged.emit() class QEQRImageProvider(QQuickImageProvider): @@ -161,7 +158,7 @@ class QEQRImageProvider(QQuickImageProvider): # fake it modules = 17 + qr.border * 2 box_size = math.floor(pixelsize/modules) - self.qimg = QImage(box_size * modules, box_size * modules, QImage.Format_RGB32) + self.qimg = QImage(box_size * modules, box_size * modules, QImage.Format.Format_RGB32) self.qimg.fill(QColor('gray')) return self.qimg, self.qimg.size() From e561ce211b85d1a2bc3a0f8c54ef5d470e226c54 Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Mon, 2 Oct 2023 19:06:58 +0200 Subject: [PATCH 10/22] cirrus: task timeout 90m --- .cirrus.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.cirrus.yml b/.cirrus.yml index c37ad7e0c..7a5ee585f 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -182,6 +182,7 @@ task: task: name: "build: Android (QML $APK_ARCH)" + timeout_in: 90m container: dockerfile: contrib/android/Dockerfile cpu: 8 From db532dbd1973bf2d37badeeba2674fd254f1250f Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Tue, 3 Oct 2023 18:53:00 +0200 Subject: [PATCH 11/22] qml: android back-gesture conflict hack not working on qt6, replace with simple properties --- .../qml/components/controls/ElListView.qml | 39 +++++++------------ 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/electrum/gui/qml/components/controls/ElListView.qml b/electrum/gui/qml/components/controls/ElListView.qml index 60111b50e..dc31b6094 100644 --- a/electrum/gui/qml/components/controls/ElListView.qml +++ b/electrum/gui/qml/components/controls/ElListView.qml @@ -1,40 +1,27 @@ -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 2.0 -import QtQuick.Controls.Material 2.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material ListView { id: root - property int width_left_exclusion_zone: 0 - property int width_right_exclusion_zone: 0 + // avoid interference with android back-gesture by defining deadzones + // you can override to 0 if listview is away from left or right edge. + property int exclusionZone: constants.fingerWidth / 2 + property int leftExclusionZone: exclusionZone + property int rightExclusionZone: exclusionZone MouseArea { anchors {top: root.top; left: root.left; bottom: root.bottom } - visible: width_left_exclusion_zone > 0 - width: width_left_exclusion_zone + visible: leftExclusionZone > 0 + width: leftExclusionZone } MouseArea { anchors { top: root.top; right: root.right; bottom: root.bottom } - visible: width_right_exclusion_zone > 0 - width: width_right_exclusion_zone + visible: rightExclusionZone > 0 + width: rightExclusionZone } - // determine distance from sides of window and reserve some - // space using noop mouseareas in order to not emit clicks when - // android back gesture is used - function layoutExclusionZones() { - var reserve = constants.fingerWidth / 2 - var p = root.mapToGlobal(0, 0) // note: coords on whole *screen*, not just window - width_left_exclusion_zone = Math.max(0, reserve - p.x) - p = root.mapToGlobal(width, 0) - width_right_exclusion_zone = Math.max(0, reserve - (app.width - p.x)) - } - - Component.onCompleted: { - if (AppController.isAndroid()) { - layoutExclusionZones() - } - } } From be801f30e890064cbdd7610c4c3323b540ca0995 Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Thu, 5 Oct 2023 11:50:12 +0200 Subject: [PATCH 12/22] gui: make common_qt compatible with both Qt5 and Qt6 --- electrum/gui/common_qt/plugins.py | 7 ++++++- electrum/gui/qml/__init__.py | 1 + electrum/gui/qt/__init__.py | 1 + electrum/plugins/trustedcoin/common_qt.py | 6 +++++- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/electrum/gui/common_qt/plugins.py b/electrum/gui/common_qt/plugins.py index 3403be027..0934477b4 100644 --- a/electrum/gui/common_qt/plugins.py +++ b/electrum/gui/common_qt/plugins.py @@ -1,4 +1,9 @@ -from PyQt6.QtCore import pyqtSignal, pyqtProperty, QObject # TODO: common code, Qt5/Qt6 mismatch! +import sys + +if getattr(sys, '_GUI_QT_VERSION') == 5: # FIXME: remove when both desktop and mobile are Qt6 + from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject +else: + from PyQt6.QtCore import pyqtSignal, pyqtProperty, QObject from electrum.logging import get_logger diff --git a/electrum/gui/qml/__init__.py b/electrum/gui/qml/__init__.py index 53e87c2e5..35926cb70 100644 --- a/electrum/gui/qml/__init__.py +++ b/electrum/gui/qml/__init__.py @@ -16,6 +16,7 @@ except Exception: from PyQt6.QtCore import (Qt, QCoreApplication, QLocale, QTranslator, QTimer, QT_VERSION_STR, PYQT_VERSION_STR) from PyQt6.QtGui import QGuiApplication +sys._GUI_QT_VERSION = 6 # used by gui/common_qt from electrum.i18n import _ from electrum.plugin import run_hook diff --git a/electrum/gui/qt/__init__.py b/electrum/gui/qt/__init__.py index 025eca2e8..94c75fc8c 100644 --- a/electrum/gui/qt/__init__.py +++ b/electrum/gui/qt/__init__.py @@ -42,6 +42,7 @@ from PyQt5.QtGui import QGuiApplication from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QWidget, QMenu, QMessageBox from PyQt5.QtCore import QObject, pyqtSignal, QTimer, Qt import PyQt5.QtCore as QtCore +sys._GUI_QT_VERSION = 5 # used by gui/common_qt try: # Preload QtMultimedia at app start, if available. diff --git a/electrum/plugins/trustedcoin/common_qt.py b/electrum/plugins/trustedcoin/common_qt.py index c960d5240..31b9954e7 100644 --- a/electrum/plugins/trustedcoin/common_qt.py +++ b/electrum/plugins/trustedcoin/common_qt.py @@ -1,9 +1,13 @@ import threading import socket import base64 +import sys from typing import TYPE_CHECKING -from PyQt6.QtCore import pyqtSignal, pyqtProperty, pyqtSlot # TODO: common code, Qt5/Qt6 mismatch! +if getattr(sys, '_GUI_QT_VERSION') == 5: # FIXME: remove when both desktop and mobile are Qt6 + from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot +else: + from PyQt6.QtCore import pyqtSignal, pyqtProperty, pyqtSlot from electrum.i18n import _ from electrum.bip32 import BIP32Node From b9ab0f63efbd42253a92200c930caea84b8a625a Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Fri, 6 Oct 2023 10:51:35 +0200 Subject: [PATCH 13/22] qt6: update buildozer ref to ce4f2257249fdf4ff1f4cb8983fd7ac44174a274 --- contrib/android/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/android/Dockerfile b/contrib/android/Dockerfile index 53db8ab67..7a7cca23d 100644 --- a/contrib/android/Dockerfile +++ b/contrib/android/Dockerfile @@ -186,7 +186,7 @@ RUN cd /opt \ && git fetch --all \ # commit: from branch master (note: careful with force-pushing! see #8162) \ # no, this is master - && git checkout "698b48136c55b2495128207c5e98dccc128bb6c2^{commit}" \ + && git checkout "ce4f2257249fdf4ff1f4cb8983fd7ac44174a274^{commit}" \ && /opt/venv/bin/python3 -m pip install --no-build-isolation --no-dependencies -e . # install python-for-android From c33ee875443b6afe34ca21c89981e26048364caa Mon Sep 17 00:00:00 2001 From: SomberNight Date: Wed, 11 Oct 2023 10:40:24 +0000 Subject: [PATCH 14/22] android: restore SimpleScannerActivity.java that was used in kivy for QR code scanning with camera https://github.com/spesmilo/electrum/blob/1c10b1ce00aa3621a229bc9fe05d3aeb2ace7da5/electrum/gui/kivy/data/java-classes/org/electrum/qr/SimpleScannerActivity.java --- .../electrum/qr/SimpleScannerActivity.java | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 electrum/gui/qml/java_classes/org/electrum/qr/SimpleScannerActivity.java diff --git a/electrum/gui/qml/java_classes/org/electrum/qr/SimpleScannerActivity.java b/electrum/gui/qml/java_classes/org/electrum/qr/SimpleScannerActivity.java new file mode 100644 index 000000000..5dda46317 --- /dev/null +++ b/electrum/gui/qml/java_classes/org/electrum/qr/SimpleScannerActivity.java @@ -0,0 +1,90 @@ +package org.electrum.qr; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.content.Intent; +import android.Manifest; +import android.content.pm.PackageManager; + +import androidx.core.app.ActivityCompat; + +import java.util.Arrays; + +import me.dm7.barcodescanner.zxing.ZXingScannerView; + +import com.google.zxing.Result; +import com.google.zxing.BarcodeFormat; + +public class SimpleScannerActivity extends Activity implements ZXingScannerView.ResultHandler { + private static final int MY_PERMISSIONS_CAMERA = 1002; + + private ZXingScannerView mScannerView = null; + final String TAG = "org.electrum.SimpleScannerActivity"; + + @Override + public void onResume() { + super.onResume(); + if (this.hasPermission()) { + this.startCamera(); + } else { + this.requestPermission(); + } + } + + @Override + public void onPause() { + super.onPause(); + if (null != mScannerView) { + mScannerView.stopCamera(); // Stop camera on pause + } + } + + private void startCamera() { + mScannerView = new ZXingScannerView(this); // Programmatically initialize the scanner view + mScannerView.setFormats(Arrays.asList(BarcodeFormat.QR_CODE)); + setContentView(mScannerView); // Set the scanner view as the content view + mScannerView.setResultHandler(this); // Register ourselves as a handler for scan results. + mScannerView.startCamera(); // Start camera on resume + } + + @Override + public void handleResult(Result rawResult) { + Intent resultIntent = new Intent(); + resultIntent.putExtra("text", rawResult.getText()); + resultIntent.putExtra("format", rawResult.getBarcodeFormat().toString()); + setResult(Activity.RESULT_OK, resultIntent); + this.finish(); + } + + private boolean hasPermission() { + return (ActivityCompat.checkSelfPermission(this, + Manifest.permission.CAMERA) + == PackageManager.PERMISSION_GRANTED); + } + + private void requestPermission() { + ActivityCompat.requestPermissions(this, + new String[]{Manifest.permission.CAMERA}, + MY_PERMISSIONS_CAMERA); + } + + @Override + public void onRequestPermissionsResult(int requestCode, + String permissions[], int[] grantResults) { + switch (requestCode) { + case MY_PERMISSIONS_CAMERA: { + if (grantResults.length > 0 + && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + // permission was granted, yay! + this.startCamera(); + } else { + // permission denied + this.finish(); + } + return; + } + } + } + +} From 5c3e14d8def20aa0fdc5bb7a70c73edc78cbb467 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Wed, 11 Oct 2023 11:02:40 +0000 Subject: [PATCH 15/22] qml: replace Send/ScanDialog with java bases zxing qr scan activity. --- .gitignore | 3 +- contrib/android/Dockerfile | 2 +- contrib/android/buildozer_qml.spec | 22 ++++- contrib/android/make_apk.sh | 2 +- .../qml/android_res/layout/scanner_layout.xml | 29 ++++++ electrum/gui/qml/components/ScanDialog.qml | 51 ---------- electrum/gui/qml/components/SendDialog.qml | 82 ---------------- .../gui/qml/components/WalletMainView.qml | 71 ++++++-------- electrum/gui/qml/components/main.qml | 4 +- .../electrum/qr/SimpleScannerActivity.java | 61 ++++++++++-- electrum/gui/qml/qeapp.py | 2 + electrum/gui/qml/qeqrscanner.py | 96 +++++++++++++++++++ 12 files changed, 234 insertions(+), 191 deletions(-) create mode 100644 electrum/gui/qml/android_res/layout/scanner_layout.xml delete mode 100644 electrum/gui/qml/components/ScanDialog.qml delete mode 100644 electrum/gui/qml/components/SendDialog.qml create mode 100644 electrum/gui/qml/qeqrscanner.py diff --git a/.gitignore b/.gitignore index 8ac25d80a..9ade38ca3 100644 --- a/.gitignore +++ b/.gitignore @@ -12,8 +12,7 @@ electrum/locale/ packages env/ .buildozer -.buildozer_kivy/ -.buildozer_qml/ +.buildozer_*/ bin/ /app.fil .idea diff --git a/contrib/android/Dockerfile b/contrib/android/Dockerfile index 7a7cca23d..5c80325be 100644 --- a/contrib/android/Dockerfile +++ b/contrib/android/Dockerfile @@ -198,7 +198,7 @@ RUN cd /opt \ && git fetch --all \ # commit: from branch accumulator/qt6-wip (note: careful with force-pushing! see #8162) \ # - && git checkout "3b3733dbf5f461e197ba83887ac0d3b6d0f1c396^{commit}" \ + && git checkout "f2741f0b7b6a4ac52fc6cb0dc9ac706e2287be02^{commit}" \ && /opt/venv/bin/python3 -m pip install --no-build-isolation --no-dependencies -e . # build env vars diff --git a/contrib/android/buildozer_qml.spec b/contrib/android/buildozer_qml.spec index 2f85c3eb0..99f64a9c3 100644 --- a/contrib/android/buildozer_qml.spec +++ b/contrib/android/buildozer_qml.spec @@ -138,9 +138,25 @@ android.add_jars = .buildozer/android/platform/*/build/libs_collections/Electrum # (list) List of Java files to add to the android project (can be java or a # directory containing the files) -# android.add_src = ... -# android.add_activities = ... -android.gradle_dependencies = com.android.support:support-compat:28.0.0 +android.add_src = electrum/gui/qml/java_classes/ + +android.gradle_dependencies = + com.android.support:support-compat:28.0.0, + me.dm7.barcodescanner:zxing:1.9.8 + +android.add_activities = org.electrum.qr.SimpleScannerActivity + +# (list) Put these files or directories in the apk res directory. +# The option may be used in three ways, the value may contain one or zero ':' +# Some examples: +# 1) A file to add to resources, legal resource names contain ['a-z','0-9','_'] +# android.add_resources = my_icons/all-inclusive.png:drawable/all_inclusive.png +# 2) A directory, here 'legal_icons' must contain resources of one kind +# android.add_resources = legal_icons:drawable +# 3) A directory, here 'legal_resources' must contain one or more directories, +# each of a resource kind: drawable, xml, etc... +# android.add_resources = legal_resources +android.add_resources = electrum/gui/qml/android_res/layout:layout # (str) python-for-android branch to use, if not master, useful to try # not yet merged features. diff --git a/contrib/android/make_apk.sh b/contrib/android/make_apk.sh index 977148bfb..88625b0a9 100755 --- a/contrib/android/make_apk.sh +++ b/contrib/android/make_apk.sh @@ -45,7 +45,7 @@ info "apk building phase starts." # FIXME: changing "APP_PACKAGE_NAME" seems to require a clean rebuild of ".buildozer/", # to avoid that, maybe change "APP_PACKAGE_DOMAIN" instead. # So, in particular, to build a testnet apk, simply uncomment: -#export APP_PACKAGE_DOMAIN=org.electrum.testnet +export APP_PACKAGE_DOMAIN=org.electrum.testnet if [ $CI ]; then # override log level specified in buildozer.spec to "debug": diff --git a/electrum/gui/qml/android_res/layout/scanner_layout.xml b/electrum/gui/qml/android_res/layout/scanner_layout.xml new file mode 100644 index 000000000..a00bb04e9 --- /dev/null +++ b/electrum/gui/qml/android_res/layout/scanner_layout.xml @@ -0,0 +1,29 @@ + + + + + + + + +