Commit Graph

4063 Commits

Author SHA1 Message Date
Sander van Grieken 895679a6be qml: styling History, ProxyConfig and NostrConfigDialog 2026-04-22 10:15:30 +02:00
Sander van Grieken 87bb63e442 qml: use standard Button for buttons outside of buttoncontainer 2026-04-22 10:15:30 +02:00
Sander van Grieken 3a740256c5 qml: add missing button containers 2026-04-22 10:15:30 +02:00
Sander van Grieken 1c0851c6eb styling OpenChannelDialog 2026-04-22 10:15:30 +02:00
Sander van Grieken 738992ac9e qml: don't add navigationbar padding when on-screen keyboard is visible,
also allow stackview pages to override navigationbar background color to
allow correct color runoff below buttons
2026-04-22 10:15:30 +02:00
Sander van Grieken 28f744f778 qml: additional styling updates 2026-04-22 10:15:30 +02:00
Sander van Grieken e99b3023e9 qml: wizard styling, password dialog styling 2026-04-22 10:15:30 +02:00
Sander van Grieken cdb5c0b86d qml: styling updates qt6.10 2026-04-22 10:15:30 +02:00
Sander van Grieken fd5b867689 qml: don't import QtMultimedia when running on android (android 8 compat) 2026-04-22 10:15:30 +02:00
Sander van Grieken 9772a6d5b6 qml: add workarounds for issue assigning custom types to QObject properties
- on the python side, for pyqtProperty's with a setter, the pyqtProperty should be declared as QVariant type
- on the qml side, properties should be declared 'var', not the custom type.
2026-04-22 10:15:30 +02:00
ThomasV bca41d941d Merge pull request #10573 from f321x/qml_wallet_rename
qml: allow renaming wallets
2026-04-22 10:03:14 +02:00
f321x 24d93420fb qml: add top padding to nostr relay url list
The first relay url was close to the top of the ElTextArea and looked a
bit sliced. Adding some padding makes it look better.
2026-04-14 08:34:18 +02:00
f321x 8a12874c8e qml: allow renaming wallets
Allows to rename a wallet file from the QML Wallet Details view.
This seems like a feature we should support as the use-case of a wallet can
change or maybe the user didn't think about a proper name when setting
up the wallet. Especially with lightning channels it is not possible to
restore from seed to change the name.

Fixes #4377
2026-04-08 10:45:59 +02:00
ghost43 09a09057f6 Merge pull request #10548 from SomberNight/202603_lockdown_rpcserver
in GUI mode, only start a limited minimal RPC server
2026-03-31 15:25:52 +00:00
ThomasV efbe1907d7 Merge pull request #10556 from f321x/settings_dialog_guard_network
qt: SettingsDialog: guard self.network access
2026-03-27 15:54:36 +01:00
f321x 1aad09a61d qt: SettingsDialog: guard self.network access
Check if self.network before trying to access it. This would trigger an
exception when toggling the trampoline checkbox in offline mode:
```
 29.13 | E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
  File "/home/user/Documents/electrum/electrum/gui/qt/settings_dialog.py", line 133, in on_trampoline_checked
    self.network.run_from_another_thread(
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'run_from_another_thread'
 31.00 | E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
  File "/home/user/Documents/electrum/electrum/gui/qt/settings_dialog.py", line 131, in on_trampoline_checked
    self.network.start_gossip()
    ^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'start_gossip'
```
2026-03-27 15:40:22 +01:00
SomberNight 726d3995f4 qt gui: more defensive 'gui' RPC (i.e. URI) handling 2026-03-25 18:54:13 +00:00
ThomasV 3012c367ad Qt: move LN fee slider to payment dialog. fixes #10516 2026-03-25 10:53:38 +01:00
f321x cb023e22e4 qml: 2fa: make 2fa setup qr code clickable
This will make the 2fa app open when the user clicks on the qr code,
much more convenient than manually copy pasting the secret.
2026-03-24 14:50:45 +01:00
ThomasV 3cf2c325d5 Merge pull request #10506 from accumulator/spend_from_coin_selection_refactor
qt: perform 'fully spend' action with coin selection, keep separate from coin control when doing action
2026-03-24 12:46:02 +01:00
f321x 2c541d2663 qt: ElectrumGui: repr(UserFacingException) -> str()
Show UserFacingException in ElectrumGui.start_new_window
as str() to the user, ther doesn't seem to be a good reason
to show its repr?
2026-03-23 10:14:31 +01:00
SomberNight 42ad18b216 rm bip70 support
- could not find a single project that still actually cares about bip70 [0]
    - well except maybe BitPay.
        - but I cannot test with BitPay:
            - they have a testnet3 staging environment on test.bitpay.com
                - but the SSL cert they use for bip70 has expired in 2021
                - the webUI probably also has not been updated since then...
                    - they claim to have added LN support in 2022 in a blog post,
                        but it's not there on test.bitpay.com
            - on mainnet, they require KYC before payment
                - < ... angry noises >
            - their loss then, I don't care.
- this is code that no one wants to maintain

- this does not yet delete the signed bip70 payment data for historical txs
    - but it is no longer possible to export it from the GUI

[0]: https://bitcoinops.org/en/topics/bip70-payment-protocol/
2026-03-20 18:12:55 +00:00
SomberNight 2ea8d11524 fixup prev 2026-03-20 13:49:16 +00:00
Sander van Grieken 03e95accdc qt, qml: for new transaction notifications, instead of using sign, explicitly say sent/received.
For multiple transactions, split summary in total sent/received and a balance change.

move duplicated code to wallet.get_user_notifications_for_new_txns()
2026-03-20 12:52:22 +01:00
ThomasV 7ee2477b68 Merge pull request #10528 from f321x/qt_swapserver_list_resize
swaps: improve SwapServerDialog, provider CLI, bugfixes
2026-03-19 09:42:05 +01:00
f321x f56e6318e3 swaps: make SwapManager.percentage Decimal
If SwapManager.percentage was a 0.2 float, rounding differences would
cause an exception in the fee calculation inverse sanity check when entering 20
000 sats into the SwapDialog. By making self.percentage a decimal we can
prevent this kind of issue.

```
File "/home/user/code/vibecoding_vm/electrum/electrum/gui/qt/swap_dialog.py", line 294, in on_send_edited
    recv_amount = self.swap_manager.get_recv_amount(send_amount, is_reverse=self.is_reverse)
  File "/home/user/code/vibecoding_vm/electrum/electrum/submarine_swaps.py", line 1320, in get_recv_amount
    if abs(send_amount - inverted_send_amount) > 1:
           ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
TypeError: unsupported operand type(s) for -: 'int' and 'NoneType'
```
2026-03-19 09:17:34 +01:00
f321x efca1cc511 qt: PluginsDialog: add link to website
Adds a link to the plugins.electrum.org website so users who open the
plugins dialog out of curiosity get guided to the website and can
discover other plugins and learn more about the system.
2026-03-17 12:02:31 +01:00
f321x ffd259287d qt: SwapServerDialog: resize server list with dialog
Waste less space in the dialog by limiting the stretch to 10px and
resize the servers_list with the dialog by setting stretch=1 so it can
be made larger.

Fixes https://github.com/spesmilo/electrum/issues/10519
2026-03-16 12:20:36 +01:00
f321x d85985cdf2 qml: rbf/cancel: fix type error
self.oldfeeRate is initialized as int in `QETxRbfFeeBumper` and
`QETxCanceller`. However QML expects it to be a string. Initializing
it as string fixes the exception. Previously this didn't happen as
`Abstract_Wallet.add_info_from_wallet_and_network()` would never
return False, so the `get_tx()` method would immediately overwrite
the self.oldfeeRate variable with a string.

```
 20.95 | D | gui.qml.qetxfinalizer | TxMonMixin.__init__
 20.95 | E | gui.qml.qeapp.Exception_Hook | exception caught by crash reporter
TypeError: unable to convert a Python 'int' object to a C++ 'QString' instance
```
2026-03-09 14:39:40 +01:00
f321x 3d13d478c9 qml: rbf/cancel: abort update if adding tx info fails
Early return the update() methods of QETxRbfFeeBumper and QETxCanceller
if it fails to fetch missing tx information from the Network to prevent
an exception in `Abstract_Wallet.bump_fee()` and
`Abstract_Wallet.dscancel()`. See
https://github.com/spesmilo/electrum/issues/5502#issuecomment-40213084270
2026-03-09 14:19:36 +01:00
ghost43 cb696ed6f8 Merge pull request #10504 from accumulator/move_qt_event_listener
common_qt: move QtEventListener and qt_event_listener decorator to common_qt
2026-03-03 17:48:01 +00:00
Sander van Grieken 48916f56bc qt: perform 'fully spend' action with coin selection, keep separate from coin control when doing action.
Also stop timer when dialog is finished, to avoid re-generating txs with the same input coin set, which
results in an exception as these coins have signatures when the swap has started.
2026-03-03 18:46:03 +01:00
ghost43 0cb4e89aee Merge pull request #10503 from accumulator/qt_coins_fully_spend_menu
qt: utxo_list: only enable 'fully spend...' menu if there are unfrozen coins in the selection.
2026-03-03 17:37:58 +00:00
SomberNight 4c27b8de8d qt: utxo_list: add asserts to helper methods that coins are selected
- otherwise they default to selecting all coins, which is unlikely to be what the user intends
- prev commit makes sure this should never happen
2026-03-03 17:29:22 +00:00
f321x 423cc678c8 qt: MyTreeView: close menu if its context changes
Stores the currently open (right-click) menu in MyTreeView
and adds a `close_menu()` method so inheritants can cleanly
close the menu again if the context it was opened upon has changed.

This is utilized by `AddressList` and `UTXOList` to close the menu
if a call to `update()` has chenged the address list in some way or
removed a utxo from the list to prevent the user from trying to use
a utxo that doesn't exist anymore.

Fixes #10464
2026-03-03 17:28:57 +01:00
Sander van Grieken 91efb3e1f4 common_qt: move QtEventListener and qt_event_listener decorator to common_qt 2026-03-03 13:03:46 +01:00
Sander van Grieken f3ba25df7d qt: utxo_list: only enable 'fully spend...' menu if there are unfrozen coins in the selection.
otherwise, when selecting only frozen coins, the set of usable coins is empty, and the menu options
will instead fall back to using ALL coins without informing the user.
2026-03-02 18:04:08 +01:00
ghost43 2c9f4fdbae Merge pull request #10433 from f321x/qt_changelog
qt: add Changelog to Help menu in toolbar
2026-02-25 17:26:06 +00:00
f321x 2df68d9249 qt: console: allow changing font size
Allows changing the font size in the qt Console with
`Ctrl` + `+` and `Ctrl` + `-`.
2026-02-23 17:27:39 +01:00
SomberNight 3afa2fcdf3 locale: gui: show translation completion percentage in language names
In the GUIs, on the language-select screen, show e.g.
  Czech (100%), Danish (13%), Dutch (54%)
instead of
  Czech, Danish, Dutch

- we count the source strings when creating the .pot PO-template file
  and add an "X-Electrum-SourceStringCount" header to it, in the push_locale.py script that uploads the .pot file to crowdin.
  - later, when we run electrum-locale/update.py to download the translations in .po files, these files will also contain the same header.
  - then when the build_locale.sh script compiles those .po files, we can read the header and use it to populate a new "stats.json" file
    that we place in electrum/locale/locale/ and bundle in the all release binaries/distributables.
    - stats.json also includes the number of translated strings for each lang
- at runtime we simply read stats.json and use the values to calculate the percentages
  - a prior implementation did not pre-calc stats.json but did all calculations at runtime (by opening all .mo translations)
    - however that was deemed to slow, hence the build-time pre-calc
      - runtime calc took 40 ms on my laptop, so I guess it could easily take 10x that on an old phone
- just as we have always been very tolerant of any locale files or even the whole locale/ dir missing, we also tolerate stats.json missing
2026-02-21 03:40:09 +00:00
SomberNight cf25990973 locale: don't translate string "Electrum", "BIP39" 2026-02-19 16:13:44 +00:00
Sander van Grieken b10b14c2f8 qml: ReceiveDetailsDialog use proper ButtonContainer 2026-02-19 17:12:17 +01:00
ThomasV 0c32bde721 Merge pull request #10480 from f321x/fix_exc_offline_mode
qt: fix toolbar action exc in offline mode
2026-02-18 17:41:23 +01:00
accumulator c097c05e07 Merge pull request #10484 from f321x/fix_android_8_startup_error
android: biometry: catch java import errors
2026-02-18 13:50:34 +01:00
SomberNight e2c41aabbe locale: don't translate string "Electrum" 2026-02-17 13:48:51 +00:00
f321x f573ab2d56 android: biometry: catch java import errors
Catch JavaError when trying to load the java classes of the biometry
module on startup. This can raise if the device is on an old API version
and the loaded java class depends on apis unknown to the os.

Fixes #10470

```
02-17 10:07:25.714  5254  5270 I python  :   0.47 | E | __main__ | daemon.run_gui errored
02-17 10:07:25.714  5254  5270 I python  : Traceback (most recent call last):
02-17 10:07:25.714  5254  5270 I python  :   File "app/main.py", line 514, in handle_cmd
02-17 10:07:25.714  5254  5270 I python  :   File "app/electrum/daemon.py", line 653, in run_gui
02-17 10:07:25.714  5254  5270 I python  :   File "app/electrum/gui/qml/__init__.py", line 38, in <module>
02-17 10:07:25.714  5254  5270 I python  :   File "app/electrum/gui/qml/qeapp.py", line 49, in <module>
02-17 10:07:25.714  5254  5270 I python  :   File "app/electrum/gui/qml/qebiometrics.py", line 33, in <module>
02-17 10:07:25.714  5254  5270 I python  :   File "jnius/reflect.py", line 243, in autoclass
02-17 10:07:25.714  5254  5270 I python  :   File "jnius/jnius_export_class.pxi", line 877, in jnius.jnius.JavaMethod.__call__
02-17 10:07:25.714  5254  5270 I python  :   File "jnius/jnius_export_class.pxi", line 964, in jnius.jnius.JavaMethod.call_method
02-17 10:07:25.714  5254  5270 I python  :   File "jnius/jnius_utils.pxi", line 79, in jnius.jnius.check_exception
02-17 10:07:25.714  5254  5270 I python  : jnius.jnius.JavaException: JVM exception occurred: Failed resolution of: Landroid/hardware/biometrics/BiometricPrompt$AuthenticationResult; java.lang.NoClassDefFoundError
```
2026-02-17 10:18:21 +01:00
f321x 907fff46e5 qt: fix toolbar action exc in offline mode
Fix exception when clicking on "Donate to server" in offline mode by not
showing the "Donate to server" menu action when no network is set.

Raise CancelledError in `fetch_bitcoin_paper` as
`_fetch_tx_from_network` already shows an according error message so the
second, subsequent error message shown by `on_error` is not useful if
`_fetch_tx_from_network` already failed.

```
63.53 | E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
 File "/home/user/Documents/electrum/electrum/gui/qt/main_window.py", line 864, in donate_to_server
   d = self.network.get_donation_address()
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get_donation_address'
```
2026-02-16 09:17:42 +01:00
SomberNight 61a6ab1d95 locale: don't translate URL, like wtf
please, use common sense :(
I guess it was a copy-paste error, but still, treat all _() and qsTr() calls as "scary" and as potential attack vectors. Don't blindly call _(): every call needs to be weighed separately.
2026-02-14 09:25:39 +00:00
ghost43 f95e6ac1e8 Merge pull request #10462 from f321x/fix_wizard_tc_exc+
wizard: fix exception when loading new tc wallet
2026-02-11 14:27:00 +00:00
f321x 3905f8d9ec wizard: fix exception when loading new tc wallet
I tried to reproduce:
https://github.com/spesmilo/electrum/issues/8815#issuecomment-2094259186
which triggered the following exception for me:

```
Traceback (most recent call last):
  File "/home/user/code/electrum-fork/electrum/gui/qt/__init__.py", line 409, in start_new_window
    window = self._create_window_for_wallet(wallet)
  File "/home/user/code/electrum-fork/electrum/gui/qt/__init__.py", line 329, in _create_window_for_wallet
    w = ElectrumWindow(self, wallet)
  File "/home/user/code/electrum-fork/electrum/gui/qt/main_window.py", line 290, in __init__
    self.load_wallet(wallet)
    ~~~~~~~~~~~~~~~~^^^^^^^^
  File "/home/user/code/electrum-fork/electrum/util.py", line 495, in do_profile
    o = func(*args, **kw_args)
  File "/home/user/code/electrum-fork/electrum/gui/qt/main_window.py", line 589, in load_wallet
    self.update_recently_opened_menu()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/user/code/electrum-fork/electrum/gui/qt/main_window.py", line 741, in update_recently_opened_menu
    for i, k in enumerate(recent):
                ~~~~~~~~~^^^^^^^^
TypeError: 'NoneType' object is not iterable
```

This happens because the trustedcoin wallet is loaded outside of
Daemon.load_wallet() so Daemon.update_recently_opened_wallets()
is not getting called and config.RECENTLY:_OPEN_WALLET_FILES is
still None when we try to iterate through it.
As fix i now use load_wallet() instead of manually
instantiating the Wallet
and additionally handle
RECENTLY_OPEN_WALLET_FILES being None in
ElectrumWindow.update_recently_opened_menu().

My pull request https://github.com/spesmilo/electrum/pull/10121
would have sent this exception to the crash reporter so we
might have noticed it earlier. I think we should not just catch
all exceptions in the wizard like on master as it causes us to
repeatedly miss regressions in the wizard that could be sent to
the crash reporter.
2026-02-11 09:14:35 +01:00