diff --git a/contrib/android/Dockerfile b/contrib/android/Dockerfile
index d462bd4d2..73493413b 100644
--- a/contrib/android/Dockerfile
+++ b/contrib/android/Dockerfile
@@ -33,12 +33,8 @@ RUN apt -y update -qq \
ENV ANDROID_NDK_HOME="${ANDROID_HOME}/android-ndk"
-#ENV ANDROID_NDK_VERSION="23b"
-#ENV ANDROID_NDK_HASH="c6e97f9c8cfe5b7be0a9e6c15af8e7a179475b7ded23e2d1c1fa0945d6fb4382"
-#ENV ANDROID_NDK_VERSION="27d"
-#ENV ANDROID_NDK_HASH="601246087a682d1944e1e16dd85bc6e49560fe8b6d61255be2829178c8ed15d9"
-ENV ANDROID_NDK_VERSION="23d-canary"
-ENV ANDROID_NDK_HASH="6944ffc20ab018ff4ef6a403048d0a99d50a0630c3eae690c8f803c452f46f3e"
+ENV ANDROID_NDK_VERSION="28c"
+ENV ANDROID_NDK_HASH="dfb20d396df28ca02a8c708314b814a4d961dc9074f9a161932746f815aa552f"
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
@@ -48,31 +44,21 @@ ENV ANDROID_NDK_DL_URL="https://dl.google.com/android/repository/${ANDROID_NDK_A
# below disabled in favor of CI build download
# download and install Android NDK
-#RUN curl --location --progress-bar \
-# "${ANDROID_NDK_DL_URL}" \
-# --output "${ANDROID_NDK_ARCHIVE}" \
-# && echo "${ANDROID_NDK_HASH} ${ANDROID_NDK_ARCHIVE}" | sha256sum -c - \
-# && mkdir --parents "${ANDROID_NDK_HOME_V}" \
-# && unzip -q "${ANDROID_NDK_ARCHIVE}" -d "${ANDROID_HOME}" \
-# && ln -sfn "${ANDROID_NDK_HOME_V}" "${ANDROID_NDK_HOME}" \
-# && rm -rf "${ANDROID_NDK_ARCHIVE}"
-
-# temporary build using NDK from CI
-ENV CI_REV="12186248"
-ENV CI_NDK_FILE="android-ndk-${CI_REV}-linux-x86_64.zip"
-COPY contrib/android/dl-ndk-ci.sh /tmp/
-RUN /tmp/dl-ndk-ci.sh https://ci.android.com/builds/submitted/${CI_REV}/linux/latest/${CI_NDK_FILE} \
- && echo "${ANDROID_NDK_HASH} android-ndk-ci-linux-x86_64.zip" | sha256sum -c - \
+RUN curl --location --progress-bar \
+ "${ANDROID_NDK_DL_URL}" \
+ --output "${ANDROID_NDK_ARCHIVE}" \
+ && echo "${ANDROID_NDK_HASH} ${ANDROID_NDK_ARCHIVE}" | sha256sum -c - \
&& mkdir --parents "${ANDROID_NDK_HOME_V}" \
- && unzip -q "android-ndk-ci-linux-x86_64.zip" -d "${ANDROID_HOME}" \
+ && unzip -q "${ANDROID_NDK_ARCHIVE}" -d "${ANDROID_HOME}" \
&& ln -sfn "${ANDROID_NDK_HOME_V}" "${ANDROID_NDK_HOME}" \
- && rm -rf "android-ndk-ci-linux-x86_64.zip"
+ && rm -rf "${ANDROID_NDK_ARCHIVE}"
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="9477386"
-ENV ANDROID_SDK_HASH="bd1aa17c7ef10066949c88dc6c9c8d536be27f992a1f3b5a584f9bd2ba5646a0"
+ENV ANDROID_SDK_TOOLS_VERSION="14742923"
+ENV ANDROID_SDK_HASH="04453066b540409d975c676d781da1477479dde3761310f1a7eb92a1dfb15af7"
+
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}"
@@ -130,8 +116,8 @@ RUN apt -y update -qq \
RUN yes | ${ANDROID_SDK_MANAGER} --licenses > /dev/null
-ENV ANDROID_SDK_BUILD_TOOLS_MAJOR_V="31"
-ENV ANDROID_SDK_BUILD_TOOLS_VERSION="31.0.0"
+ENV ANDROID_SDK_BUILD_TOOLS_MAJOR_V="35"
+ENV ANDROID_SDK_BUILD_TOOLS_VERSION="35.0.0"
# download platforms, API, build tools
RUN ${ANDROID_SDK_MANAGER} "platforms;android-${ANDROID_SDK_BUILD_TOOLS_MAJOR_V}" > /dev/null && \
@@ -190,7 +176,6 @@ 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
@@ -250,8 +235,8 @@ RUN cd /opt \
&& /opt/venv/bin/python3 -m pip install --no-build-isolation --no-dependencies -e .
# install python-for-android
-ENV P4A_CHECKOUT_COMMIT="a01269f7799587ad74ee40e0b642d917b8db7d4e"
-# ^ from branch electrum_20251211 (note: careful with force-pushing! see #8162)
+ENV P4A_CHECKOUT_COMMIT="1098be6964cfc2156959e435e81c2c50f8398586"
+# ^ from branch electrum_202602 (note: careful with force-pushing! see #8162)
RUN cd /opt \
&& git clone https://github.com/spesmilo/python-for-android \
&& cd python-for-android \
diff --git a/contrib/android/Readme.md b/contrib/android/Readme.md
index e9ccf879b..6e348effd 100644
--- a/contrib/android/Readme.md
+++ b/contrib/android/Readme.md
@@ -108,8 +108,6 @@ Run electrum with the `-g` switch: `electrum -g qml`
Notes:
-- pyqt ~6.4 would work best, as the gui has not yet been adapted to styling changes in 6.5
-- However, pyqt6 as distributed on PyPI does not include a required module (PyQt6.QtQml) until 6.5
- Installing these deps from your OS package manager should also work,
except many don't distribute pyqt6 yet.
For pyqt5 on debian-based distros, this used to look like this:
diff --git a/contrib/android/buildozer_qml.spec b/contrib/android/buildozer_qml.spec
index 454618176..a73fdc5b8 100644
--- a/contrib/android/buildozer_qml.spec
+++ b/contrib/android/buildozer_qml.spec
@@ -105,19 +105,19 @@ android.permissions = INTERNET, CAMERA, WRITE_EXTERNAL_STORAGE, POST_NOTIFICATIO
# (int) Android API to use (compileSdkVersion)
# note: when changing, Dockerfile also needs to be changed to install corresponding build tools
-android.api = 31
+android.api = 35
# (int) Android targetSdkVersion
android.target_sdk_version = 35
# (int) Minimum API required. You will need to set the android.ndk_api to be as low as this value.
-android.minapi = 23
+android.minapi = 26
# (str) Android NDK version to use
-android.ndk = 23b
+android.ndk = 28c
# (int) Android NDK API to use (optional). This is the minimum API your app will support.
-android.ndk_api = 23
+android.ndk_api = 26
# (bool) Use --private data storage (True) or --dir public storage (False)
#android.private_storage = True
@@ -168,7 +168,7 @@ android.add_src = electrum/gui/qml/java_classes/
# kotlin-stdlib is required for zxing-cpp (BarcodeScannerView)
android.gradle_dependencies =
- com.android.support:support-compat:28.0.0,
+ androidx.core:core:1.16.0,
org.jetbrains.kotlin:kotlin-stdlib:1.8.22
android.add_activities = org.electrum.qr.SimpleScannerActivity, org.electrum.biometry.BiometricActivity
diff --git a/contrib/android/dl-ndk-ci.sh b/contrib/android/dl-ndk-ci.sh
deleted file mode 100755
index 41b1922f2..000000000
--- a/contrib/android/dl-ndk-ci.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-if [ -z "$1" ]; then
- echo "missing url"
- exit 1
-fi
-echo $1
-
-curl $1 | grep "var JSVariables" | python3 -c "import sys; line=sys.stdin.read(); line=line[line.find('{'):-2]; import json; j=json.loads(line); print(j['artifactUrl'])" | wget -i - -O android-ndk-ci-linux-x86_64.zip
diff --git a/contrib/android/p4a_recipes/android/__init__.py b/contrib/android/p4a_recipes/android/__init__.py
new file mode 100644
index 000000000..17bd29ad2
--- /dev/null
+++ b/contrib/android/p4a_recipes/android/__init__.py
@@ -0,0 +1,20 @@
+import os
+
+from pythonforandroid.recipes.android import AndroidRecipe
+from pythonforandroid.util import load_source, HashPinnedDependency
+
+util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py'))
+
+
+assert AndroidRecipe.depends == [('sdl3', 'sdl2', 'genericndkbuild', 'qt6'), 'pyjnius', 'python3'], AndroidRecipe.depends
+assert AndroidRecipe.python_depends == []
+
+
+class AndroidRecipePinned(util.InheritedRecipeMixin, AndroidRecipe):
+ hostpython_prerequisites = [
+ HashPinnedDependency(package="Cython==3.1.8",
+ hashes=['sha256:282b3c8e6abc3fea421919e862e898ffdd86fc0796009bdb5ffdf8211413219f'])
+ ]
+
+
+recipe = AndroidRecipePinned()
diff --git a/contrib/android/p4a_recipes/cffi/__init__.py b/contrib/android/p4a_recipes/cffi/__init__.py
index c96c7ac51..a5bbf2b32 100644
--- a/contrib/android/p4a_recipes/cffi/__init__.py
+++ b/contrib/android/p4a_recipes/cffi/__init__.py
@@ -6,14 +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 CffiRecipe._version == "1.15.1"
-assert CffiRecipe.depends == ['setuptools', 'pycparser', 'libffi', 'python3']
+assert CffiRecipe._version == "2.0.0"
+assert CffiRecipe.depends == ['pycparser', 'libffi', 'python3'], CffiRecipe.depends
assert CffiRecipe.python_depends == []
class CffiRecipePinned(util.InheritedRecipeMixin, CffiRecipe):
- version = "1.17.1"
- sha512sum = "907129891d56351ca5cb885aae62334ad432321826d6eddfaa32195b4c7b7689a80333e6d14d0aab479a646aba148b9852c0815b80344dfffa4f183a5e74372c"
+ sha512sum = "a71b74e642e11eb50e9bb4ae0e7116bdb3c4a7c9622a3766d84506fa7994c02e09644b41b439b95ca99b0303e91891897cff38018d498eb087e0961f0ad4fb8b"
recipe = CffiRecipePinned()
diff --git a/contrib/android/p4a_recipes/hostpython3/__init__.py b/contrib/android/p4a_recipes/hostpython3/__init__.py
index a9a1be3eb..a4a63d7bd 100644
--- a/contrib/android/p4a_recipes/hostpython3/__init__.py
+++ b/contrib/android/p4a_recipes/hostpython3/__init__.py
@@ -1,7 +1,7 @@
import os
from pythonforandroid.recipes.hostpython3 import HostPython3Recipe
-from pythonforandroid.util import load_source
+from pythonforandroid.util import load_source, HashPinnedDependency
util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py'))
@@ -13,7 +13,23 @@ assert HostPython3Recipe.python_depends == []
class HostPython3RecipePinned(util.InheritedRecipeMixin, HostPython3Recipe):
# PYTHON_VERSION= # < line here so that I can grep the codebase and teleport here
version = "3.11.14"
- sha512sum = "41fb3ae22ce4ac0e8bb6b9ae8db88a810af1001d944e3f1abc9e86824ae4be31347e3e3a70425ab12271c6b7eeef552f00164ef23cfffa2551c3c9d1fe5ab91f"
+ sha512sum = "4642f6d59c76c6e5dbd827fdb28694376a9cc76e513146d092b49afb41513b3c9dff2339cfcebfb5b260f5cdc49a59a69906e284e5d478b2189d3374e9e24fd5"
+
+ # this property overrides the default hostpython dependencies for PyProjectRecipe recipies
+ pyproject_base_dependencies = [
+ HashPinnedDependency(package="build==1.4.0",
+ hashes=['sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596']),
+ HashPinnedDependency(package="pip==24.0",
+ hashes=['sha256:ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc']),
+ HashPinnedDependency(package="setuptools==80.9.0",
+ hashes=['sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922']),
+
+ # pin deptree build==1.4.0
+ HashPinnedDependency(package="packaging==26.0",
+ hashes=['sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529']),
+ HashPinnedDependency(package="pyproject_hooks==1.2.0",
+ hashes=['sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913']),
+ ]
recipe = HostPython3RecipePinned()
diff --git a/contrib/android/p4a_recipes/openssl/__init__.py b/contrib/android/p4a_recipes/openssl/__init__.py
index fdbb7d662..062b18e58 100644
--- a/contrib/android/p4a_recipes/openssl/__init__.py
+++ b/contrib/android/p4a_recipes/openssl/__init__.py
@@ -6,7 +6,7 @@ from pythonforandroid.util import load_source
util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py'))
-assert OpenSSLRecipe._version == "3.0.18"
+# assert OpenSSLRecipe._version == "3.3.1"
assert OpenSSLRecipe.depends == []
assert OpenSSLRecipe.python_depends == []
diff --git a/contrib/android/p4a_recipes/packaging/__init__.py b/contrib/android/p4a_recipes/packaging/__init__.py
index a8f225ae2..b16d67d47 100644
--- a/contrib/android/p4a_recipes/packaging/__init__.py
+++ b/contrib/android/p4a_recipes/packaging/__init__.py
@@ -1,15 +1,13 @@
from pythonforandroid.recipes.packaging import PackagingRecipe
-assert PackagingRecipe._version == "21.3"
+assert PackagingRecipe._version == "26.0"
assert PackagingRecipe.depends == ["setuptools", "pyparsing", "python3"]
assert PackagingRecipe.python_depends == []
class PackagingRecipePinned(PackagingRecipe):
- #version = "21.3"
- # note: 21.3 is the last version to use setup.py, so newer versions don't work. see comment for PyparsingRecipePinned
- sha512sum = "2e3aa276a4229ac7dc0654d586799473ced9761a83aa4159660d37ae1a2a8f30e987248dd0e260e2834106b589f259a57ce9936eef0dcc3c430a99ac6b663e05"
+ sha512sum = "27a066a7d65ba76189212973b6a0d162f3d361848b1b0c34a82865cf180b3284a837cc34206c297f002a73feae414e25a26c5960bb884a74ea337f582585f1d2"
recipe = PackagingRecipePinned()
diff --git a/contrib/android/p4a_recipes/pycryptodomex/__init__.py b/contrib/android/p4a_recipes/pycryptodomex/__init__.py
index 0e0a580bf..0491968e5 100644
--- a/contrib/android/p4a_recipes/pycryptodomex/__init__.py
+++ b/contrib/android/p4a_recipes/pycryptodomex/__init__.py
@@ -1,5 +1,5 @@
from pythonforandroid.recipe import PythonRecipe
-
+from pythonforandroid.util import HashPinnedDependency
assert PythonRecipe.depends == ['python3']
assert PythonRecipe.python_depends == []
@@ -9,7 +9,11 @@ class PycryptodomexRecipe(PythonRecipe):
version = "3.23.0"
sha512sum = "951cebaad2e19b9f9d04fe85c73ab1ff8b515069c1e0e8e3cd6845ec9ccd5ef3e5737259e0934ed4a6536e289dee6aabac58e1c822a5a6393e86b482c60afc89"
url = "https://github.com/Legrandin/pycryptodome/archive/v{version}x.tar.gz"
- depends = ["setuptools", "cffi"]
+ depends = ["cffi"]
+ hostpython_prerequisites = [
+ HashPinnedDependency(package="setuptools==80.9.0",
+ hashes=['sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922']),
+ ]
recipe = PycryptodomexRecipe()
diff --git a/contrib/android/p4a_recipes/pyjnius/__init__.py b/contrib/android/p4a_recipes/pyjnius/__init__.py
index 16a052e0e..267f5d9a3 100644
--- a/contrib/android/p4a_recipes/pyjnius/__init__.py
+++ b/contrib/android/p4a_recipes/pyjnius/__init__.py
@@ -1,19 +1,23 @@
import os
from pythonforandroid.recipes.pyjnius import PyjniusRecipe
-from pythonforandroid.util import load_source
+from pythonforandroid.util import load_source, HashPinnedDependency
util = load_source('util', os.path.join(os.path.dirname(os.path.dirname(__file__)), 'util.py'))
-assert PyjniusRecipe._version == "1.5.0"
-assert PyjniusRecipe.depends == [('genericndkbuild', 'sdl2', 'qt6'), 'six', 'python3']
+assert PyjniusRecipe._version == "1.7.0"
+assert PyjniusRecipe.depends == [('genericndkbuild', 'sdl2', 'sdl3', 'qt6'), 'six', 'python3'], PyjniusRecipe.depends
assert PyjniusRecipe.python_depends == []
class PyjniusRecipePinned(util.InheritedRecipeMixin, PyjniusRecipe):
- version = "1.6.1"
- sha512sum = "deb5ac566479111c6f4c6adb895821b263d72bf88414fb093bdfd5ad5d0b7aea56b53d5ef0967e28db360f4fb6fb1c2264123f15c747884799df55848191c424"
+ hostpython_prerequisites = [
+ HashPinnedDependency(package="Cython==3.1.8",
+ hashes=['sha256:282b3c8e6abc3fea421919e862e898ffdd86fc0796009bdb5ffdf8211413219f'])
+ ]
+
+ sha512sum = "a192c30ef87ca9601455976feb49f03dfdb8e1bf2545744a7b771a6d0930a56b334c7a2a39d30fb8855c070f16e4673dc5ff6920b04a6155ab5f9247b271df76"
recipe = PyjniusRecipePinned()
diff --git a/contrib/android/p4a_recipes/pyparsing/__init__.py b/contrib/android/p4a_recipes/pyparsing/__init__.py
index 04f515dbc..c6a3e9e1e 100644
--- a/contrib/android/p4a_recipes/pyparsing/__init__.py
+++ b/contrib/android/p4a_recipes/pyparsing/__init__.py
@@ -1,4 +1,5 @@
from pythonforandroid.recipes.pyparsing import PyparsingRecipe
+from pythonforandroid.util import HashPinnedDependency
assert PyparsingRecipe._version == "3.0.7"
@@ -15,5 +16,12 @@ class PyparsingRecipePinned(PyparsingRecipe):
# see "PyProjectRecipe" from https://github.com/kivy/python-for-android/pull/3007
sha512sum = "1e692f4cdaa6b6e8ca2729d0a3e2ba16d978f1957c538b6de3a4220ec7d996bdbe87c41c43abab851fffa3b0498a05841373e435602917b8c095042e273badb5"
+ hostpython_prerequisites = [
+ HashPinnedDependency(package="setuptools==80.9.0",
+ hashes=['sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922']),
+ HashPinnedDependency(package="pip==24.0",
+ hashes=['sha256:ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc']),
+ ]
+
recipe = PyparsingRecipePinned()
diff --git a/contrib/android/p4a_recipes/pyqt6/__init__.py b/contrib/android/p4a_recipes/pyqt6/__init__.py
index 37b2a2119..1f08245d2 100644
--- a/contrib/android/p4a_recipes/pyqt6/__init__.py
+++ b/contrib/android/p4a_recipes/pyqt6/__init__.py
@@ -1,18 +1,18 @@
import os
from pythonforandroid.recipes.pyqt6 import PyQt6Recipe
-from pythonforandroid.util import load_source
+from pythonforandroid.util import load_source, HashPinnedDependency
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._version == "6.10.2"
+assert PyQt6Recipe.depends == ['qt6', 'pyjnius', 'setuptools', 'pyqt6sip', 'hostpython3', 'pyqt_builder', 'python3'], PyQt6Recipe.depends
assert PyQt6Recipe.python_depends == []
class PyQt6RecipePinned(util.InheritedRecipeMixin, PyQt6Recipe):
- sha512sum = "51e5f0d028ee7984876da1653cb135d61e2c402f18b939a92477888cc7c86d3bc2889477403dee6b3d9f66519ee3236d344323493b4c2c2e658e1637b10e53bf"
+ sha512sum = "d58515d181530fdd71edc3edfa0b647a3aeeb56cbc33f4d7fd0d40a7a99d52298ac5bb4438b5dadea5439759e52cc459e601f1fab5d9afdd61f2a492d0bae1ef"
recipe = PyQt6RecipePinned()
diff --git a/contrib/android/p4a_recipes/pyqt6sip/__init__.py b/contrib/android/p4a_recipes/pyqt6sip/__init__.py
index 301c15762..dea22376f 100644
--- a/contrib/android/p4a_recipes/pyqt6sip/__init__.py
+++ b/contrib/android/p4a_recipes/pyqt6sip/__init__.py
@@ -1,18 +1,25 @@
import os
from pythonforandroid.recipes.pyqt6sip import PyQt6SipRecipe
-from pythonforandroid.util import load_source
+from pythonforandroid.util import load_source, HashPinnedDependency
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._version == "13.10.3"
+assert PyQt6SipRecipe.depends == ['python3']
assert PyQt6SipRecipe.python_depends == []
class PyQt6SipRecipePinned(util.InheritedRecipeMixin, PyQt6SipRecipe):
- sha512sum = "1e4170d167a326afe6df86e4a35e209299548054981cb2e5d56da234ef9db4d8594bcb05b6be363c3bc6252776ae9de63d589a3d9f33fba8250d39cdb5e9061a"
+ sha512sum = "555b061eec3db6a66388fae07de21f58d756f6f12b13e4ede729c3348d2c8997ac5a59d3006ee45c3a09b5cde673f579265fa254bc583a4ba721748cf8f3a617"
+
+ hostpython_prerequisites = [
+ HashPinnedDependency(package="setuptools==80.9.0",
+ hashes=['sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922']),
+ HashPinnedDependency(package="packaging==26.0",
+ hashes=['sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529']),
+ ]
recipe = PyQt6SipRecipePinned()
diff --git a/contrib/android/p4a_recipes/pyqt_builder/__init__.py b/contrib/android/p4a_recipes/pyqt_builder/__init__.py
index 6b6a67488..8fa65576d 100644
--- a/contrib/android/p4a_recipes/pyqt_builder/__init__.py
+++ b/contrib/android/p4a_recipes/pyqt_builder/__init__.py
@@ -1,13 +1,14 @@
from pythonforandroid.recipes.pyqt_builder import PyQtBuilderRecipe
+from pythonforandroid.util import HashPinnedDependency
-assert PyQtBuilderRecipe._version == "1.15.1"
-assert PyQtBuilderRecipe.depends == ["sip", "packaging", "python3"]
+assert PyQtBuilderRecipe._version == "1.19.1"
+assert PyQtBuilderRecipe.depends == ["sip", "python3"], PyQtBuilderRecipe.depends
assert PyQtBuilderRecipe.python_depends == []
class PyQtBuilderRecipePinned(PyQtBuilderRecipe):
- sha512sum = "61ee73b6bb922c04739da60025ab50d35d345d2e298943305fcbd3926cda31d732cc5e5b0dbfc39f5eb85c0f0b091b8c3f5fee00dcc240d7849c5c4191c1368a"
+ sha512sum = "2308c51f93c37b1d13f312e4f2475d26b22d374ef284925fead9eab4aa89b994770431aca45170ac2154b4813fff151798f113f56d4cbf6c6e544fb463104a6d"
recipe = PyQtBuilderRecipePinned()
diff --git a/contrib/android/p4a_recipes/python3/__init__.py b/contrib/android/p4a_recipes/python3/__init__.py
index 6fc9d51e8..11cf39546 100644
--- a/contrib/android/p4a_recipes/python3/__init__.py
+++ b/contrib/android/p4a_recipes/python3/__init__.py
@@ -13,7 +13,7 @@ assert Python3Recipe.python_depends == []
class Python3RecipePinned(util.InheritedRecipeMixin, Python3Recipe):
# PYTHON_VERSION= # < line here so that I can grep the codebase and teleport here
version = "3.11.14"
- sha512sum = "41fb3ae22ce4ac0e8bb6b9ae8db88a810af1001d944e3f1abc9e86824ae4be31347e3e3a70425ab12271c6b7eeef552f00164ef23cfffa2551c3c9d1fe5ab91f"
+ sha512sum = "4642f6d59c76c6e5dbd827fdb28694376a9cc76e513146d092b49afb41513b3c9dff2339cfcebfb5b260f5cdc49a59a69906e284e5d478b2189d3374e9e24fd5"
recipe = Python3RecipePinned()
diff --git a/contrib/android/p4a_recipes/qt6/__init__.py b/contrib/android/p4a_recipes/qt6/__init__.py
index 1a91e0bf3..dcb443d9a 100644
--- a/contrib/android/p4a_recipes/qt6/__init__.py
+++ b/contrib/android/p4a_recipes/qt6/__init__.py
@@ -1,19 +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._version == "6.5.3"
+assert Qt6Recipe._version == "6.10.2"
assert Qt6Recipe.depends == ['python3', 'hostqt6']
assert Qt6Recipe.python_depends == []
+
class Qt6RecipePinned(util.InheritedRecipeMixin, Qt6Recipe):
- sha512sum = "0bdbe8b9a43390c98cf19e851ec5394bc78438d227cf9d0d7a3748aee9a32a7f14fc46f52d4fa283819f21413567080aee7225c566af5278557f5e1992674da3"
- # sha512sum = "ca8ea3b81c121886636988275f7fa8ae6d19f7be02669e63ab19b4285b611057a41279db9532c25ae87baa3904b010e1db68b899cd0eda17a5a8d3d87098b4d5"
+ sha512sum = "bf1a1d42d57b4d2e77f7227f4cbe01e847fd65035461b89481063b32f25a57be6e5a07889acc4af65ca9ff9d27b7fe63bd2fe60b8aa7fa19d554394d799fbaa1"
recipe = Qt6RecipePinned()
diff --git a/contrib/android/p4a_recipes/setuptools/__init__.py b/contrib/android/p4a_recipes/setuptools/__init__.py
deleted file mode 100644
index 10a26f398..000000000
--- a/contrib/android/p4a_recipes/setuptools/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from pythonforandroid.recipes.setuptools import SetuptoolsRecipe
-
-
-assert SetuptoolsRecipe._version == "51.3.3"
-assert SetuptoolsRecipe.depends == ['python3']
-assert SetuptoolsRecipe.python_depends == []
-
-
-class SetuptoolsRecipePinned(SetuptoolsRecipe):
- sha512sum = "5a3572466a68c6f650111448ce3343f64c62044650bb8635edbff97e2bc7b216b8bbe3b4e3bccf34e6887f3bedc911b27ca5f9a515201cae49cf44fbacf03345"
-
-
-recipe = SetuptoolsRecipePinned()
diff --git a/contrib/android/p4a_recipes/sip/__init__.py b/contrib/android/p4a_recipes/sip/__init__.py
index d1aea65e4..af6fdffb4 100644
--- a/contrib/android/p4a_recipes/sip/__init__.py
+++ b/contrib/android/p4a_recipes/sip/__init__.py
@@ -1,13 +1,18 @@
from pythonforandroid.recipes.sip import SipRecipe
+from pythonforandroid.util import HashPinnedDependency
-
-assert SipRecipe._version == "6.7.9"
-assert SipRecipe.depends == ["setuptools", "packaging", "tomli", "ply", "python3"], SipRecipe.depends
+assert SipRecipe._version == "6.15.1"
+assert SipRecipe.depends == ["python3"], SipRecipe.depends
assert SipRecipe.python_depends == []
class SipRecipePinned(SipRecipe):
- sha512sum = "bb9d0d0d92002b6fd33f7e8ebe8cd62456dacc16b5734b73760b1ba14fb9b1f2b9b6640b40196c6cf5f345e1afde48bdef39675c4d3480041771325d4cf3c233"
+ sha512sum = "30a312419ba82c0221c0cf03c3fb3ad7d45bb8fe633d1d7477025a7986b0a7f7b7b781a8d9cd6bcdb78f3b872231fd1eed123a761b497861822f2e35093f574d"
+
+ hostpython_prerequisites = [
+ HashPinnedDependency(package="setuptools==80.9.0",
+ hashes=['sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922']),
+ ]
recipe = SipRecipePinned()
diff --git a/electrum/gui/icons/closebutton.png b/electrum/gui/icons/closebutton.png
index 349241801..ecd8a0de4 100644
Binary files a/electrum/gui/icons/closebutton.png and b/electrum/gui/icons/closebutton.png differ
diff --git a/electrum/gui/icons/copy_bw.png b/electrum/gui/icons/copy_bw.png
index 739edbecb..50d75729c 100644
Binary files a/electrum/gui/icons/copy_bw.png and b/electrum/gui/icons/copy_bw.png differ
diff --git a/electrum/gui/icons/qrcode.png b/electrum/gui/icons/qrcode.png
index 41a84aa1d..3c1bf8b04 100644
Binary files a/electrum/gui/icons/qrcode.png and b/electrum/gui/icons/qrcode.png differ
diff --git a/electrum/gui/icons/qrcode_white.png b/electrum/gui/icons/qrcode_white.png
index 23ea91655..9c675be77 100644
Binary files a/electrum/gui/icons/qrcode_white.png and b/electrum/gui/icons/qrcode_white.png differ
diff --git a/electrum/gui/qml/components/AddressDetails.qml b/electrum/gui/qml/components/AddressDetails.qml
index b631e4b6b..eaf4c610e 100644
--- a/electrum/gui/qml/components/AddressDetails.qml
+++ b/electrum/gui/qml/components/AddressDetails.qml
@@ -329,6 +329,7 @@ Pane {
}
}
}
+ property color navigationBarBackgroundColor: constants.highlightBackground
AddressDetails {
id: addressdetails
diff --git a/electrum/gui/qml/components/Addresses.qml b/electrum/gui/qml/components/Addresses.qml
index aecd75415..71d441121 100644
--- a/electrum/gui/qml/components/Addresses.qml
+++ b/electrum/gui/qml/components/Addresses.qml
@@ -107,9 +107,9 @@ Pane {
Layout.fillWidth: true
Layout.fillHeight: true
- verticalPadding: 0
+ verticalPadding: bg.lineWidth
horizontalPadding: 0
- background: PaneInsetBackground {}
+ background: PaneInsetBackground { id: bg; vertical: false }
ElListView {
id: listview
@@ -249,6 +249,7 @@ Pane {
ButtonContainer {
Layout.fillWidth: true
+
FlatButton {
Layout.fillWidth: true
Layout.preferredWidth: 1
@@ -275,6 +276,7 @@ Pane {
}
}
+ property color navigationBarBackgroundColor: constants.highlightBackground
Component {
id: sectionDelegate
diff --git a/electrum/gui/qml/components/BIP39RecoveryDialog.qml b/electrum/gui/qml/components/BIP39RecoveryDialog.qml
index 6910d3de8..97e9d0a47 100644
--- a/electrum/gui/qml/components/BIP39RecoveryDialog.qml
+++ b/electrum/gui/qml/components/BIP39RecoveryDialog.qml
@@ -37,6 +37,7 @@ ElDialog {
InfoTextArea {
Layout.fillWidth: true
Layout.margins: constants.paddingMedium
+ backgroundColor: constants.darkerDialogBackground
text: bip39RecoveryListModel.state == Bip39RecoveryListModel.Scanning
? qsTr('Scanning for accounts...')
@@ -65,7 +66,9 @@ ElDialog {
verticalPadding: 0
horizontalPadding: 0
- background: PaneInsetBackground {}
+ background: PaneInsetBackground {
+ baseColor: constants.darkerDialogBackground
+ }
ColumnLayout {
spacing: 0
diff --git a/electrum/gui/qml/components/BalanceDetails.qml b/electrum/gui/qml/components/BalanceDetails.qml
index 49b92a462..03efe73e7 100644
--- a/electrum/gui/qml/components/BalanceDetails.qml
+++ b/electrum/gui/qml/components/BalanceDetails.qml
@@ -233,8 +233,8 @@ Pane {
}
}
-
}
+ property color navigationBarBackgroundColor: constants.highlightBackground
Component {
id: openChannelDialog
diff --git a/electrum/gui/qml/components/ChannelDetails.qml b/electrum/gui/qml/components/ChannelDetails.qml
index ab18e6e45..d43e1efdd 100644
--- a/electrum/gui/qml/components/ChannelDetails.qml
+++ b/electrum/gui/qml/components/ChannelDetails.qml
@@ -145,14 +145,10 @@ Pane {
Layout.fillWidth: true
Layout.preferredHeight: 1
}
- Pane {
- background: Rectangle { color: Material.dialogColor }
- padding: 0
- FlatButton {
- Layout.minimumWidth: implicitWidth
- text: channeldetails.frozenForSending ? qsTr('Unfreeze') : qsTr('Freeze')
- onClicked: channeldetails.freezeForSending()
- }
+ Button {
+ Layout.minimumWidth: implicitWidth
+ text: channeldetails.frozenForSending ? qsTr('Unfreeze') : qsTr('Freeze')
+ onClicked: channeldetails.freezeForSending()
}
}
@@ -182,14 +178,10 @@ Pane {
Layout.fillWidth: true
Layout.preferredHeight: 1
}
- Pane {
- background: Rectangle { color: Material.dialogColor }
- padding: 0
- FlatButton {
- Layout.minimumWidth: implicitWidth
- text: channeldetails.frozenForReceiving ? qsTr('Unfreeze') : qsTr('Freeze')
- onClicked: channeldetails.freezeForReceiving()
- }
+ Button {
+ Layout.minimumWidth: implicitWidth
+ text: channeldetails.frozenForReceiving ? qsTr('Unfreeze') : qsTr('Freeze')
+ onClicked: channeldetails.freezeForReceiving()
}
}
@@ -466,8 +458,8 @@ Pane {
}
}
}
-
}
+ property color navigationBarBackgroundColor: constants.highlightBackground
ChannelDetails {
id: channeldetails
diff --git a/electrum/gui/qml/components/ChannelOpenProgressDialog.qml b/electrum/gui/qml/components/ChannelOpenProgressDialog.qml
index 6179dd4c0..d251f7ee1 100644
--- a/electrum/gui/qml/components/ChannelOpenProgressDialog.qml
+++ b/electrum/gui/qml/components/ChannelOpenProgressDialog.qml
@@ -23,7 +23,7 @@ ElDialog {
property string channelBackup
- function reset() {
+ function resetDialog() {
state = ''
errorText.text = ''
peerText.text = ''
@@ -81,7 +81,7 @@ ElDialog {
}
}
- TextHighlightPane {
+ DialogHighlightPane {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: dialog.width * 3/4
Label {
@@ -100,6 +100,7 @@ ElDialog {
visible: false
iconStyle: InfoTextArea.IconStyle.Error
textFormat: TextEdit.PlainText
+ backgroundColor: constants.darkerDialogBackground
}
InfoTextArea {
@@ -108,6 +109,7 @@ ElDialog {
Layout.preferredWidth: dialog.width * 2/3
visible: false
textFormat: TextEdit.PlainText
+ backgroundColor: constants.darkerDialogBackground
}
}
diff --git a/electrum/gui/qml/components/Channels.qml b/electrum/gui/qml/components/Channels.qml
index 4369c8fbc..ea8c1283a 100644
--- a/electrum/gui/qml/components/Channels.qml
+++ b/electrum/gui/qml/components/Channels.qml
@@ -63,13 +63,10 @@ Pane {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.topMargin: constants.paddingLarge
- Layout.bottomMargin: constants.paddingLarge
- Layout.leftMargin: constants.paddingMedium
- Layout.rightMargin: constants.paddingMedium
- verticalPadding: 0
+ verticalPadding: bg.lineWidth
horizontalPadding: 0
- background: PaneInsetBackground {}
+ background: PaneInsetBackground { id: bg; vertical: false }
ColumnLayout {
spacing: 0
@@ -121,6 +118,7 @@ Pane {
ButtonContainer {
Layout.fillWidth: true
+
FlatButton {
Layout.fillWidth: true
Layout.preferredWidth: 1
@@ -157,8 +155,8 @@ Pane {
icon.source: '../../icons/lightning.png'
}
}
-
}
+ property color navigationBarBackgroundColor: constants.highlightBackground
Component {
id: openChannelDialog
diff --git a/electrum/gui/qml/components/CloseChannelDialog.qml b/electrum/gui/qml/components/CloseChannelDialog.qml
index cfae22c69..aafb51e82 100644
--- a/electrum/gui/qml/components/CloseChannelDialog.qml
+++ b/electrum/gui/qml/components/CloseChannelDialog.qml
@@ -70,7 +70,7 @@ ElDialog {
color: Material.accentColor
}
- TextHighlightPane {
+ DialogHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
@@ -91,6 +91,7 @@ ElDialog {
Layout.fillWidth: true
Layout.bottomMargin: constants.paddingLarge
text: channeldetails.messageForceClose
+ backgroundColor: constants.darkerDialogBackground
}
Label {
@@ -140,6 +141,7 @@ ElDialog {
Layout.maximumWidth: parent.width
visible: !channeldetails.isClosing && errorText.text
iconStyle: InfoTextArea.IconStyle.Error
+ backgroundColor: constants.darkerDialogBackground
}
Label {
Layout.alignment: Qt.AlignHCenter
@@ -154,17 +156,21 @@ ElDialog {
}
}
- FlatButton {
+ DialogButtonContainer {
Layout.columnSpan: 2
Layout.fillWidth: true
- text: qsTr('Close channel')
- icon.source: '../../icons/closebutton.png'
- enabled: !channeldetails.isClosing
- onClicked: {
- if (closetypegroup.checkedButton.closetype == 'local_force') {
- showBackupThenClose()
- } else {
- doCloseChannel()
+
+ FlatButton {
+ Layout.fillWidth: true
+ text: qsTr('Close channel')
+ icon.source: '../../icons/closebutton.png'
+ enabled: !channeldetails.isClosing
+ onClicked: {
+ if (closetypegroup.checkedButton.closetype == 'local_force') {
+ showBackupThenClose()
+ } else {
+ doCloseChannel()
+ }
}
}
}
diff --git a/electrum/gui/qml/components/ConfirmTxDialog.qml b/electrum/gui/qml/components/ConfirmTxDialog.qml
index f51a7f365..2faa088fa 100644
--- a/electrum/gui/qml/components/ConfirmTxDialog.qml
+++ b/electrum/gui/qml/components/ConfirmTxDialog.qml
@@ -11,7 +11,7 @@ ElDialog {
id: dialog
required property QtObject finalizer
- required property Amount satoshis
+ required property var satoshis // type: Amount
property string address
property string message
property bool showOptions: true
@@ -71,7 +71,7 @@ ElDialog {
color: Material.accentColor
}
- TextHighlightPane {
+ DialogHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
GridLayout {
@@ -122,7 +122,7 @@ ElDialog {
color: Material.accentColor
}
- TextHighlightPane {
+ DialogHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
height: feepicker.height
@@ -153,7 +153,7 @@ ElDialog {
visible: showOptions
}
- TextHighlightPane {
+ DialogHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
visible: optionstoggle.visible && !optionstoggle.collapsed
@@ -214,6 +214,7 @@ ElDialog {
visible: finalizer.warning != ''
text: finalizer.warning
iconStyle: InfoTextArea.IconStyle.Warn
+ backgroundColor: constants.darkerDialogBackground
}
ToggleLabel {
@@ -234,6 +235,7 @@ ElDialog {
Layout.columnSpan: 2
Layout.fillWidth: true
visible: finalizer.valid
+ backgroundColor: constants.darkerDialogBackground
idx: index
model: modelData
@@ -258,6 +260,7 @@ ElDialog {
Layout.columnSpan: 2
Layout.fillWidth: true
visible: finalizer.valid
+ backgroundColor: constants.darkerDialogBackground
allowShare: false
allowClickAddress: false
@@ -270,15 +273,19 @@ ElDialog {
}
}
- FlatButton {
- id: sendButton
+ DialogButtonContainer {
Layout.fillWidth: true
- text: (Daemon.currentWallet.isWatchOnly || !Daemon.currentWallet.canSignWithoutCosigner)
- ? qsTr('Finalize...')
- : qsTr('Pay...')
- icon.source: '../../icons/confirmed.png'
- enabled: finalizer.valid
- onClicked: doAccept()
+
+ FlatButton {
+ id: sendButton
+ Layout.fillWidth: true
+ text: (Daemon.currentWallet.isWatchOnly || !Daemon.currentWallet.canSignWithoutCosigner)
+ ? qsTr('Finalize...')
+ : qsTr('Pay...')
+ icon.source: '../../icons/confirmed.png'
+ enabled: finalizer.valid
+ onClicked: doAccept()
+ }
}
}
diff --git a/electrum/gui/qml/components/Constants.qml b/electrum/gui/qml/components/Constants.qml
index 95d79a479..ea08a2fac 100644
--- a/electrum/gui/qml/components/Constants.qml
+++ b/electrum/gui/qml/components/Constants.qml
@@ -29,8 +29,10 @@ Item {
property color mutedForeground: 'gray' //Qt.lighter(Material.background, 2)
property color darkerBackground: Qt.darker(Material.background, 1.20)
- property color lighterBackground: Qt.lighter(Material.background, 1.10)
property color darkerDialogBackground: Qt.darker(Material.dialogColor, 1.20)
+ property color highlightBackground: Qt.lighter(Material.background, 1.30)
+ property color dialogColor: Material.dialogColor
+ property color seedTextAreaBackground: Qt.darker(darkerDialogBackground, 1.20)
property color notificationBackground: Qt.lighter(Material.background, 1.5)
property color colorCredit: "#ff80ff80"
diff --git a/electrum/gui/qml/components/CpfpBumpFeeDialog.qml b/electrum/gui/qml/components/CpfpBumpFeeDialog.qml
index 1c8f7b127..69803bf50 100644
--- a/electrum/gui/qml/components/CpfpBumpFeeDialog.qml
+++ b/electrum/gui/qml/components/CpfpBumpFeeDialog.qml
@@ -59,7 +59,7 @@ ElDialog {
color: Material.accentColor
}
- TextHighlightPane {
+ DialogHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
height: feepicker_childinfo.height
@@ -82,7 +82,7 @@ ElDialog {
color: Material.accentColor
}
- TextHighlightPane {
+ DialogHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
@@ -159,6 +159,7 @@ ElDialog {
visible: cpfpfeebumper.warning != ''
text: cpfpfeebumper.warning
iconStyle: InfoTextArea.IconStyle.Warn
+ backgroundColor: constants.darkerDialogBackground
}
ToggleLabel {
@@ -213,13 +214,16 @@ ElDialog {
}
}
- FlatButton {
- id: sendButton
+ DialogButtonContainer {
Layout.fillWidth: true
- text: qsTr('Ok')
- icon.source: '../../icons/confirmed.png'
- enabled: cpfpfeebumper.valid
- onClicked: doAccept()
+ FlatButton {
+ id: sendButton
+ Layout.fillWidth: true
+ text: qsTr('Ok')
+ icon.source: '../../icons/confirmed.png'
+ enabled: cpfpfeebumper.valid
+ onClicked: doAccept()
+ }
}
}
}
diff --git a/electrum/gui/qml/components/ExportTxDialog.qml b/electrum/gui/qml/components/ExportTxDialog.qml
index 249f07c18..230c72dc7 100644
--- a/electrum/gui/qml/components/ExportTxDialog.qml
+++ b/electrum/gui/qml/components/ExportTxDialog.qml
@@ -39,7 +39,7 @@ ElDialog {
width: parent.width
spacing: constants.paddingMedium
- TextHighlightPane {
+ DialogHighlightPane {
Layout.fillWidth: true
Layout.leftMargin: constants.paddingMedium
Layout.rightMargin: constants.paddingMedium
@@ -61,6 +61,7 @@ ElDialog {
Layout.margins: constants.paddingLarge
visible: dialog.text_help
text: dialog.text_help
+ backgroundColor: constants.darkerDialogBackground
}
InfoTextArea {
@@ -72,11 +73,12 @@ ElDialog {
visible: dialog.text_warn
text: dialog.text_warn
iconStyle: InfoTextArea.IconStyle.Warn
+ backgroundColor: constants.darkerDialogBackground
}
}
}
- ButtonContainer {
+ DialogButtonContainer {
id: buttons
Layout.fillWidth: true
diff --git a/electrum/gui/qml/components/GenericShareDialog.qml b/electrum/gui/qml/components/GenericShareDialog.qml
index afaa75f62..b14730dc6 100644
--- a/electrum/gui/qml/components/GenericShareDialog.qml
+++ b/electrum/gui/qml/components/GenericShareDialog.qml
@@ -42,7 +42,7 @@ ElDialog {
width: parent.width
spacing: constants.paddingMedium
- TextHighlightPane {
+ DialogHighlightPane {
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
Layout.leftMargin: constants.paddingMedium
@@ -60,7 +60,7 @@ ElDialog {
Layout.bottomMargin: constants.paddingMedium
}
- TextHighlightPane {
+ DialogHighlightPane {
Layout.fillWidth: true
visible: dialog.text
@@ -84,11 +84,12 @@ ElDialog {
visible: dialog.text_help
text: dialog.text_help
Layout.fillWidth: true
+ backgroundColor: constants.darkerDialogBackground
}
}
}
- ButtonContainer {
+ DialogButtonContainer {
Layout.fillWidth: true
FlatButton {
diff --git a/electrum/gui/qml/components/History.qml b/electrum/gui/qml/components/History.qml
index c99be7599..7b2782bb7 100644
--- a/electrum/gui/qml/components/History.qml
+++ b/electrum/gui/qml/components/History.qml
@@ -14,8 +14,8 @@ Pane {
padding: 0
clip: true
- background: Rectangle {
- color: constants.darkerBackground
+ background: PaneInsetBackground {
+ vertical: false
}
ElListView {
diff --git a/electrum/gui/qml/components/ImportAddressesKeysDialog.qml b/electrum/gui/qml/components/ImportAddressesKeysDialog.qml
index e84d5e7e7..2f23cd6d7 100644
--- a/electrum/gui/qml/components/ImportAddressesKeysDialog.qml
+++ b/electrum/gui/qml/components/ImportAddressesKeysDialog.qml
@@ -84,7 +84,6 @@ ElDialog {
icon.source: '../../icons/qrcode.png'
icon.height: constants.iconSizeMedium
icon.width: constants.iconSizeMedium
- scale: 1.2
onClicked: {
var dialog = app.scanDialog.createObject(app, {
hint: Daemon.currentWallet.isWatchOnly
diff --git a/electrum/gui/qml/components/ImportChannelBackupDialog.qml b/electrum/gui/qml/components/ImportChannelBackupDialog.qml
deleted file mode 100644
index 4de22020e..000000000
--- a/electrum/gui/qml/components/ImportChannelBackupDialog.qml
+++ /dev/null
@@ -1,98 +0,0 @@
-import QtQuick
-import QtQuick.Layouts
-import QtQuick.Controls
-
-import org.electrum 1.0
-
-import "controls"
-
-ElDialog {
- id: root
-
- property bool valid: false
-
- width: parent.width
- height: parent.height
-
- padding: 0
-
- title: qsTr('Import channel backup')
- iconSource: Qt.resolvedUrl('../../icons/file.png')
-
- function verifyChannelBackup(text) {
- return valid = Daemon.currentWallet.isValidChannelBackup(text)
- }
-
- onAccepted: {
- Daemon.currentWallet.importChannelBackup(channelbackup_ta.text)
- }
-
- ColumnLayout {
- anchors.fill: parent
- spacing: 0
-
- RowLayout {
- Layout.fillWidth: true
- Layout.leftMargin: constants.paddingLarge
-
- TextArea {
- id: channelbackup_ta
- Layout.fillWidth: true
- Layout.minimumHeight: 80
- font.family: FixedFont
- focus: true
- wrapMode: TextEdit.WrapAnywhere
- onTextChanged: verifyChannelBackup(text)
- }
- ColumnLayout {
- ToolButton {
- icon.source: '../../icons/paste.png'
- icon.height: constants.iconSizeMedium
- icon.width: constants.iconSizeMedium
- onClicked: {
- channelbackup_ta.text = AppController.clipboardToText()
- }
- }
- ToolButton {
- icon.source: '../../icons/qrcode.png'
- icon.height: constants.iconSizeMedium
- icon.width: constants.iconSizeMedium
- scale: 1.2
- onClicked: {
- var dialog = app.scanDialog.createObject(app, {
- hint: qsTr('Scan a channel backup')
- })
- dialog.onFoundText.connect(function(data) {
- channelbackup_ta.text = data
- dialog.close()
- })
- dialog.open()
- }
- }
- }
- }
-
- TextArea {
- id: validationtext
- visible: text
- Layout.fillWidth: true
- Layout.leftMargin: constants.paddingLarge
-
- readOnly: true
- wrapMode: TextInput.WordWrap
- background: Rectangle {
- color: 'transparent'
- }
- }
-
- Item { Layout.preferredWidth: 1; Layout.fillHeight: true }
-
- FlatButton {
- Layout.fillWidth: true
- enabled: valid
- text: qsTr('Import')
- onClicked: doAccept()
- }
- }
-
-}
diff --git a/electrum/gui/qml/components/InvoiceDialog.qml b/electrum/gui/qml/components/InvoiceDialog.qml
index 51f41de5a..2a91e5888 100644
--- a/electrum/gui/qml/components/InvoiceDialog.qml
+++ b/electrum/gui/qml/components/InvoiceDialog.qml
@@ -10,7 +10,7 @@ import "controls"
ElDialog {
id: dialog
- property Invoice invoice
+ property var invoice // type Invoice
property bool payImmediately: false
property string broadcastTxid
@@ -24,7 +24,7 @@ ElDialog {
property bool _canMax: invoice.invoiceType == Invoice.OnchainInvoice
- property Amount _invoice_amount: invoice.amount
+ property var _invoice_amount: invoice.amount // type: Amount
ColumnLayout {
anchors.fill: parent
@@ -67,6 +67,7 @@ ElDialog {
? InfoTextArea.IconStyle.Pending
: InfoTextArea.IconStyle.Error
: InfoTextArea.IconStyle.Info
+ backgroundColor: constants.darkerDialogBackground
}
Label {
@@ -77,7 +78,7 @@ ElDialog {
color: Material.accentColor
}
- TextHighlightPane {
+ DialogHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
visible: invoice.invoiceType == Invoice.OnchainInvoice
@@ -114,7 +115,7 @@ ElDialog {
color: Material.accentColor
}
- TextHighlightPane {
+ DialogHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
@@ -137,7 +138,7 @@ ElDialog {
color: Material.accentColor
}
- TextHighlightPane {
+ DialogHighlightPane {
id: amountContainer
Layout.columnSpan: 2
@@ -294,6 +295,8 @@ ElDialog {
id: maxAmountMessage
visible: amountMax.checked && text
compact: true
+ backgroundColor: constants.darkerDialogBackground
+
Connections {
target: invoice
function onMaxAmountMessage(message) {
@@ -320,7 +323,7 @@ ElDialog {
color: Material.accentColor
}
- TextHighlightPane {
+ DialogHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
@@ -358,7 +361,7 @@ ElDialog {
color: Material.accentColor
}
- TextHighlightPane {
+ DialogHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
@@ -401,7 +404,7 @@ ElDialog {
visible: 'r' in invoice.lnprops && invoice.lnprops.r.length
model: invoice.lnprops.r
- TextHighlightPane {
+ DialogHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
@@ -428,7 +431,7 @@ ElDialog {
color: Material.accentColor
}
- TextHighlightPane {
+ DialogHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
visible: invoice.invoiceType == Invoice.LightningInvoice && invoice.address
@@ -458,7 +461,7 @@ ElDialog {
}
}
- ButtonContainer {
+ DialogButtonContainer {
Layout.fillWidth: true
FlatButton {
diff --git a/electrum/gui/qml/components/Invoices.qml b/electrum/gui/qml/components/Invoices.qml
index e57223fd9..513449f0d 100644
--- a/electrum/gui/qml/components/Invoices.qml
+++ b/electrum/gui/qml/components/Invoices.qml
@@ -18,7 +18,6 @@ Pane {
ColumnLayout {
Layout.fillWidth: true
- Layout.margins: constants.paddingLarge
InfoTextArea {
Layout.fillWidth: true
@@ -32,9 +31,9 @@ Pane {
}
Frame {
- background: PaneInsetBackground {}
+ background: PaneInsetBackground {id: bg; vertical: false}
- verticalPadding: 0
+ verticalPadding: bg.lineWidth
horizontalPadding: 0
Layout.fillHeight: true
Layout.fillWidth: true
@@ -87,6 +86,7 @@ Pane {
ButtonContainer {
Layout.fillWidth: true
+
FlatButton {
Layout.fillWidth: true
Layout.preferredWidth: 1
@@ -112,4 +112,6 @@ Pane {
}
}
}
+ property color navigationBarBackgroundColor: constants.highlightBackground
+
}
diff --git a/electrum/gui/qml/components/LnurlPayRequestDialog.qml b/electrum/gui/qml/components/LnurlPayRequestDialog.qml
index 338dc08d8..da2a9f857 100644
--- a/electrum/gui/qml/components/LnurlPayRequestDialog.qml
+++ b/electrum/gui/qml/components/LnurlPayRequestDialog.qml
@@ -13,7 +13,7 @@ ElDialog {
title: qsTr('LNURL Payment request')
iconSource: '../../../icons/link.png'
- property InvoiceParser invoiceParser
+ property var invoiceParser // type: InvoiceParser
padding: 0
needsSystemBarPadding: false
@@ -43,6 +43,7 @@ ElDialog {
compact: true
visible: invoiceParser.lnurlData['min_sendable_sat'] != invoiceParser.lnurlData['max_sendable_sat']
text: qsTr('Amount must be between %1 and %2 %3').arg(Config.formatSats(invoiceParser.lnurlData['min_sendable_sat'])).arg(Config.formatSats(invoiceParser.lnurlData['max_sendable_sat'])).arg(Config.baseUnit)
+ backgroundColor: constants.darkerDialogBackground
}
Label {
@@ -129,15 +130,18 @@ ElDialog {
}
}
- FlatButton {
+ DialogButtonContainer {
Layout.topMargin: constants.paddingLarge
Layout.fillWidth: true
- text: qsTr('Pay...')
- icon.source: '../../icons/confirmed.png'
- enabled: valid
- onClicked: {
- invoiceParser.lnurlGetInvoice(comment.text)
- dialog.close()
+ FlatButton {
+ Layout.fillWidth: true
+ text: qsTr('Pay...')
+ icon.source: '../../icons/confirmed.png'
+ enabled: valid
+ onClicked: {
+ invoiceParser.lnurlGetInvoice(comment.text)
+ dialog.close()
+ }
}
}
}
diff --git a/electrum/gui/qml/components/LnurlWithdrawRequestDialog.qml b/electrum/gui/qml/components/LnurlWithdrawRequestDialog.qml
index d5a84c6f1..e68c3843a 100644
--- a/electrum/gui/qml/components/LnurlWithdrawRequestDialog.qml
+++ b/electrum/gui/qml/components/LnurlWithdrawRequestDialog.qml
@@ -13,8 +13,8 @@ ElDialog {
title: qsTr('LNURL Withdraw request')
iconSource: '../../../icons/link.png'
- property Wallet wallet: Daemon.currentWallet
- property RequestDetails requestDetails
+ property var wallet: Daemon.currentWallet // type: Wallet
+ property var requestDetails // type: RequestDetails
padding: 0
needsSystemBarPadding: false
@@ -50,6 +50,7 @@ ElDialog {
ColumnLayout {
width: parent.width
+ spacing: 0
GridLayout {
id: rootLayout
@@ -75,6 +76,7 @@ ElDialog {
+ '\n\n'
+ qsTr('Do a submarine swap in the \'Channels\' tab to get more incoming liquidity.')
iconStyle: InfoTextArea.IconStyle.Error
+ backgroundColor: constants.darkerDialogBackground
}
InfoTextArea {
@@ -83,9 +85,10 @@ ElDialog {
compact: true
visible: !dialog.insufficientLiquidity && dialog.providerMinWithdrawable != dialog.providerMaxWithdrawable
text: qsTr('Amount must be between %1 and %2 %3')
- .arg(Config.formatSats(dialog.effectiveMinWithdrawable))
- .arg(Config.formatSats(dialog.effectiveMaxWithdrawable))
- .arg(Config.baseUnit)
+ .arg(Config.formatSats(dialog.effectiveMinWithdrawable))
+ .arg(Config.formatSats(dialog.effectiveMaxWithdrawable))
+ .arg(Config.baseUnit)
+ backgroundColor: constants.darkerDialogBackground
}
InfoTextArea {
@@ -99,6 +102,7 @@ ElDialog {
+ ' '
+ qsTr('You may need to do a submarine swap to increase your incoming liquidity.')
iconStyle: InfoTextArea.IconStyle.Warn
+ backgroundColor: constants.darkerDialogBackground
}
Label {
@@ -160,16 +164,19 @@ ElDialog {
}
}
- FlatButton {
+ DialogButtonContainer {
Layout.topMargin: constants.paddingLarge
Layout.fillWidth: true
- text: qsTr('Withdraw...')
- icon.source: '../../icons/confirmed.png'
- enabled: valid && !requestDetails.busy
- onClicked: {
- var satsAmount = amountBtc.textAsSats.satsInt;
- requestDetails.lnurlRequestWithdrawal(satsAmount);
- dialog.close();
+ FlatButton {
+ Layout.fillWidth: true
+ text: qsTr('Withdraw...')
+ icon.source: '../../icons/confirmed.png'
+ enabled: valid && !requestDetails.busy
+ onClicked: {
+ var satsAmount = amountBtc.textAsSats.satsInt;
+ requestDetails.lnurlRequestWithdrawal(satsAmount);
+ dialog.close();
+ }
}
}
}
diff --git a/electrum/gui/qml/components/MessageDialog.qml b/electrum/gui/qml/components/MessageDialog.qml
index a2211ff75..4452b3baa 100644
--- a/electrum/gui/qml/components/MessageDialog.qml
+++ b/electrum/gui/qml/components/MessageDialog.qml
@@ -46,8 +46,13 @@ ElDialog {
}
}
- ButtonContainer {
+ DialogButtonContainer {
Layout.fillWidth: true
+ function beforeLayout() {
+ if (!dialog.text) {
+ headerComponent = null
+ }
+ }
FlatButton {
Layout.fillWidth: true
diff --git a/electrum/gui/qml/components/NetworkOverview.qml b/electrum/gui/qml/components/NetworkOverview.qml
index 12ffdc65a..ffb893c1c 100644
--- a/electrum/gui/qml/components/NetworkOverview.qml
+++ b/electrum/gui/qml/components/NetworkOverview.qml
@@ -314,6 +314,7 @@ Pane {
}
}
}
+ property color navigationBarBackgroundColor: constants.highlightBackground
Component {
id: serverConfig
diff --git a/electrum/gui/qml/components/NostrConfigDialog.qml b/electrum/gui/qml/components/NostrConfigDialog.qml
index f53646826..0eb6cfd86 100644
--- a/electrum/gui/qml/components/NostrConfigDialog.qml
+++ b/electrum/gui/qml/components/NostrConfigDialog.qml
@@ -50,21 +50,25 @@ ElDialog {
Layout.fillHeight: true
Layout.leftMargin: constants.paddingLarge
Layout.rightMargin: constants.paddingLarge
+ Layout.bottomMargin: constants.paddingLarge
- TextHighlightPane {
+ InfoTextArea {
Layout.fillWidth: true
- Label {
- text: qsTr('Enter the list of Nostr relays') + '
' +
- qsTr('Nostr relays are used to send and receive submarine swap offers.') +
- ' ' + qsTr('For multisig wallets, nostr is also used to relay transactions to your co-signers.') +
- ' ' + qsTr('Connections to nostr are only made when required, and ephemerally.')
- width: parent.width
- wrapMode: Text.Wrap
- }
+ Layout.bottomMargin: constants.paddingLarge
+ compact: true
+ text: qsTr('Nostr relays are used to send and receive submarine swap offers.') +
+ ' ' + qsTr('For multisig wallets, nostr is also used to relay transactions to your co-signers.') +
+ ' ' + qsTr('Connections to nostr are only made when required, and ephemerally.')
+ backgroundColor: constants.darkerDialogBackground
+ }
+
+ Label {
+ text: qsTr('Enter the list of Nostr relays')
}
RowLayout {
Layout.fillWidth: true
+ Layout.topMargin: constants.paddingLarge
ElTextArea {
id: relays_ta
Layout.fillWidth: true
@@ -96,14 +100,18 @@ ElDialog {
}
}
- FlatButton {
+ DialogButtonContainer {
Layout.fillWidth: true
- text: qsTr('Ok')
- enabled: valid
- icon.source: '../../icons/confirmed.png'
- onClicked: {
- Config.nostrRelays = clean_array(relays_ta.text).join(",")
- rootItem.close()
+
+ FlatButton {
+ Layout.fillWidth: true
+ text: qsTr('Ok')
+ enabled: valid
+ icon.source: '../../icons/confirmed.png'
+ onClicked: {
+ Config.nostrRelays = clean_array(relays_ta.text).join(",")
+ rootItem.close()
+ }
}
}
}
diff --git a/electrum/gui/qml/components/OpenChannelDialog.qml b/electrum/gui/qml/components/OpenChannelDialog.qml
index 97d709b52..a9b6f3d31 100644
--- a/electrum/gui/qml/components/OpenChannelDialog.qml
+++ b/electrum/gui/qml/components/OpenChannelDialog.qml
@@ -55,6 +55,7 @@ ElDialog {
'\n\n',
qsTr('If you want to have recoverable channels, you must create a new wallet with an Electrum seed')
].join('')
+ backgroundColor: constants.darkerDialogBackground
}
InfoTextArea {
@@ -65,80 +66,79 @@ ElDialog {
text: [ qsTr('You currently have recoverable channels setting disabled.'),
qsTr('This means your channels cannot be recovered from seed.')
].join(' ')
- }
-
- Label {
- text: qsTr('Node')
- Layout.columnSpan: 3
- color: Material.accentColor
+ backgroundColor: constants.darkerDialogBackground
}
// gossip
- TextArea {
- id: node
- visible: Config.useGossip
- Layout.columnSpan: 2
- Layout.fillWidth: true
- font.family: FixedFont
- wrapMode: Text.Wrap
- placeholderText: qsTr('Paste or scan node uri/pubkey')
- inputMethodHints: Qt.ImhSensitiveData | Qt.ImhNoPredictiveText | Qt.ImhNoAutoUppercase
- onTextChanged: {
- if (activeFocus)
- channelopener.connectStr = text
- }
- onActiveFocusChanged: {
- if (!activeFocus)
- channelopener.connectStr = text
- }
- }
-
RowLayout {
+ Layout.columnSpan: 3
visible: Config.useGossip
spacing: 0
- ToolButton {
- icon.source: '../../icons/paste.png'
- icon.height: constants.iconSizeMedium
- icon.width: constants.iconSizeMedium
- onClicked: {
- var cliptext = AppController.clipboardToText()
- if (!cliptext)
- return
- if (channelopener.validateConnectString(cliptext)) {
- channelopener.connectStr = cliptext
- node.text = channelopener.connectStr
- } else {
- var dialog = app.messageDialog.createObject(app, {
- text: qsTr('Invalid node-id or connect string')
+
+ TextArea {
+ id: nodeUri
+ visible: Config.useGossip
+ Layout.fillWidth: true
+ Layout.minimumHeight: nodeUriFontMetrics.lineSpacing * 4 + topPadding + bottomPadding
+ Layout.topMargin: constants.paddingSmall
+ font.family: FixedFont
+ wrapMode: Text.Wrap
+ placeholderText: qsTr('Paste or scan node uri/pubkey')
+ inputMethodHints: Qt.ImhSensitiveData | Qt.ImhNoPredictiveText | Qt.ImhNoAutoUppercase
+ onTextChanged: {
+ if (activeFocus)
+ channelopener.connectStr = text
+ }
+ onActiveFocusChanged: {
+ if (!activeFocus)
+ channelopener.connectStr = text
+ }
+ }
+ ColumnLayout {
+ spacing: 0
+ ToolButton {
+ icon.source: '../../icons/paste.png'
+ icon.height: constants.iconSizeMedium
+ icon.width: constants.iconSizeMedium
+ onClicked: {
+ var cliptext = AppController.clipboardToText()
+ if (!cliptext)
+ return
+ if (channelopener.validateConnectString(cliptext)) {
+ channelopener.connectStr = cliptext
+ nodeUri.text = channelopener.connectStr
+ } else {
+ var dialog = app.messageDialog.createObject(app, {
+ text: qsTr('Invalid node-id or connect string')
+ })
+ dialog.open()
+ }
+ }
+ }
+ ToolButton {
+ icon.source: '../../icons/qrcode.png'
+ icon.height: constants.iconSizeMedium
+ icon.width: constants.iconSizeMedium
+ onClicked: {
+ var dialog = app.scanDialog.createObject(app, {
+ hint: qsTr('Scan a node-id or a connect string')
+ })
+ dialog.onFoundText.connect(function(data) {
+ if (channelopener.validateConnectString(data)) {
+ channelopener.connectStr = data
+ nodeUri.text = channelopener.connectStr
+ } else {
+ var errdialog = app.messageDialog.createObject(app, {
+ text: qsTr('Invalid node-id or connect string')
+ })
+ errdialog.open()
+ }
+ dialog.close()
})
dialog.open()
}
}
}
- ToolButton {
- icon.source: '../../icons/qrcode.png'
- icon.height: constants.iconSizeMedium
- icon.width: constants.iconSizeMedium
- scale: 1.2
- onClicked: {
- var dialog = app.scanDialog.createObject(app, {
- hint: qsTr('Scan a node-id or a connect string')
- })
- dialog.onFoundText.connect(function(data) {
- if (channelopener.validateConnectString(data)) {
- channelopener.connectStr = data
- node.text = channelopener.connectStr
- } else {
- var errdialog = app.messageDialog.createObject(app, {
- text: qsTr('Invalid node-id or connect string')
- })
- errdialog.open()
- }
- dialog.close()
- })
- dialog.open()
- }
- }
}
// trampoline
@@ -160,11 +160,7 @@ ElDialog {
}
}
- Label {
- text: qsTr('Amount')
- Layout.columnSpan: 3
- color: Material.accentColor
- }
+ Item { Layout.columnSpan: 3; width: 1; height: constants.paddingLarge }
BtcField {
id: amountBtc
@@ -238,17 +234,21 @@ ElDialog {
text: channelopener.warning
visible: text
compact: true
+ backgroundColor: constants.darkerDialogBackground
}
}
}
- FlatButton {
+ DialogButtonContainer {
Layout.fillWidth: true
- text: qsTr('Open Channel...')
- icon.source: '../../icons/confirmed.png'
- enabled: channelopener.valid
- onClicked: channelopener.openChannel()
+ FlatButton {
+ Layout.fillWidth: true
+ text: qsTr('Open Channel...')
+ icon.source: '../../icons/confirmed.png'
+ enabled: channelopener.valid
+ onClicked: channelopener.openChannel()
+ }
}
}
@@ -298,7 +298,7 @@ ElDialog {
}
onChannelOpening: (peer) => {
console.log('Channel is opening')
- app.channelOpenProgressDialog.reset()
+ app.channelOpenProgressDialog.resetDialog()
app.channelOpenProgressDialog.peer = peer
app.channelOpenProgressDialog.open()
}
@@ -327,4 +327,8 @@ ElDialog {
id: amountFontMetrics
font: amountBtc.font
}
+ FontMetrics {
+ id: nodeUriFontMetrics
+ font: nodeUri.font
+ }
}
diff --git a/electrum/gui/qml/components/OpenWalletDialog.qml b/electrum/gui/qml/components/OpenWalletDialog.qml
index 51ec37e61..dbc5dad70 100644
--- a/electrum/gui/qml/components/OpenWalletDialog.qml
+++ b/electrum/gui/qml/components/OpenWalletDialog.qml
@@ -41,23 +41,20 @@ ElDialog {
InfoTextArea {
id: notice
+ Layout.fillWidth: true
+ Layout.bottomMargin: constants.paddingSmall
text: Daemon.singlePasswordEnabled || isStartup
? qsTr('Please enter password')
: qsTr('Wallet %1 requires password to unlock').arg(name)
- iconStyle: InfoTextArea.IconStyle.Warn
- Layout.fillWidth: true
- }
-
- Label {
- text: qsTr('Password')
- Layout.fillWidth: true
- color: Material.accentColor
+ compact: true
+ iconStyle: InfoTextArea.IconStyle.Info
+ backgroundColor: constants.darkerDialogBackground
}
PasswordField {
id: password
Layout.fillWidth: true
- Layout.leftMargin: constants.paddingXLarge
+ placeholderText: qsTr('Password')
onTextChanged: {
unlockButton.enabled = true
@@ -77,16 +74,19 @@ ElDialog {
}
}
- FlatButton {
- id: unlockButton
+ DialogButtonContainer {
Layout.fillWidth: true
- icon.source: '../../icons/unlock.png'
- text: qsTr("Unlock")
- onClicked: {
- unlock()
+
+ FlatButton {
+ id: unlockButton
+ Layout.fillWidth: true
+ icon.source: '../../icons/unlock.png'
+ text: qsTr("Unlock")
+ onClicked: {
+ unlock()
+ }
}
}
-
}
function unlock() {
diff --git a/electrum/gui/qml/components/PasswordDialog.qml b/electrum/gui/qml/components/PasswordDialog.qml
index 550f00b23..9f8c0bf19 100644
--- a/electrum/gui/qml/components/PasswordDialog.qml
+++ b/electrum/gui/qml/components/PasswordDialog.qml
@@ -39,32 +39,23 @@ ElDialog {
text: infotext
Layout.bottomMargin: constants.paddingMedium
Layout.fillWidth: true
- }
-
- Label {
- Layout.fillWidth: true
- text: qsTr('Password')
- color: Material.accentColor
+ backgroundColor: constants.darkerDialogBackground
+ compact: true
}
PasswordField {
id: pw_1
- Layout.leftMargin: constants.paddingXLarge
- }
-
- Label {
- Layout.fillWidth: true
- text: qsTr('Password (again)')
- visible: confirmPassword
- color: Material.accentColor
+ Layout.bottomMargin: constants.paddingSmall
+ placeholderText: qsTr('Password')
}
PasswordField {
id: pw_2
- Layout.leftMargin: constants.paddingXLarge
+ Layout.bottomMargin: constants.paddingSmall
visible: confirmPassword
showReveal: false
echoMode: pw_1.echoMode
+ placeholderText: qsTr('Password (again)')
}
RowLayout {
@@ -82,7 +73,7 @@ ElDialog {
}
PasswordStrengthIndicator {
- Layout.fillWidth: true
+ Layout.preferredWidth: passworddialog.width / 2
password: pw_1.text
}
}
@@ -98,13 +89,17 @@ ElDialog {
}
}
- FlatButton {
+ DialogButtonContainer {
Layout.fillWidth: true
- text: qsTr("Ok")
- icon.source: '../../icons/confirmed.png'
- enabled: confirmPassword ? pw_1.text.length >= 6 && pw_1.text == pw_2.text : true
- onClicked: {
- passwordEntered(pw_1.text)
+
+ FlatButton {
+ Layout.fillWidth: true
+ text: qsTr("Ok")
+ icon.source: '../../icons/confirmed.png'
+ enabled: confirmPassword ? pw_1.text.length >= 6 && pw_1.text == pw_2.text : true
+ onClicked: {
+ passwordEntered(pw_1.text)
+ }
}
}
}
diff --git a/electrum/gui/qml/components/ProxyConfigDialog.qml b/electrum/gui/qml/components/ProxyConfigDialog.qml
index c3d6bf31b..fb31db19f 100644
--- a/electrum/gui/qml/components/ProxyConfigDialog.qml
+++ b/electrum/gui/qml/components/ProxyConfigDialog.qml
@@ -32,13 +32,17 @@ ElDialog {
Item { Layout.fillHeight: true; Layout.preferredWidth: 1 }
- FlatButton {
+ DialogButtonContainer {
Layout.fillWidth: true
- text: qsTr('Ok')
- icon.source: '../../icons/confirmed.png'
- onClicked: {
- Network.proxy = proxyconfig.toProxyDict()
- rootItem.close()
+
+ FlatButton {
+ Layout.fillWidth: true
+ text: qsTr('Ok')
+ icon.source: '../../icons/confirmed.png'
+ onClicked: {
+ Network.proxy = proxyconfig.toProxyDict()
+ rootItem.close()
+ }
}
}
}
diff --git a/electrum/gui/qml/components/RbfBumpFeeDialog.qml b/electrum/gui/qml/components/RbfBumpFeeDialog.qml
index 4d9fdcf9c..f3e5fcdf6 100644
--- a/electrum/gui/qml/components/RbfBumpFeeDialog.qml
+++ b/electrum/gui/qml/components/RbfBumpFeeDialog.qml
@@ -46,6 +46,7 @@ ElDialog {
Layout.fillWidth: true
Layout.bottomMargin: constants.paddingLarge
text: qsTr('Move the slider to increase your transaction\'s fee. This will improve its position in the mempool')
+ backgroundColor: constants.darkerDialogBackground
}
Label {
@@ -107,7 +108,7 @@ ElDialog {
color: Material.accentColor
}
- TextHighlightPane {
+ DialogHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
height: feepicker.height
@@ -127,7 +128,7 @@ ElDialog {
color: Material.accentColor
}
- TextHighlightPane {
+ DialogHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
visible: !optionstoggle.collapsed
@@ -167,6 +168,7 @@ ElDialog {
iconStyle: InfoTextArea.IconStyle.Warn
visible: rbffeebumper.warning != ''
text: rbffeebumper.warning
+ backgroundColor: constants.darkerDialogBackground
}
ToggleLabel {
@@ -221,13 +223,17 @@ ElDialog {
}
}
- FlatButton {
- id: sendButton
+ DialogButtonContainer {
Layout.fillWidth: true
- text: qsTr('Ok')
- icon.source: '../../icons/confirmed.png'
- enabled: rbffeebumper.valid
- onClicked: doAccept()
+
+ FlatButton {
+ id: sendButton
+ Layout.fillWidth: true
+ text: qsTr('Ok')
+ icon.source: '../../icons/confirmed.png'
+ enabled: rbffeebumper.valid
+ onClicked: doAccept()
+ }
}
}
}
diff --git a/electrum/gui/qml/components/RbfCancelDialog.qml b/electrum/gui/qml/components/RbfCancelDialog.qml
index b8832b10d..5e9b5d7b6 100644
--- a/electrum/gui/qml/components/RbfCancelDialog.qml
+++ b/electrum/gui/qml/components/RbfCancelDialog.qml
@@ -43,6 +43,7 @@ ElDialog {
Layout.fillWidth: true
Layout.bottomMargin: constants.paddingLarge
text: qsTr('Cancel an unconfirmed transaction by double-spending its inputs back to your wallet with a higher fee.')
+ backgroundColor: constants.darkerDialogBackground
}
Label {
@@ -79,7 +80,7 @@ ElDialog {
color: Material.accentColor
}
- TextHighlightPane {
+ DialogHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true
height: feepicker.height
@@ -99,6 +100,7 @@ ElDialog {
iconStyle: InfoTextArea.IconStyle.Warn
visible: txcanceller.warning != ''
text: txcanceller.warning
+ backgroundColor: constants.darkerDialogBackground
}
ToggleLabel {
@@ -153,13 +155,17 @@ ElDialog {
}
}
- FlatButton {
- id: confirmButton
+ DialogButtonContainer {
Layout.fillWidth: true
- text: qsTr('Ok')
- icon.source: '../../icons/confirmed.png'
- enabled: txcanceller.valid
- onClicked: doAccept()
+
+ FlatButton {
+ id: confirmButton
+ Layout.fillWidth: true
+ text: qsTr('Ok')
+ icon.source: '../../icons/confirmed.png'
+ enabled: txcanceller.valid
+ onClicked: doAccept()
+ }
}
}
}
diff --git a/electrum/gui/qml/components/ReceiveDetailsDialog.qml b/electrum/gui/qml/components/ReceiveDetailsDialog.qml
index c29df76b9..964bdd2d0 100644
--- a/electrum/gui/qml/components/ReceiveDetailsDialog.qml
+++ b/electrum/gui/qml/components/ReceiveDetailsDialog.qml
@@ -95,7 +95,7 @@ ElDialog {
}
}
- ButtonContainer {
+ DialogButtonContainer {
Layout.fillWidth: true
FlatButton {
diff --git a/electrum/gui/qml/components/ReceiveDialog.qml b/electrum/gui/qml/components/ReceiveDialog.qml
index 19982d05f..b7ebf3cc9 100644
--- a/electrum/gui/qml/components/ReceiveDialog.qml
+++ b/electrum/gui/qml/components/ReceiveDialog.qml
@@ -50,7 +50,7 @@ ElDialog {
width: parent.width
spacing: constants.paddingMedium
- TextHighlightPane {
+ DialogHighlightPane {
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
@@ -143,7 +143,7 @@ ElDialog {
}
- ButtonContainer {
+ DialogButtonContainer {
id: buttons
Layout.fillWidth: true
diff --git a/electrum/gui/qml/components/ReceiveRequests.qml b/electrum/gui/qml/components/ReceiveRequests.qml
index c6792fdd1..e389a48b1 100644
--- a/electrum/gui/qml/components/ReceiveRequests.qml
+++ b/electrum/gui/qml/components/ReceiveRequests.qml
@@ -21,7 +21,6 @@ Pane {
ColumnLayout {
Layout.fillWidth: true
- Layout.margins: constants.paddingLarge
InfoTextArea {
Layout.fillWidth: true
@@ -31,13 +30,13 @@ Pane {
}
Heading {
- text: qsTr('Pending requests')
+ text: qsTr('Pending payment requests')
}
Frame {
- background: PaneInsetBackground {}
+ background: PaneInsetBackground {id: bg; vertical: false}
- verticalPadding: 0
+ verticalPadding: bg.lineWidth
horizontalPadding: 0
Layout.fillHeight: true
Layout.fillWidth: true
@@ -108,4 +107,5 @@ Pane {
}
}
}
+ property color navigationBarBackgroundColor: constants.highlightBackground
}
diff --git a/electrum/gui/qml/components/ScanDialog.qml b/electrum/gui/qml/components/ScanDialog.qml
index d8e4ed93a..8b6b3d750 100644
--- a/electrum/gui/qml/components/ScanDialog.qml
+++ b/electrum/gui/qml/components/ScanDialog.qml
@@ -6,7 +6,8 @@ import org.electrum
import "controls"
-// currently not used on android, kept for future use when qt6 camera stops crashing
+// currently not used on android, kept for testing on desktop, and future use
+// on android when qt6 camera support becomes usable (i.e. stops crashing)
ElDialog {
id: scanDialog
@@ -50,4 +51,6 @@ ElDialog {
onClicked: doReject()
}
}
+
+ onClosed: destroy()
}
diff --git a/electrum/gui/qml/components/SendDialog.qml b/electrum/gui/qml/components/SendDialog.qml
index e17c45ce4..6244823f8 100644
--- a/electrum/gui/qml/components/SendDialog.qml
+++ b/electrum/gui/qml/components/SendDialog.qml
@@ -11,8 +11,8 @@ import "controls"
ElDialog {
id: dialog
- property InvoiceParser invoiceParser
- property PIResolver piResolver
+ property var invoiceParser // type: InvoiceParser
+ property var piResolver // type: PIResolver
signal txFound(data: string)
signal channelBackupFound(data: string)
@@ -66,7 +66,7 @@ ElDialog {
}
}
- ButtonContainer {
+ DialogButtonContainer {
Layout.fillWidth: true
FlatButton {
diff --git a/electrum/gui/qml/components/ServerConfigDialog.qml b/electrum/gui/qml/components/ServerConfigDialog.qml
index 9fed62953..688cf0f54 100644
--- a/electrum/gui/qml/components/ServerConfigDialog.qml
+++ b/electrum/gui/qml/components/ServerConfigDialog.qml
@@ -26,27 +26,31 @@ ElDialog {
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
- Layout.leftMargin: constants.paddingLarge
- Layout.rightMargin: constants.paddingLarge
ServerConfig {
id: serverconfig
Layout.fillWidth: true
Layout.fillHeight: true
+ Layout.leftMargin: constants.paddingLarge
+ Layout.rightMargin: constants.paddingLarge
}
}
- FlatButton {
+ DialogButtonContainer {
Layout.fillWidth: true
- text: qsTr('Ok')
- enabled: serverconfig.addressValid
- icon.source: '../../icons/confirmed.png'
- onClicked: {
- let auto_connect = serverconfig.serverConnectMode == ServerConnectModeComboBox.Mode.Autoconnect
- let server = serverconfig.address
- let one_server = serverconfig.serverConnectMode == ServerConnectModeComboBox.Mode.Single
- Network.setServerParameters(server, auto_connect, one_server)
- rootItem.close()
+
+ FlatButton {
+ Layout.fillWidth: true
+ text: qsTr('Ok')
+ enabled: serverconfig.addressValid
+ icon.source: '../../icons/confirmed.png'
+ onClicked: {
+ let auto_connect = serverconfig.serverConnectMode == ServerConnectModeComboBox.Mode.Autoconnect
+ let server = serverconfig.address
+ let one_server = serverconfig.serverConnectMode == ServerConnectModeComboBox.Mode.Single
+ Network.setServerParameters(server, auto_connect, one_server)
+ rootItem.close()
+ }
}
}
}
diff --git a/electrum/gui/qml/components/SignVerifyMessageDialog.qml b/electrum/gui/qml/components/SignVerifyMessageDialog.qml
index 4a6321bac..a37ce2c78 100644
--- a/electrum/gui/qml/components/SignVerifyMessageDialog.qml
+++ b/electrum/gui/qml/components/SignVerifyMessageDialog.qml
@@ -179,8 +179,9 @@ ElDialog {
}
}
- ButtonContainer {
+ DialogButtonContainer {
Layout.fillWidth: true
+
FlatButton {
Layout.fillWidth: true
Layout.preferredWidth: 1
diff --git a/electrum/gui/qml/components/SwapDialog.qml b/electrum/gui/qml/components/SwapDialog.qml
index 126b602b0..d3eead881 100644
--- a/electrum/gui/qml/components/SwapDialog.qml
+++ b/electrum/gui/qml/components/SwapDialog.qml
@@ -42,6 +42,7 @@ ElDialog {
: swaphelper.state == SwapHelper.NoService
? InfoTextArea.IconStyle.Warn
: InfoTextArea.IconStyle.Info
+ backgroundColor: constants.darkerDialogBackground
}
GridLayout {
@@ -252,37 +253,32 @@ ElDialog {
}
- Pane {
+ Button {
Layout.alignment: Qt.AlignHCenter
visible: _swaphelper.isNostr()
- background: Rectangle { color: constants.darkerDialogBackground }
- padding: 0
-
- FlatButton {
- text: qsTr('Choose swap provider')
- enabled: _swaphelper.state != SwapHelper.Initializing
- && _swaphelper.state != SwapHelper.Started
- && _swaphelper.state != SwapHelper.Success
- && _swaphelper.availableSwapServers.count
- onClicked: {
- var dialog = app.nostrSwapServersDialog.createObject(app, {
- swaphelper: _swaphelper,
- selectedPubkey: Config.swapServerNPub
- })
- dialog.accepted.connect(function() {
- if (Config.swapServerNPub != dialog.selectedPubkey) {
- Config.swapServerNPub = dialog.selectedPubkey
- _swaphelper.setReadyState()
- }
- })
- dialog.open()
- }
+ text: qsTr('Choose swap provider')
+ enabled: _swaphelper.state != SwapHelper.Initializing
+ && _swaphelper.state != SwapHelper.Started
+ && _swaphelper.state != SwapHelper.Success
+ && _swaphelper.availableSwapServers.count
+ onClicked: {
+ var dialog = app.nostrSwapServersDialog.createObject(app, {
+ swaphelper: _swaphelper,
+ selectedPubkey: Config.swapServerNPub
+ })
+ dialog.accepted.connect(function() {
+ if (Config.swapServerNPub != dialog.selectedPubkey) {
+ Config.swapServerNPub = dialog.selectedPubkey
+ _swaphelper.setReadyState()
+ }
+ })
+ dialog.open()
}
}
Item { Layout.fillHeight: true; Layout.preferredWidth: 1 }
- ButtonContainer {
+ DialogButtonContainer {
Layout.columnSpan: 2
Layout.fillWidth: true
FlatButton {
diff --git a/electrum/gui/qml/components/SweepDialog.qml b/electrum/gui/qml/components/SweepDialog.qml
index 849a70356..a23ff6723 100644
--- a/electrum/gui/qml/components/SweepDialog.qml
+++ b/electrum/gui/qml/components/SweepDialog.qml
@@ -58,8 +58,10 @@ ElDialog {
RowLayout {
Layout.fillWidth: true
- TextHighlightPane {
+
+ DialogHighlightPane {
Layout.fillWidth: true
+
Label {
text: qsTr('Enter the list of private keys to sweep into this wallet')
width: parent.width
@@ -112,7 +114,6 @@ ElDialog {
icon.source: '../../icons/qrcode.png'
icon.height: constants.iconSizeMedium
icon.width: constants.iconSizeMedium
- scale: 1.2
onClicked: {
var dialog = app.scanDialog.createObject(app, {
hint: qsTr('Scan a private key')
@@ -133,24 +134,29 @@ ElDialog {
iconStyle: InfoTextArea.IconStyle.Warn
Layout.fillWidth: true
Layout.margins: constants.paddingMedium
+ backgroundColor: constants.darkerDialogBackground
visible: text
}
}
}
- FlatButton {
+ DialogButtonContainer {
Layout.fillWidth: true
- Layout.preferredWidth: 1
- enabled: valid
- icon.source: '../../icons/tab_send.png'
- text: qsTr('Sweep...')
- onClicked: {
- console.log('sweeping')
- root.privateKeys = sweepkeys.text
- root.accept()
+ headerComponent: null
+
+ FlatButton {
+ Layout.fillWidth: true
+ Layout.preferredWidth: 1
+ enabled: valid
+ icon.source: '../../icons/tab_send.png'
+ text: qsTr('Sweep...')
+ onClicked: {
+ console.log('sweeping')
+ root.privateKeys = sweepkeys.text
+ root.accept()
+ }
}
}
-
}
Bitcoin {
diff --git a/electrum/gui/qml/components/TxDetails.qml b/electrum/gui/qml/components/TxDetails.qml
index 42f462a2e..0a5d217be 100644
--- a/electrum/gui/qml/components/TxDetails.qml
+++ b/electrum/gui/qml/components/TxDetails.qml
@@ -480,6 +480,7 @@ Pane {
}
}
+ property color navigationBarBackgroundColor: constants.highlightBackground
TxDetails {
id: txdetails
diff --git a/electrum/gui/qml/components/WalletDetails.qml b/electrum/gui/qml/components/WalletDetails.qml
index 9db036f9a..4456c80e8 100644
--- a/electrum/gui/qml/components/WalletDetails.qml
+++ b/electrum/gui/qml/components/WalletDetails.qml
@@ -517,6 +517,7 @@ Pane {
}
}
}
+ property color navigationBarBackgroundColor: constants.highlightBackground
Connections {
target: Daemon
diff --git a/electrum/gui/qml/components/WalletMainView.qml b/electrum/gui/qml/components/WalletMainView.qml
index c39cda5ed..55f73519d 100644
--- a/electrum/gui/qml/components/WalletMainView.qml
+++ b/electrum/gui/qml/components/WalletMainView.qml
@@ -2,6 +2,7 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Controls.Material
+import QtQuick.Controls.Material.impl
import QtQml
import org.electrum 1.0
@@ -302,6 +303,7 @@ Item {
var dialog = receiveDetailsDialog.createObject(mainView)
dialog.open()
}
+ pressAndHoldIndicator: true
onPressAndHold: {
Config.userKnowsPressAndHold = true
Daemon.currentWallet.deleteExpiredRequests()
@@ -316,6 +318,7 @@ Item {
text: qsTr('Send')
enabled: !invoiceParser.busy && !piResolver.busy && !requestDetails.busy
onClicked: openSendDialog()
+ pressAndHoldIndicator: true
onPressAndHold: {
Config.userKnowsPressAndHold = true
app.stack.push(Qt.resolvedUrl('Invoices.qml'))
@@ -324,6 +327,7 @@ Item {
}
}
}
+ property color navigationBarBackgroundColor: constants.highlightBackground
PIResolver {
id: piResolver
diff --git a/electrum/gui/qml/components/WalletSummary.qml b/electrum/gui/qml/components/WalletSummary.qml
deleted file mode 100644
index baddd0645..000000000
--- a/electrum/gui/qml/components/WalletSummary.qml
+++ /dev/null
@@ -1,128 +0,0 @@
-import QtQuick
-import QtQuick.Layouts
-import QtQuick.Controls
-import QtQuick.Controls.Material
-
-import org.electrum 1.0
-
-import "controls"
-
-Item {
- id: root
- clip: true
- implicitHeight: 0
-
- function open() {
- state = 'opened'
- }
- function close() {
- state = ''
- }
- function toggle() {
- if (state == 'opened')
- state = ''
- else
- state = 'opened'
- }
-
- states: [
- State {
- name: 'opened'
- PropertyChanges { target: root; implicitHeight: detailsPane.height }
- }
- ]
-
- transitions: [
- Transition {
- from: ''
- to: 'opened'
- NumberAnimation { target: root; properties: 'implicitHeight'; duration: 200 }
- },
- Transition {
- from: 'opened'
- to: ''
- NumberAnimation { target: root; properties: 'implicitHeight'; duration: 100 }
- }
- ]
-
- Pane {
- id: detailsPane
- width: parent.width
- anchors.bottom: parent.bottom
- padding: 0
- background: Rectangle {
- color: Material.dialogColor
- }
-
- ColumnLayout {
- id: rootLayout
- width: parent.width
- spacing: constants.paddingXLarge
-
- Item { Layout.preferredWidth: 1; Layout.preferredHeight: 1 }
-
- RowLayout {
- Layout.fillWidth: true
- FlatButton {
- text: qsTr('More details')
- Layout.fillWidth: true
- Layout.preferredWidth: 1
- enabled: app.stack.currentItem.objectName != 'WalletDetails'
- onClicked: {
- root.close()
- app.stack.pushOnRoot(Qt.resolvedUrl('WalletDetails.qml'))
- }
- }
- FlatButton {
- text: qsTr('Switch wallet')
- Layout.fillWidth: true
- icon.source: '../../icons/file.png'
- Layout.preferredWidth: 1
- enabled: app.stack.currentItem.objectName != 'Wallets'
- onClicked: {
- root.close()
- app.stack.pushOnRoot(Qt.resolvedUrl('Wallets.qml'))
- }
- }
- }
- }
- }
-
- property string formattedTotalBalance
- property string formattedTotalBalanceFiat
-
- function setBalances() {
- root.formattedTotalBalance = Config.formatSats(Daemon.currentWallet.totalBalance)
- if (Daemon.fx.enabled) {
- root.formattedTotalBalanceFiat = Daemon.fx.fiatValue(Daemon.currentWallet.totalBalance, false)
- }
- }
-
-
- // instead of all these explicit connections, we should expose
- // formatted balances directly as a property
- Connections {
- target: Config
- function onBaseUnitChanged() { setBalances() }
- function onThousandsSeparatorChanged() { setBalances() }
- }
-
- Connections {
- target: Daemon
- function onWalletLoaded() { setBalances() }
- }
-
- Connections {
- target: Daemon.fx
- function onEnabledUpdated() { setBalances() }
- function onQuotesUpdated() { setBalances() }
- }
-
- Connections {
- target: Daemon.currentWallet
- function onBalanceChanged() {
- setBalances()
- }
- }
-
-}
diff --git a/electrum/gui/qml/components/Wallets.qml b/electrum/gui/qml/components/Wallets.qml
index b38fdf78a..e98e82c14 100644
--- a/electrum/gui/qml/components/Wallets.qml
+++ b/electrum/gui/qml/components/Wallets.qml
@@ -32,7 +32,6 @@ Pane {
ColumnLayout {
Layout.fillWidth: true
- Layout.margins: constants.paddingLarge
Heading {
text: qsTr('Wallets')
@@ -42,9 +41,9 @@ Pane {
id: detailsFrame
Layout.fillWidth: true
Layout.fillHeight: true
- verticalPadding: 0
+ verticalPadding: bg.lineWidth
horizontalPadding: 0
- background: PaneInsetBackground {}
+ background: PaneInsetBackground { id: bg; vertical: false }
ElListView {
id: listview
@@ -117,27 +116,31 @@ Pane {
}
- FlatButton {
+ ButtonContainer {
Layout.fillWidth: true
- text: qsTr('Create Wallet')
- icon.source: '../../icons/add.png'
- onClicked: {
- if (Daemon.availableWallets.rowCount() > 0 && Config.walletShouldUseSinglePassword
- && (!Daemon.singlePassword || Daemon.numWalletsWithPassword(Daemon.singlePassword) < 1)) {
- // if the user has wallets but hasn't unlocked any wallet yet force them to do so.
- // this ensures they know at least one wallets password and can complete the wizard
- // where they will need to enter the password of an existing wallet.
- var dialog = app.messageDialog.createObject(app, {
- title: qsTr('Wallet unlock required'),
- text: qsTr("You have to unlock any existing wallet first before creating a new wallet."),
- })
- dialog.open()
- } else {
- rootItem.createWallet()
+ FlatButton {
+ Layout.fillWidth: true
+ text: qsTr('Create Wallet')
+ icon.source: '../../icons/add.png'
+ onClicked: {
+ if (Daemon.availableWallets.rowCount() > 0 && Config.walletShouldUseSinglePassword
+ && (!Daemon.singlePassword || Daemon.numWalletsWithPassword(Daemon.singlePassword) < 1)) {
+ // if the user has wallets but hasn't unlocked any wallet yet force them to do so.
+ // this ensures they know at least one wallets password and can complete the wizard
+ // where they will need to enter the password of an existing wallet.
+ var dialog = app.messageDialog.createObject(app, {
+ title: qsTr('Wallet unlock required'),
+ text: qsTr("You have to unlock any existing wallet first before creating a new wallet."),
+ })
+ dialog.open()
+ } else {
+ rootItem.createWallet()
+ }
}
}
}
}
+ property color navigationBarBackgroundColor: constants.highlightBackground
Connections {
target: Daemon
diff --git a/electrum/gui/qml/components/controls/BtcField.qml b/electrum/gui/qml/components/controls/BtcField.qml
index a42624356..ce11cfe1f 100644
--- a/electrum/gui/qml/components/controls/BtcField.qml
+++ b/electrum/gui/qml/components/controls/BtcField.qml
@@ -16,7 +16,7 @@ TextField {
regularExpression: msatPrecision ? Config.btcAmountRegexMsat : Config.btcAmountRegex
}
- property Amount textAsSats
+ property var textAsSats
onTextChanged: {
textAsSats = Config.unitsToSats(amount.text)
if (fiatfield.activeFocus)
diff --git a/electrum/gui/qml/components/controls/ButtonContainer.qml b/electrum/gui/qml/components/controls/ButtonContainer.qml
index 527897c0b..59cc6fe3a 100644
--- a/electrum/gui/qml/components/controls/ButtonContainer.qml
+++ b/electrum/gui/qml/components/controls/ButtonContainer.qml
@@ -7,11 +7,22 @@ Container {
id: root
property bool showSeparator: true
+ property color separatorColor: constants.darkerBackground
+ property Component headerComponent: null
+ property var _contentRootItem
+ property var _headerItem
property Item _layout
+ background: Rectangle {
+ color: constants.highlightBackground
+ }
+
function fillContentItem() {
- var contentRoot = containerLayout.createObject(root)
+ var outerLayout = rootLayout.createObject(root)
+ if (headerComponent != null)
+ _headerItem = headerComponent.createObject(outerLayout)
+ var contentRoot = containerLayout.createObject(outerLayout)
contentRoot.children.length = 0 // empty array
let total = contentChildren.length
@@ -32,7 +43,8 @@ Container {
contentRoot.children.push(button)
}
- contentItem = contentRoot
+ contentItem = outerLayout //contentRoot
+ _contentRootItem = contentRoot
}
// override this function to dynamically add buttons.
@@ -43,6 +55,13 @@ Container {
fillContentItem()
}
+ Component {
+ id: rootLayout
+ ColumnLayout {
+ spacing: 0
+ }
+ }
+
Component {
id: containerLayout
RowLayout {
@@ -59,7 +78,7 @@ Container {
Layout.preferredWidth: showSeparator ? 2 : 0
Layout.preferredHeight: pheight
Layout.alignment: Qt.AlignVCenter
- color: constants.darkerBackground
+ color: root.separatorColor
Component.onCompleted: {
// create binding here, we need to be able to have stable ref master_idx
visible = Qt.binding(function() {
@@ -74,3 +93,4 @@ Container {
}
}
+
diff --git a/electrum/gui/qml/components/controls/ChannelBar.qml b/electrum/gui/qml/components/controls/ChannelBar.qml
index 8635356f7..4f67dd765 100644
--- a/electrum/gui/qml/components/controls/ChannelBar.qml
+++ b/electrum/gui/qml/components/controls/ChannelBar.qml
@@ -6,11 +6,11 @@ import QtQuick.Controls.Material
import org.electrum 1.0
Item {
- property Amount capacity
- property Amount localCapacity
- property Amount remoteCapacity
- property Amount canSend
- property Amount canReceive
+ property var capacity // type: Amount
+ property var localCapacity // type: Amount
+ property var remoteCapacity // type: Amount
+ property var canSend // type: Amount
+ property var canReceive // type: Amount
property bool frozenForSending: false
property bool frozenForReceiving: false
diff --git a/electrum/gui/qml/components/controls/DialogButtonContainer.qml b/electrum/gui/qml/components/controls/DialogButtonContainer.qml
new file mode 100644
index 000000000..3c7f9f1ba
--- /dev/null
+++ b/electrum/gui/qml/components/controls/DialogButtonContainer.qml
@@ -0,0 +1,19 @@
+import QtQuick
+import QtQuick.Layouts
+
+ButtonContainer {
+ id: root
+ separatorColor: constants.darkerDialogBackground
+ background: Rectangle {
+ color: "transparent"
+ }
+ headerComponent: Component {
+ Rectangle {
+ Layout.fillWidth: true
+ Layout.preferredHeight: 2
+ Layout.leftMargin: constants.paddingSmall
+ Layout.rightMargin: constants.paddingSmall
+ color: root.separatorColor
+ }
+ }
+}
diff --git a/electrum/gui/qml/components/controls/DialogHighlightPane.qml b/electrum/gui/qml/components/controls/DialogHighlightPane.qml
new file mode 100644
index 000000000..1913972ec
--- /dev/null
+++ b/electrum/gui/qml/components/controls/DialogHighlightPane.qml
@@ -0,0 +1,5 @@
+import QtQuick
+
+TextHighlightPane {
+ backgroundColor: constants.darkerDialogBackground
+}
diff --git a/electrum/gui/qml/components/controls/ElDialog.qml b/electrum/gui/qml/components/controls/ElDialog.qml
index 74bd44c21..b90402c9e 100644
--- a/electrum/gui/qml/components/controls/ElDialog.qml
+++ b/electrum/gui/qml/components/controls/ElDialog.qml
@@ -17,7 +17,7 @@ Dialog {
property bool _wasOpened: false
// Add bottom padding for Android navigation bar if needed
- bottomPadding: needsSystemBarPadding ? app.navigationBarHeight : 0
+ bottomPadding: needsSystemBarPadding && app.keyboardFreeZone.state != 'visible' ? app.navigationBarHeight : 0
// called to finally close dialog after checks by onClosing handler in main.qml
function doClose() {
@@ -106,10 +106,10 @@ Dialog {
Rectangle {
Layout.fillWidth: true
- Layout.leftMargin: constants.paddingXXSmall
- Layout.rightMargin: constants.paddingXXSmall
- height: 1
- color: Qt.rgba(0,0,0,0.5)
+ Layout.leftMargin: constants.paddingSmall
+ Layout.rightMargin: constants.paddingSmall
+ Layout.preferredHeight: 2
+ color: constants.darkerDialogBackground
}
}
diff --git a/electrum/gui/qml/components/controls/FlatButton.qml b/electrum/gui/qml/components/controls/FlatButton.qml
index 621dec49b..ab3f0e409 100644
--- a/electrum/gui/qml/components/controls/FlatButton.qml
+++ b/electrum/gui/qml/components/controls/FlatButton.qml
@@ -9,6 +9,7 @@ TabButton {
checkable: false
property bool textUnderIcon: true
+ property bool pressAndHoldIndicator: false
font.pixelSize: constants.fontSizeSmall
icon.width: constants.iconSizeMedium
@@ -25,4 +26,45 @@ TabButton {
font: control.font
color: !control.enabled ? control.Material.hintTextColor : control.down || control.checked ? control.Material.accentColor : control.Material.foreground
}
+
+ Rectangle {
+ id: indicator
+ anchors.top: control.top
+ anchors.horizontalCenter: control.horizontalCenter
+ width: 0
+ opacity: 0
+ height: 3
+ color: control.Material.accentColor
+
+ states: State {
+ name: 'pressing'
+ when: pressAndHoldIndicator && control.pressed
+ PropertyChanges {
+ target: indicator
+ width: control.width
+ opacity: 1
+ }
+ }
+
+ transitions: Transition {
+ to: 'pressing'
+ SequentialAnimation {
+ PauseAnimation {
+ duration: 200
+ }
+ ParallelAnimation {
+ NumberAnimation {
+ target: indicator
+ property: "width"
+ duration: 600
+ }
+ NumberAnimation {
+ target: indicator
+ property: "opacity"
+ duration: 600
+ }
+ }
+ }
+ }
+ }
}
diff --git a/electrum/gui/qml/components/controls/FormattedAmount.qml b/electrum/gui/qml/components/controls/FormattedAmount.qml
index 80d6d778a..43c57e68c 100644
--- a/electrum/gui/qml/components/controls/FormattedAmount.qml
+++ b/electrum/gui/qml/components/controls/FormattedAmount.qml
@@ -6,7 +6,7 @@ import QtQuick.Controls.Material
import org.electrum 1.0
GridLayout {
- required property Amount amount
+ required property var amount // type: Amount
property bool showAlt: true
property bool singleLine: true
property bool valid: true
diff --git a/electrum/gui/qml/components/controls/HelpDialog.qml b/electrum/gui/qml/components/controls/HelpDialog.qml
index ac7dac0ad..28724b538 100644
--- a/electrum/gui/qml/components/controls/HelpDialog.qml
+++ b/electrum/gui/qml/components/controls/HelpDialog.qml
@@ -35,7 +35,7 @@ ElDialog {
implicitHeight: rootLayout.height + topPadding + bottomPadding
padding: constants.paddingLarge
background: Rectangle {
- color: constants.lighterBackground
+ color: constants.highlightBackground
}
ColumnLayout {
id: rootLayout
diff --git a/electrum/gui/qml/components/controls/PaneInsetBackground.qml b/electrum/gui/qml/components/controls/PaneInsetBackground.qml
index 9762e4101..8733a5705 100644
--- a/electrum/gui/qml/components/controls/PaneInsetBackground.qml
+++ b/electrum/gui/qml/components/controls/PaneInsetBackground.qml
@@ -3,25 +3,33 @@ import QtQuick.Controls.Material
Rectangle {
property color baseColor: Material.background
+ property bool vertical: true
+ property bool horizontal: true
+ property int lineWidth: 2
+
Rectangle {
anchors { left: parent.left; top: parent.top; right: parent.right }
- height: 1
+ height: lineWidth
color: Qt.darker(baseColor, 1.50)
+ visible: horizontal
}
Rectangle {
anchors { left: parent.left; top: parent.top; bottom: parent.bottom }
- width: 1
+ width: lineWidth
color: Qt.darker(baseColor, 1.50)
+ visible: vertical
}
Rectangle {
anchors { left: parent.left; bottom: parent.bottom; right: parent.right }
- height: 1
+ height: lineWidth
color: Qt.lighter(baseColor, 1.50)
+ visible: horizontal
}
Rectangle {
anchors { right: parent.right; top: parent.top; bottom: parent.bottom }
- width: 1
+ width: lineWidth
color: Qt.lighter(baseColor, 1.50)
+ visible: vertical
}
color: Qt.darker(baseColor, 1.15)
}
diff --git a/electrum/gui/qml/components/controls/PasswordField.qml b/electrum/gui/qml/components/controls/PasswordField.qml
index e9fc0e10d..064ed6480 100644
--- a/electrum/gui/qml/components/controls/PasswordField.qml
+++ b/electrum/gui/qml/components/controls/PasswordField.qml
@@ -7,6 +7,7 @@ RowLayout {
property alias text: password_tf.text
property alias tf: password_tf
property alias echoMode: password_tf.echoMode
+ property alias placeholderText: password_tf.placeholderText
property bool showReveal: true
signal accepted
diff --git a/electrum/gui/qml/components/controls/ProxyConfig.qml b/electrum/gui/qml/components/controls/ProxyConfig.qml
index 05bc05b2b..e1e665d6e 100644
--- a/electrum/gui/qml/components/controls/ProxyConfig.qml
+++ b/electrum/gui/qml/components/controls/ProxyConfig.qml
@@ -53,68 +53,62 @@ Item {
model: proxy_type_map
}
- GridLayout {
- columns: 2
+ ColumnLayout {
+ // columns: 2
Layout.fillWidth: true
+ spacing: constants.paddingSmall
- Label {
- text: qsTr("Address")
- enabled: address.enabled
- }
+ RowLayout {
+ Layout.fillWidth: true
+ Layout.rightMargin: constants.paddingLarge
- TextField {
- id: address
- enabled: proxy_enabled_cb.checked
- inputMethodHints: Qt.ImhNoPredictiveText
+ TextField {
+ id: address
+ Layout.fillWidth: true
+ enabled: proxy_enabled_cb.checked
+ inputMethodHints: Qt.ImhNoPredictiveText
+ placeholderText: qsTr("Address")
+ }
+
+ TextField {
+ id: port
+ Layout.fillWidth: true
+ enabled: proxy_enabled_cb.checked
+ inputMethodHints: Qt.ImhDigitsOnly
+ placeholderText: qsTr("Port")
+ }
}
Label {
- text: qsTr("Port")
- enabled: port.enabled
- }
-
- TextField {
- id: port
- enabled: proxy_enabled_cb.checked
- inputMethodHints: Qt.ImhDigitsOnly
- }
-
- Label {
- text: qsTr("Username")
+ Layout.topMargin: constants.paddingLarge
+ text: qsTr("Authentication")
enabled: username_tf.enabled
}
TextField {
id: username_tf
+ Layout.fillWidth: true
+ Layout.rightMargin: constants.paddingLarge
enabled: proxy_enabled_cb.checked
inputMethodHints: Qt.ImhNoPredictiveText
- }
-
- Label {
- text: qsTr("Password")
- enabled: password_tf.enabled
+ placeholderText: qsTr("Username")
}
PasswordField {
id: password_tf
enabled: proxy_enabled_cb.checked
+ placeholderText: qsTr("Password")
}
}
- Pane {
+ Button {
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: constants.paddingLarge
- padding: 0
- background: Rectangle {
- color: constants.darkerDialogBackground
- }
- FlatButton {
- enabled: proxy_enabled_cb.checked && !_probing
- text: qsTr('Detect Tor proxy')
- onClicked: {
- _probing = true
- Network.probeTor()
- }
+ enabled: proxy_enabled_cb.checked && !_probing
+ text: qsTr('Detect Tor proxy')
+ onClicked: {
+ _probing = true
+ Network.probeTor()
}
}
diff --git a/electrum/gui/qml/components/controls/SeedKeyboardKey.qml b/electrum/gui/qml/components/controls/SeedKeyboardKey.qml
index fa5fcc9f9..68b08c3d5 100644
--- a/electrum/gui/qml/components/controls/SeedKeyboardKey.qml
+++ b/electrum/gui/qml/components/controls/SeedKeyboardKey.qml
@@ -19,6 +19,10 @@ Pane {
kbd.keyEvent(keycode, key)
}
+ background: Rectangle {
+ color: constants.darkerDialogBackground
+ }
+
FlatButton {
anchors.fill: parent
diff --git a/electrum/gui/qml/components/controls/SeedTextArea.qml b/electrum/gui/qml/components/controls/SeedTextArea.qml
index 76952ccad..9674c008f 100644
--- a/electrum/gui/qml/components/controls/SeedTextArea.qml
+++ b/electrum/gui/qml/components/controls/SeedTextArea.qml
@@ -35,10 +35,11 @@ Pane {
TextArea {
id: seedtextarea
Layout.fillWidth: true
- Layout.minimumHeight: fontMetrics.height * 3 + topPadding + bottomPadding
+ Layout.minimumHeight: fontMetrics.lineSpacing * 3 + topPadding + bottomPadding
rightPadding: constants.paddingLarge
leftPadding: constants.paddingLarge
+ bottomPadding: constants.paddingXLarge
wrapMode: TextInput.WordWrap
font.bold: true
@@ -47,8 +48,9 @@ Pane {
inputMethodHints: Qt.ImhSensitiveData | Qt.ImhLowercaseOnly | Qt.ImhNoPredictiveText
readOnly: AppController.isAndroid()
- background: Rectangle {
- color: constants.darkerBackground
+ Component.onCompleted: {
+ background.filled = true
+ background.fillColor = constants.seedTextAreaBackground
}
onTextChanged: {
@@ -66,16 +68,19 @@ Pane {
Rectangle {
anchors.fill: contentText
color: root.indicatorValid ? 'green' : 'red'
- border.color: Material.accentColor
- radius: 2
+ radius: 3
}
Label {
id: contentText
text: root.indicatorText
anchors.right: parent.right
anchors.bottom: parent.bottom
- leftPadding: root.indicatorText != '' ? constants.paddingLarge : 0
- rightPadding: root.indicatorText != '' ? constants.paddingLarge : 0
+ anchors.rightMargin: constants.paddingXXSmall
+ anchors.bottomMargin: constants.paddingXXSmall
+ leftPadding: root.indicatorText != '' ? constants.paddingMedium : 0
+ rightPadding: root.indicatorText != '' ? constants.paddingMedium : 0
+ topPadding: root.indicatorText != '' ? constants.paddingXXSmall/2 : 0
+ bottomPadding: root.indicatorText != '' ? constants.paddingXXSmall/2 : 0
font.bold: false
font.pixelSize: constants.fontSizeSmall
}
@@ -99,7 +104,7 @@ Pane {
Layout.margins: constants.paddingXXSmall
width: suggestionLabel.width
height: suggestionLabel.height
- color: constants.lighterBackground
+ color: constants.darkerDialogBackground
radius: constants.paddingXXSmall
Label {
id: suggestionLabel
@@ -127,7 +132,7 @@ Pane {
Layout.fillWidth: true
Layout.preferredHeight: kbd.width / 1.75
visible: !root.readOnly
- onKeyEvent: {
+ onKeyEvent: (keycode, text) => {
if (keycode == Qt.Key_Backspace) {
if (seedtextarea.text.length > 0)
seedtextarea.text = seedtextarea.text.substring(0, seedtextarea.text.length-1)
diff --git a/electrum/gui/qml/components/controls/ServerConfig.qml b/electrum/gui/qml/components/controls/ServerConfig.qml
index aae493bae..0df5cb786 100644
--- a/electrum/gui/qml/components/controls/ServerConfig.qml
+++ b/electrum/gui/qml/components/controls/ServerConfig.qml
@@ -43,7 +43,7 @@ Item {
HelpButton {
Layout.alignment: Qt.AlignRight
- heading: qsTr('Connection mode')+':'
+ heading: qsTr('Connection mode') + ':'
helptext: Config.getTranslatedMessage('MSG_CONNECTMODE_SERVER_HELP') + '
' +
Config.getTranslatedMessage('MSG_CONNECTMODE_NODES_HELP') + '