Compare commits
4 Commits
fix/i18n-r
...
346aeee62b
| Author | SHA1 | Date | |
|---|---|---|---|
|
346aeee62b
|
|||
|
3b2eed37cc
|
|||
| 0c60462163 | |||
| a81443ff67 |
@@ -117,7 +117,10 @@ python3 build_zip.py # -> bal-electrum-plugin.zip (deterministic, prints sha25
|
|||||||
```
|
```
|
||||||
|
|
||||||
- `build_zip.py` needs **Babel** (`pip install babel`): it compiles the
|
- `build_zip.py` needs **Babel** (`pip install babel`): it compiles the
|
||||||
translation catalogs into the zip and stops if Babel is missing.
|
translation catalogs into the zip and stops if Babel is missing. The i18n
|
||||||
|
tests need it too. Install it in the **runtime** env used for releases
|
||||||
|
(`source "$BAL_HOME/electrum/env/bin/activate" && pip install babel`);
|
||||||
|
`make-release.sh` checks it before running anything.
|
||||||
- `make-release.sh` requires gpg and Gitea credentials (`~/.git-credentials`
|
- `make-release.sh` requires gpg and Gitea credentials (`~/.git-credentials`
|
||||||
or `GITEA_USER`/`GITEA_TOKEN`). It bumps `bal/manifest.json` — bump the
|
or `GITEA_USER`/`GITEA_TOKEN`). It bumps `bal/manifest.json` — bump the
|
||||||
version there, never invent a new source of truth.
|
version there, never invent a new source of truth.
|
||||||
|
|||||||
63
CHANGELOG.md
63
CHANGELOG.md
@@ -3549,3 +3549,66 @@ delivery; when it is not, the plugin raises an explicit error (see below).
|
|||||||
catalogs refreshed (removed format strings marked obsolete).
|
catalogs refreshed (removed format strings marked obsolete).
|
||||||
|
|
||||||
**Outcome:** DONE.
|
**Outcome:** DONE.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 63. i18n review fixes (Truman's review of the translation PR)
|
||||||
|
|
||||||
|
**Date:** 2026-10-07
|
||||||
|
|
||||||
|
**What changed:**
|
||||||
|
|
||||||
|
- `make-release.sh`
|
||||||
|
- Step 3 now also runs `tests/test_i18n.py`, `tests/test_translations.py`,
|
||||||
|
`tests/test_cli_*.py` and `tests/test_import_will_details.py` (the i18n
|
||||||
|
tests were never run by the release gate; the CLI and will-import tests
|
||||||
|
were not either).
|
||||||
|
- Checks up front that Babel is importable by `python3` and stops with
|
||||||
|
"pip install babel" otherwise: the i18n tests (step 3) and `build_zip.py`
|
||||||
|
(step 5) both need it, so a release no longer stops half-way.
|
||||||
|
- `AGENTS.md`: Babel must be installed in the runtime env used for releases.
|
||||||
|
- `pyproject.toml`: `[tool.ruff.lint.isort] known-first-party = ["bal"]`.
|
||||||
|
WHY: the reported I001 in `tests/test_translations.py` is not reproducible
|
||||||
|
from the repository root (ruff 0.15.11 and 0.6.9: clean), but it appears as
|
||||||
|
soon as ruff classifies `bal` as third-party (then 20 files report I001).
|
||||||
|
Removing the blank line would break the check where `bal` is first-party;
|
||||||
|
declaring it makes the result the same on every machine.
|
||||||
|
- `bal/core/willexecutors.py` - `get_willexecutor_transactions` returns COPIES
|
||||||
|
of the executor records. It used to write `txs`, `txsids` and the
|
||||||
|
translated `broadcast_status` into the will item's own `we` dict, which is
|
||||||
|
saved in the wallet (stored data depended on the UI language).
|
||||||
|
- `bal/core/will.py` - `WillItem` drops those transient fields when loading a
|
||||||
|
will saved by an older version, and maps a translated leading "New"
|
||||||
|
("Nuovo", "Nuevo" - saved by i18n test builds) back to "New".
|
||||||
|
- `bal/gui/qt/window.py`, `bal/cli/controller.py`: the status history of a new
|
||||||
|
will item is saved as the literal "New" (was `_("New")`).
|
||||||
|
- `tests/test_core_status_language_neutral.py` (new, 7 tests; 5 fail on
|
||||||
|
`main`): English "New" stored, translated "New" mapped back, the mapping
|
||||||
|
covers every catalog's translation of "New", the push helper does not
|
||||||
|
modify the will item, old transient fields dropped on load.
|
||||||
|
|
||||||
|
**Scope:** this entry contains ONLY the i18n review fixes. The other fixes
|
||||||
|
prepared in the same session (invalidation fee, Check `KeyError`, cascade,
|
||||||
|
deselected executor) are not part of it and will be proposed separately.
|
||||||
|
|
||||||
|
**Verification (on `main` 827a1d1):**
|
||||||
|
|
||||||
|
- New test file `tests/test_core_status_language_neutral.py`: 5 of 7 fail on
|
||||||
|
`main`, 7 of 7 pass with this change.
|
||||||
|
- Extended release test list (as above) plus the new test file: 446 passed,
|
||||||
|
1 failed (`main`: 439 passed, same failure). The failure is pre-existing:
|
||||||
|
`test_group_e_mock_karen7::test_e5` needs `tests/karen7`, a wallet file that
|
||||||
|
is not in the repository.
|
||||||
|
- Whole `tests/` directory: 609 passed, 26 failed, 3 collection errors
|
||||||
|
(`main`: 602 passed, and the SAME 26 failures and 3 errors, test by test).
|
||||||
|
All pre-existing and unrelated: 9 need `tests/karen7`; 21 in
|
||||||
|
`test_auto_rebuild_on_new_tx.py`, `test_cli_autorebuild.py` and
|
||||||
|
`test_cli_controller_offline.py` fail only when the whole directory runs
|
||||||
|
together (they pass when each file runs alone); 3 audio tests need an audio
|
||||||
|
device. `test_gui_export_dialogs.py::test_audio_import_receive_wiring` hangs
|
||||||
|
forever, also on `main`, so it was deselected.
|
||||||
|
- `ruff check bal/ tests/`: the same 3 pre-existing I001 as on `main`
|
||||||
|
(`dialogs.py`, `test_core_animated_qr.py`, `test_core_qr_transfer.py`),
|
||||||
|
none new.
|
||||||
|
|
||||||
|
**Outcome:** DONE (pending Truman's review).
|
||||||
|
|||||||
@@ -385,7 +385,9 @@ class BalController:
|
|||||||
tx["heirsvalue"] = txs[txid].heirsvalue
|
tx["heirsvalue"] = txs[txid].heirsvalue
|
||||||
tx["description"] = txs[txid].description
|
tx["description"] = txs[txid].description
|
||||||
tx["willexecutor"] = copy_structure(txs[txid].willexecutor)
|
tx["willexecutor"] = copy_structure(txs[txid].willexecutor)
|
||||||
tx["status"] = _("New")
|
# Stored history: always English (translated only for display by
|
||||||
|
# format_status_history); never _() here.
|
||||||
|
tx["status"] = "New"
|
||||||
tx["baltx_fees"] = txs[txid].tx_fees
|
tx["baltx_fees"] = txs[txid].tx_fees
|
||||||
tx["time"] = creation_time
|
tx["time"] = creation_time
|
||||||
tx["heirs"] = copy_structure(txs[txid].heirs)
|
tx["heirs"] = copy_structure(txs[txid].heirs)
|
||||||
|
|||||||
@@ -1364,6 +1364,37 @@ class WillItem(Logger):
|
|||||||
# format_status_history() still translates them.
|
# format_status_history() still translates them.
|
||||||
LEGACY_STATUS_LABELS = (N_("New"),)
|
LEGACY_STATUS_LABELS = (N_("New"),)
|
||||||
|
|
||||||
|
# Translations of "New" that test builds of the i18n work saved INTO the
|
||||||
|
# status history (window.py / the CLI used ``_("New")`` when building).
|
||||||
|
# They are mapped back to "New" on load so the history is language
|
||||||
|
# neutral again. Keep in sync with the "New" msgstr of every catalog in
|
||||||
|
# bal/locale (tests/test_core_status_language_neutral.py checks it).
|
||||||
|
TRANSLATED_NEW_LABELS = ("Nuovo", "Nuevo")
|
||||||
|
|
||||||
|
# Fields that Willexecutors.get_willexecutor_transactions /
|
||||||
|
# push_transactions_to_willexecutor used to write into the item's own
|
||||||
|
# executor record (older versions); they are transient push data.
|
||||||
|
TRANSIENT_PUSH_FIELDS = ("txs", "txsids", "broadcast_status")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _untranslate_new_status(status):
|
||||||
|
"""Map a translated leading "New" of a saved history back to "New"."""
|
||||||
|
head, sep, rest = status.partition(".")
|
||||||
|
if head in WillItem.TRANSLATED_NEW_LABELS:
|
||||||
|
return "New" + sep + rest
|
||||||
|
return status
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _without_transient_push_fields(we):
|
||||||
|
"""Return ``we`` without the transient push fields (a copy if needed)."""
|
||||||
|
if not isinstance(we, dict) or not any(
|
||||||
|
k in we for k in WillItem.TRANSIENT_PUSH_FIELDS
|
||||||
|
):
|
||||||
|
return we
|
||||||
|
return {
|
||||||
|
k: v for k, v in we.items() if k not in WillItem.TRANSIENT_PUSH_FIELDS
|
||||||
|
}
|
||||||
|
|
||||||
def set_status(self, status, value=True):
|
def set_status(self, status, value=True):
|
||||||
"""Set a status flag and apply the related side effects.
|
"""Set a status flag and apply the related side effects.
|
||||||
|
|
||||||
@@ -1445,8 +1476,10 @@ class WillItem(Logger):
|
|||||||
w = data
|
w = data
|
||||||
self.tx = Will.get_tx_from_any(w["tx"])
|
self.tx = Will.get_tx_from_any(w["tx"])
|
||||||
self.heirs = w.get("heirs", None)
|
self.heirs = w.get("heirs", None)
|
||||||
self.we = w.get("willexecutor", None)
|
self.we = WillItem._without_transient_push_fields(
|
||||||
self.status = w.get("status") or ""
|
w.get("willexecutor", None)
|
||||||
|
)
|
||||||
|
self.status = WillItem._untranslate_new_status(w.get("status") or "")
|
||||||
self.description = w.get("description", None)
|
self.description = w.get("description", None)
|
||||||
self.time = w.get("time", None)
|
self.time = w.get("time", None)
|
||||||
self.change = w.get("change", None)
|
self.change = w.get("change", None)
|
||||||
|
|||||||
@@ -231,6 +231,13 @@ class Willexecutors:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_willexecutor_transactions(will, force=False):
|
def get_willexecutor_transactions(will, force=False):
|
||||||
|
"""Group the valid, signed, not-yet-pushed will txs by will-executor.
|
||||||
|
|
||||||
|
Returns ``{url: executor_record}`` where each record gets ``txs`` (the
|
||||||
|
raw txs, one per line) and ``txsids``.
|
||||||
|
|
||||||
|
The returned records are COPIES: the will items are never modified.
|
||||||
|
"""
|
||||||
willexecutors = {}
|
willexecutors = {}
|
||||||
for wid, willitem in will.items():
|
for wid, willitem in will.items():
|
||||||
if willitem.get_status("VALID"):
|
if willitem.get_status("VALID"):
|
||||||
@@ -240,10 +247,18 @@ class Willexecutors:
|
|||||||
url = willexecutor["url"]
|
url = willexecutor["url"]
|
||||||
if willexecutor and Willexecutors.is_selected(willexecutor):
|
if willexecutor and Willexecutors.is_selected(willexecutor):
|
||||||
if url not in willexecutors:
|
if url not in willexecutors:
|
||||||
willexecutor["txs"] = ""
|
# Work on a COPY of the record: the item's
|
||||||
willexecutor["txsids"] = []
|
# own ``we`` dict is saved in the wallet, so
|
||||||
willexecutor["broadcast_status"] = _("Waiting...")
|
# the transient push fields below (raw txs,
|
||||||
willexecutors[url] = willexecutor
|
# txids and the - translated - broadcast
|
||||||
|
# status shown in the push dialog) must
|
||||||
|
# never end up in it (stored data must not
|
||||||
|
# depend on the UI language, see bal/i18n.py).
|
||||||
|
record = dict(willexecutor)
|
||||||
|
record["txs"] = ""
|
||||||
|
record["txsids"] = []
|
||||||
|
record["broadcast_status"] = _("Waiting...")
|
||||||
|
willexecutors[url] = record
|
||||||
willexecutors[url]["txs"] += str(willitem.tx) + "\n"
|
willexecutors[url]["txs"] += str(willitem.tx) + "\n"
|
||||||
willexecutors[url]["txsids"].append(wid)
|
willexecutors[url]["txsids"].append(wid)
|
||||||
|
|
||||||
|
|||||||
@@ -358,7 +358,8 @@ class BalWizardWidget(QWidget):
|
|||||||
class BalWizardHeirsWidget(BalWizardWidget):
|
class BalWizardHeirsWidget(BalWizardWidget):
|
||||||
title = N_("Bitcoin After Life Heirs")
|
title = N_("Bitcoin After Life Heirs")
|
||||||
message = N_(
|
message = N_(
|
||||||
"Please add your heirs\n remember that 100% of wallet balance will be spent"
|
"Please add your heirs\n"
|
||||||
|
" remember that the wallet balance will be spent at 100%"
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_content(self):
|
def get_content(self):
|
||||||
|
|||||||
@@ -551,7 +551,9 @@ class BalWindow:
|
|||||||
tx["heirsvalue"] = txs[txid].heirsvalue
|
tx["heirsvalue"] = txs[txid].heirsvalue
|
||||||
tx["description"] = txs[txid].description
|
tx["description"] = txs[txid].description
|
||||||
tx["willexecutor"] = copy_structure(txs[txid].willexecutor)
|
tx["willexecutor"] = copy_structure(txs[txid].willexecutor)
|
||||||
tx["status"] = _("New")
|
# Stored history: always English (translated only for display by
|
||||||
|
# format_status_history); never _() here.
|
||||||
|
tx["status"] = "New"
|
||||||
tx["baltx_fees"] = txs[txid].tx_fees
|
tx["baltx_fees"] = txs[txid].tx_fees
|
||||||
tx["time"] = creation_time
|
tx["time"] = creation_time
|
||||||
tx["heirs"] = copy_structure(txs[txid].heirs)
|
tx["heirs"] = copy_structure(txs[txid].heirs)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PROJECT VERSION\n"
|
"Project-Id-Version: PROJECT VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2026-10-03 12:24-0400\n"
|
"POT-Creation-Date: 2026-10-07 14:25-0400\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@@ -60,7 +60,7 @@ msgstr ""
|
|||||||
msgid "Error"
|
msgid "Error"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/core/will.py:1348 bal/gui/qt/dialogs.py:824
|
#: bal/core/will.py:1348 bal/gui/qt/dialogs.py:825
|
||||||
msgid "Expired"
|
msgid "Expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ msgstr ""
|
|||||||
msgid "Updated"
|
msgid "Updated"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/core/will.py:1359 bal/gui/qt/dialogs.py:2632
|
#: bal/core/will.py:1359 bal/gui/qt/dialogs.py:2633
|
||||||
msgid "Valid"
|
msgid "Valid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -195,15 +195,15 @@ msgstr ""
|
|||||||
msgid "Bal Wizard Setup"
|
msgid "Bal Wizard Setup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:325 bal/gui/qt/dialogs.py:2760
|
#: bal/gui/qt/dialogs.py:325 bal/gui/qt/dialogs.py:2762
|
||||||
msgid "Previous"
|
msgid "Previous"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:329 bal/gui/qt/dialogs.py:2763
|
#: bal/gui/qt/dialogs.py:329 bal/gui/qt/dialogs.py:2765
|
||||||
msgid "Next"
|
msgid "Next"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:333 bal/gui/qt/dialogs.py:4019
|
#: bal/gui/qt/dialogs.py:333 bal/gui/qt/dialogs.py:4048
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -212,194 +212,193 @@ msgid "Bitcoin After Life Heirs"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:360
|
#: bal/gui/qt/dialogs.py:360
|
||||||
#, python-format
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Please add your heirs\n"
|
"Please add your heirs\n"
|
||||||
" remember that 100% of wallet balance will be spent"
|
" remember that the wallet balance will be spent at 100%"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:369 bal/gui/qt/lists.py:1229
|
#: bal/gui/qt/dialogs.py:370 bal/gui/qt/lists.py:1229
|
||||||
msgid "Add"
|
msgid "Add"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:371 bal/gui/qt/dialogs.py:2593 bal/gui/qt/lists.py:311
|
#: bal/gui/qt/dialogs.py:372 bal/gui/qt/dialogs.py:2594 bal/gui/qt/lists.py:311
|
||||||
#: bal/gui/qt/lists.py:673 bal/gui/qt/lists.py:1237
|
#: bal/gui/qt/lists.py:673 bal/gui/qt/lists.py:1237
|
||||||
msgid "Import"
|
msgid "Import"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:373 bal/gui/qt/dialogs.py:2429
|
#: bal/gui/qt/dialogs.py:374 bal/gui/qt/dialogs.py:2430
|
||||||
#: bal/gui/qt/dialogs.py:2597 bal/gui/qt/lists.py:312 bal/gui/qt/lists.py:672
|
#: bal/gui/qt/dialogs.py:2598 bal/gui/qt/lists.py:312 bal/gui/qt/lists.py:672
|
||||||
#: bal/gui/qt/lists.py:1249
|
#: bal/gui/qt/lists.py:1249
|
||||||
msgid "Export"
|
msgid "Export"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:398 bal/gui/qt/dialogs.py:506
|
#: bal/gui/qt/dialogs.py:399 bal/gui/qt/dialogs.py:507
|
||||||
msgid "Bitcoin After Life Will-Executors"
|
msgid "Bitcoin After Life Will-Executors"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:399
|
#: bal/gui/qt/dialogs.py:400
|
||||||
msgid "Choose willexecutors download method"
|
msgid "Choose willexecutors download method"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:406
|
#: bal/gui/qt/dialogs.py:407
|
||||||
msgid "Automatically download and select willexecutors"
|
msgid "Automatically download and select willexecutors"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:407
|
#: bal/gui/qt/dialogs.py:408
|
||||||
msgid "Only download willexecutors list"
|
msgid "Only download willexecutors list"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:408
|
#: bal/gui/qt/dialogs.py:409
|
||||||
msgid "Import willexecutor list from file"
|
msgid "Import willexecutor list from file"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:409
|
#: bal/gui/qt/dialogs.py:410
|
||||||
msgid "Manual"
|
msgid "Manual"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:438 bal/gui/qt/lists.py:1559
|
#: bal/gui/qt/dialogs.py:439 bal/gui/qt/lists.py:1559
|
||||||
msgid "willexecutors"
|
msgid "willexecutors"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:507
|
#: bal/gui/qt/dialogs.py:508
|
||||||
msgid "Configure and select your willexecutors"
|
msgid "Configure and select your willexecutors"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:526
|
#: bal/gui/qt/dialogs.py:527
|
||||||
msgid "Bitcoin After Life Will Settings"
|
msgid "Bitcoin After Life Will Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:561 bal/gui/qt/dialogs.py:614
|
#: bal/gui/qt/dialogs.py:562 bal/gui/qt/dialogs.py:615
|
||||||
msgid "Please wait"
|
msgid "Please wait"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:644
|
#: bal/gui/qt/dialogs.py:645
|
||||||
msgid "Building Will"
|
msgid "Building Will"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:649
|
#: bal/gui/qt/dialogs.py:650
|
||||||
msgid "Building Will:"
|
msgid "Building Will:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:730 bal/gui/qt/dialogs.py:755
|
#: bal/gui/qt/dialogs.py:731 bal/gui/qt/dialogs.py:756
|
||||||
#: bal/gui/qt/dialogs.py:765 bal/gui/qt/dialogs.py:788
|
#: bal/gui/qt/dialogs.py:766 bal/gui/qt/dialogs.py:789
|
||||||
msgid "Checking variables"
|
msgid "Checking variables"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:756
|
#: bal/gui/qt/dialogs.py:757
|
||||||
msgid "Check Alive Threshold Passed: you have to Invalidate your old Will"
|
msgid "Check Alive Threshold Passed: you have to Invalidate your old Will"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:765 bal/gui/qt/dialogs.py:847
|
#: bal/gui/qt/dialogs.py:766 bal/gui/qt/dialogs.py:848
|
||||||
msgid "No Heirs"
|
msgid "No Heirs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:788 bal/gui/qt/dialogs.py:1335
|
#: bal/gui/qt/dialogs.py:789 bal/gui/qt/dialogs.py:1336
|
||||||
#: bal/gui/qt/dialogs.py:2281 bal/gui/qt/window.py:2315
|
#: bal/gui/qt/dialogs.py:2282 bal/gui/qt/window.py:2315
|
||||||
msgid "Ok"
|
msgid "Ok"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:792
|
#: bal/gui/qt/dialogs.py:793
|
||||||
msgid ""
|
msgid ""
|
||||||
"In the inheritance process, the entire wallet will always be fully emptied. \n"
|
"In the inheritance process, the entire wallet will always be fully emptied. \n"
|
||||||
"Your settings require an adjustment of the amounts"
|
"Your settings require an adjustment of the amounts"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:801 bal/gui/qt/window.py:844
|
#: bal/gui/qt/dialogs.py:802 bal/gui/qt/window.py:844
|
||||||
msgid "Will-executor fee too high: {}"
|
msgid "Will-executor fee too high: {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:835
|
#: bal/gui/qt/dialogs.py:836
|
||||||
msgid "Postponed: invalidating old will"
|
msgid "Postponed: invalidating old will"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:870 bal/gui/qt/dialogs.py:879
|
#: bal/gui/qt/dialogs.py:871 bal/gui/qt/dialogs.py:880
|
||||||
#: bal/gui/qt/dialogs.py:2241
|
#: bal/gui/qt/dialogs.py:2242
|
||||||
msgid "Checking your will"
|
msgid "Checking your will"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:872
|
#: bal/gui/qt/dialogs.py:873
|
||||||
msgid "An inheritance of this wallet is already executed (on blockchain)"
|
msgid "An inheritance of this wallet is already executed (on blockchain)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:881
|
#: bal/gui/qt/dialogs.py:882
|
||||||
msgid "Inheritance in mempool (waiting confirmation)"
|
msgid "Inheritance in mempool (waiting confirmation)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:914
|
#: bal/gui/qt/dialogs.py:915
|
||||||
msgid "Will-Executor excluded"
|
msgid "Will-Executor excluded"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:914 bal/gui/qt/dialogs.py:1008
|
#: bal/gui/qt/dialogs.py:915 bal/gui/qt/dialogs.py:1009
|
||||||
#: bal/gui/qt/dialogs.py:2222 bal/gui/qt/dialogs.py:2233
|
#: bal/gui/qt/dialogs.py:2223 bal/gui/qt/dialogs.py:2234
|
||||||
msgid "Skipped"
|
msgid "Skipped"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:920 bal/gui/qt/dialogs.py:1705 bal/gui/qt/lists.py:345
|
#: bal/gui/qt/dialogs.py:921 bal/gui/qt/dialogs.py:1706 bal/gui/qt/lists.py:345
|
||||||
#: bal/gui/qt/theme.py:116
|
#: bal/gui/qt/theme.py:116
|
||||||
msgid "Will-Executor"
|
msgid "Will-Executor"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:921
|
#: bal/gui/qt/dialogs.py:922
|
||||||
msgid "Not present - select one or enable backup mode"
|
msgid "Not present - select one or enable backup mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:982
|
#: bal/gui/qt/dialogs.py:983
|
||||||
msgid "All heirs' shares are below the dust limit: the inheritance cannot be created. Increase the amounts or reduce the number of heirs."
|
msgid "All heirs' shares are below the dust limit: the inheritance cannot be created. Increase the amounts or reduce the number of heirs."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:998
|
#: bal/gui/qt/dialogs.py:999
|
||||||
msgid "Wallet balance is too low: {} satoshi available, but the miner and will-executor fees need {} satoshi (the minimum usable amount is {} satoshi). Add funds, or select fewer will-executors."
|
msgid "Wallet balance is too low: {} satoshi available, but the miner and will-executor fees need {} satoshi (the minimum usable amount is {} satoshi). Add funds, or select fewer will-executors."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1042
|
#: bal/gui/qt/dialogs.py:1043
|
||||||
msgid "Heir {}"
|
msgid "Heir {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1044
|
#: bal/gui/qt/dialogs.py:1045
|
||||||
msgid "{} is DUST - excluded (amount below dust limit)"
|
msgid "{} is DUST - excluded (amount below dust limit)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1100
|
#: bal/gui/qt/dialogs.py:1101
|
||||||
msgid "Heir"
|
msgid "Heir"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1217 bal/gui/qt/dialogs.py:2270
|
#: bal/gui/qt/dialogs.py:1218 bal/gui/qt/dialogs.py:2271
|
||||||
msgid "Please wait {}secs"
|
msgid "Please wait {}secs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1224 bal/gui/qt/dialogs.py:1276
|
#: bal/gui/qt/dialogs.py:1225 bal/gui/qt/dialogs.py:1277
|
||||||
#: bal/gui/qt/dialogs.py:1314
|
#: bal/gui/qt/dialogs.py:1315
|
||||||
msgid "Broadcasting"
|
msgid "Broadcasting"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1335 bal/gui/qt/window.py:2317
|
#: bal/gui/qt/dialogs.py:1336 bal/gui/qt/window.py:2317
|
||||||
msgid "Ko"
|
msgid "Ko"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1346
|
#: bal/gui/qt/dialogs.py:1347
|
||||||
msgid "Timeout - no answer"
|
msgid "Timeout - no answer"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1388
|
#: bal/gui/qt/dialogs.py:1389
|
||||||
msgid "checking {} - {}"
|
msgid "checking {} - {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1391 bal/gui/qt/dialogs.py:2239
|
#: bal/gui/qt/dialogs.py:1392 bal/gui/qt/dialogs.py:2240
|
||||||
#: bal/gui/qt/window.py:1691
|
#: bal/gui/qt/window.py:1691
|
||||||
msgid "Waiting"
|
msgid "Waiting"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1405
|
#: bal/gui/qt/dialogs.py:1406
|
||||||
msgid "checked {} - {}"
|
msgid "checked {} - {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1455 bal/gui/qt/dialogs.py:2025
|
#: bal/gui/qt/dialogs.py:1456 bal/gui/qt/dialogs.py:2026
|
||||||
#: bal/gui/qt/dialogs.py:2036
|
#: bal/gui/qt/dialogs.py:2037
|
||||||
msgid "Error: {}"
|
msgid "Error: {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1516
|
#: bal/gui/qt/dialogs.py:1517
|
||||||
msgid ""
|
msgid ""
|
||||||
"Your will has expired and must be invalidated before it can be rebuilt.\n"
|
"Your will has expired and must be invalidated before it can be rebuilt.\n"
|
||||||
"A transaction window will now open:\n"
|
"A transaction window will now open:\n"
|
||||||
@@ -407,159 +406,159 @@ msgid ""
|
|||||||
"After the invalidation is confirmed, press the Check button to finish the will."
|
"After the invalidation is confirmed, press the Check button to finish the will."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1545 bal/gui/qt/window.py:849
|
#: bal/gui/qt/dialogs.py:1546 bal/gui/qt/window.py:849
|
||||||
msgid "Check Alive must be after today and before the delivery date, please update it"
|
msgid "Check Alive must be after today and before the delivery date, please update it"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1568
|
#: bal/gui/qt/dialogs.py:1569
|
||||||
msgid ""
|
msgid ""
|
||||||
"Your old will has been invalidated and the transaction was broadcast.\n"
|
"Your old will has been invalidated and the transaction was broadcast.\n"
|
||||||
"Electrum may need a little time to register it.\n"
|
"Electrum may need a little time to register it.\n"
|
||||||
"Please wait until the invalidation transaction is confirmed, then press the Check button again to finish updating your will."
|
"Please wait until the invalidation transaction is confirmed, then press the Check button again to finish updating your will."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1584
|
#: bal/gui/qt/dialogs.py:1585
|
||||||
msgid "Invalidate your old will"
|
msgid "Invalidate your old will"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1598 bal/gui/qt/dialogs.py:1643
|
#: bal/gui/qt/dialogs.py:1599 bal/gui/qt/dialogs.py:1644
|
||||||
msgid "Aborted"
|
msgid "Aborted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1617
|
#: bal/gui/qt/dialogs.py:1618
|
||||||
msgid "Auto-sign disabled — sign manually"
|
msgid "Auto-sign disabled — sign manually"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1630
|
#: bal/gui/qt/dialogs.py:1631
|
||||||
msgid ""
|
msgid ""
|
||||||
"The delivery date was automatically moved one day earlier so the updated will can correctly replace the previous one.\n"
|
"The delivery date was automatically moved one day earlier so the updated will can correctly replace the previous one.\n"
|
||||||
"Please sign (and broadcast) to confirm the change."
|
"Please sign (and broadcast) to confirm the change."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1640
|
#: bal/gui/qt/dialogs.py:1641
|
||||||
msgid "Sign your will"
|
msgid "Sign your will"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1645 bal/gui/qt/dialogs.py:1928
|
#: bal/gui/qt/dialogs.py:1646 bal/gui/qt/dialogs.py:1929
|
||||||
msgid "Nothing to do"
|
msgid "Nothing to do"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1664
|
#: bal/gui/qt/dialogs.py:1665
|
||||||
msgid "Finished"
|
msgid "Finished"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1681
|
#: bal/gui/qt/dialogs.py:1682
|
||||||
msgid "Calendar"
|
msgid "Calendar"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1683 bal/gui/qt/dialogs.py:1713
|
#: bal/gui/qt/dialogs.py:1684 bal/gui/qt/dialogs.py:1714
|
||||||
#: bal/gui/qt/dialogs.py:1780 bal/gui/qt/dialogs.py:2028
|
#: bal/gui/qt/dialogs.py:1781 bal/gui/qt/dialogs.py:2029
|
||||||
#: bal/gui/qt/dialogs.py:2968 bal/gui/qt/dialogs.py:3207
|
#: bal/gui/qt/dialogs.py:2976 bal/gui/qt/dialogs.py:3231
|
||||||
#: bal/gui/qt/dialogs.py:4038
|
#: bal/gui/qt/dialogs.py:4067
|
||||||
msgid "Close"
|
msgid "Close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1709 bal/gui/qt/dialogs.py:1776
|
#: bal/gui/qt/dialogs.py:1710 bal/gui/qt/dialogs.py:1777
|
||||||
msgid "🔮 Wizard"
|
msgid "🔮 Wizard"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1772 bal/gui/qt/dialogs.py:2580
|
#: bal/gui/qt/dialogs.py:1773 bal/gui/qt/dialogs.py:2581
|
||||||
msgid "Heirs"
|
msgid "Heirs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1881 bal/gui/qt/widgets.py:1150
|
#: bal/gui/qt/dialogs.py:1882 bal/gui/qt/widgets.py:1150
|
||||||
msgid "(reminder {idx}/{total})"
|
msgid "(reminder {idx}/{total})"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1945
|
#: bal/gui/qt/dialogs.py:1946
|
||||||
msgid "All done"
|
msgid "All done"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:1996
|
#: bal/gui/qt/dialogs.py:1997
|
||||||
msgid "Next steps (manual): press 'Sign' to sign your will, then 'Broadcast' to send it to the will-executors."
|
msgid "Next steps (manual): press 'Sign' to sign your will, then 'Broadcast' to send it to the will-executors."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2001
|
#: bal/gui/qt/dialogs.py:2002
|
||||||
msgid "Next step (manual): press 'Sign' to sign your will."
|
msgid "Next step (manual): press 'Sign' to sign your will."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2005
|
#: bal/gui/qt/dialogs.py:2006
|
||||||
msgid "Next step (manual): press 'Broadcast' to send your will to the will-executors."
|
msgid "Next step (manual): press 'Broadcast' to send your will to the will-executors."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2100
|
#: bal/gui/qt/dialogs.py:2101
|
||||||
msgid "Miner fee rate changed (the will was built with {} sat/byte, now it is {}): a new will must be prepared."
|
msgid "Miner fee rate changed (the will was built with {} sat/byte, now it is {}): a new will must be prepared."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2105
|
#: bal/gui/qt/dialogs.py:2106
|
||||||
msgid "The miner fee rate changed: a new will must be prepared."
|
msgid "The miner fee rate changed: a new will must be prepared."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2109
|
#: bal/gui/qt/dialogs.py:2110
|
||||||
msgid "Will-executor \"{}\" is not covered by the current will: a new will must be prepared."
|
msgid "Will-executor \"{}\" is not covered by the current will: a new will must be prepared."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2114
|
#: bal/gui/qt/dialogs.py:2115
|
||||||
msgid "Backup mode is enabled but the will has no backup transaction: a new will must be prepared."
|
msgid "Backup mode is enabled but the will has no backup transaction: a new will must be prepared."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2123
|
#: bal/gui/qt/dialogs.py:2124
|
||||||
msgid "Heir \"{}\" is not covered by the current will (it was added or removed, or its delivery date changed): a new will must be prepared."
|
msgid "Heir \"{}\" is not covered by the current will (it was added or removed, or its delivery date changed): a new will must be prepared."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2132
|
#: bal/gui/qt/dialogs.py:2133
|
||||||
msgid "The heirs changed: a new will must be prepared."
|
msgid "The heirs changed: a new will must be prepared."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2134
|
#: bal/gui/qt/dialogs.py:2135
|
||||||
msgid "A will-executor changed: a new will must be prepared."
|
msgid "A will-executor changed: a new will must be prepared."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2143
|
#: bal/gui/qt/dialogs.py:2144
|
||||||
msgid "The wallet contains funds that the current will does not cover yet: a new will must be prepared."
|
msgid "The wallet contains funds that the current will does not cover yet: a new will must be prepared."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2147
|
#: bal/gui/qt/dialogs.py:2148
|
||||||
msgid "The will contains no valid transaction: a new will must be prepared."
|
msgid "The will contains no valid transaction: a new will must be prepared."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2153
|
#: bal/gui/qt/dialogs.py:2154
|
||||||
msgid "The will is no longer coherent and must be rebuilt; the exact reason could not be determined."
|
msgid "The will is no longer coherent and must be rebuilt; the exact reason could not be determined."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2183
|
#: bal/gui/qt/dialogs.py:2184
|
||||||
msgid "No heirs: add at least one heir before building the will."
|
msgid "No heirs: add at least one heir before building the will."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2186
|
#: bal/gui/qt/dialogs.py:2187
|
||||||
msgid "The wallet has no spendable funds, so no inheritance transaction can be created."
|
msgid "The wallet has no spendable funds, so no inheritance transaction can be created."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2190
|
#: bal/gui/qt/dialogs.py:2191
|
||||||
msgid "No usable will-executor: none of the servers in the list is both selected and valid. Open the will-executor settings, select at least one server and check that it is reachable."
|
msgid "No usable will-executor: none of the servers in the list is both selected and valid. Open the will-executor settings, select at least one server and check that it is reachable."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2195
|
#: bal/gui/qt/dialogs.py:2196
|
||||||
msgid "No delivery date left to build: every heir's date is already covered by the existing will. Choose a later delivery date, or change an heir's date."
|
msgid "No delivery date left to build: every heir's date is already covered by the existing will. Choose a later delivery date, or change an heir's date."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2200
|
#: bal/gui/qt/dialogs.py:2201
|
||||||
msgid "The amount to send must cover the miner fees plus this will-executor's fee, and the wallet balance is not enough: select cheaper will-executors, or add funds to the wallet."
|
msgid "The amount to send must cover the miner fees plus this will-executor's fee, and the wallet balance is not enough: select cheaper will-executors, or add funds to the wallet."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2205
|
#: bal/gui/qt/dialogs.py:2206
|
||||||
msgid "A will-executor asks for more than the maximum fee you allowed: raise the maximum fee in the settings, or select a cheaper will-executor."
|
msgid "A will-executor asks for more than the maximum fee you allowed: raise the maximum fee in the settings, or select a cheaper will-executor."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2210
|
#: bal/gui/qt/dialogs.py:2211
|
||||||
msgid "The inheritance transactions could not be assembled from the available funds (the balance may not cover the miner fees)."
|
msgid "The inheritance transactions could not be assembled from the available funds (the balance may not cover the miner fees)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2214
|
#: bal/gui/qt/dialogs.py:2215
|
||||||
msgid "An unexpected error stopped the transactions being prepared for a will-executor, so it was skipped. Try again, or select a different will-executor."
|
msgid "An unexpected error stopped the transactions being prepared for a will-executor, so it was skipped. Try again, or select a different will-executor."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2225
|
#: bal/gui/qt/dialogs.py:2226
|
||||||
msgid ""
|
msgid ""
|
||||||
"Could not build the will, and the exact cause could not be determined. Please check that:\n"
|
"Could not build the will, and the exact cause could not be determined. Please check that:\n"
|
||||||
"- the wallet balance covers the miner and will-executor fees,\n"
|
"- the wallet balance covers the miner and will-executor fees,\n"
|
||||||
@@ -568,403 +567,403 @@ msgid ""
|
|||||||
"- at least one will-executor is selected and reachable."
|
"- at least one will-executor is selected and reachable."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2246
|
#: bal/gui/qt/dialogs.py:2247
|
||||||
msgid "Invalidating old will"
|
msgid "Invalidating old will"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2252
|
#: bal/gui/qt/dialogs.py:2253
|
||||||
msgid "Building your will"
|
msgid "Building your will"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2258
|
#: bal/gui/qt/dialogs.py:2259
|
||||||
msgid "Signing your will"
|
msgid "Signing your will"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2264
|
#: bal/gui/qt/dialogs.py:2265
|
||||||
msgid "Broadcasting your will to executors"
|
msgid "Broadcasting your will to executors"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2312
|
#: bal/gui/qt/dialogs.py:2313
|
||||||
msgid "Wait"
|
msgid "Wait"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2415
|
#: bal/gui/qt/dialogs.py:2416
|
||||||
msgid "Will Details"
|
msgid "Will Details"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2421 bal/gui/qt/dialogs.py:4013
|
#: bal/gui/qt/dialogs.py:2422 bal/gui/qt/dialogs.py:4042
|
||||||
#: bal/gui/qt/lists.py:668
|
#: bal/gui/qt/lists.py:668
|
||||||
msgid "Sign"
|
msgid "Sign"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2425 bal/gui/qt/lists.py:675
|
#: bal/gui/qt/dialogs.py:2426 bal/gui/qt/lists.py:675
|
||||||
msgid "Broadcast"
|
msgid "Broadcast"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2432 bal/gui/qt/lists.py:677
|
#: bal/gui/qt/dialogs.py:2433 bal/gui/qt/lists.py:677
|
||||||
msgid "Invalidate"
|
msgid "Invalidate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2437 bal/gui/qt/lists.py:674
|
#: bal/gui/qt/dialogs.py:2438 bal/gui/qt/lists.py:674
|
||||||
msgid "Merge"
|
msgid "Merge"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2445
|
#: bal/gui/qt/dialogs.py:2446
|
||||||
msgid "Expiration date: {}"
|
msgid "Expiration date: {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2451
|
#: bal/gui/qt/dialogs.py:2452
|
||||||
msgid "Valid Txs:{}"
|
msgid "Valid Txs:{}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2453
|
#: bal/gui/qt/dialogs.py:2454
|
||||||
msgid "Total Txs:{}"
|
msgid "Total Txs:{}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2507
|
#: bal/gui/qt/dialogs.py:2508
|
||||||
msgid "Hide replaced"
|
msgid "Hide replaced"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2509
|
#: bal/gui/qt/dialogs.py:2510
|
||||||
msgid "Unhide replaced"
|
msgid "Unhide replaced"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2515
|
#: bal/gui/qt/dialogs.py:2516
|
||||||
msgid "Hide invalidated"
|
msgid "Hide invalidated"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2517
|
#: bal/gui/qt/dialogs.py:2518
|
||||||
msgid "Unhide invalidated"
|
msgid "Unhide invalidated"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2542
|
#: bal/gui/qt/dialogs.py:2543
|
||||||
msgid "Will-Executor Service List"
|
msgid "Will-Executor Service List"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2589 bal/gui/qt/lists.py:314
|
#: bal/gui/qt/dialogs.py:2590 bal/gui/qt/lists.py:314
|
||||||
msgid "New Heir"
|
msgid "New Heir"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2631
|
#: bal/gui/qt/dialogs.py:2632
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2634
|
#: bal/gui/qt/dialogs.py:2635
|
||||||
msgid "Valid NC"
|
msgid "Valid NC"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2771 bal/gui/qt/dialogs.py:2847
|
#: bal/gui/qt/dialogs.py:2773 bal/gui/qt/dialogs.py:2851
|
||||||
msgid "Auto"
|
msgid "Auto"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2773
|
#: bal/gui/qt/dialogs.py:2775
|
||||||
msgid "Automatically advance through the QR codes."
|
msgid "Automatically advance through the QR codes."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2777
|
#: bal/gui/qt/dialogs.py:2779
|
||||||
msgid "QR codes per second:"
|
msgid "QR codes per second:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2781
|
#: bal/gui/qt/dialogs.py:2783
|
||||||
msgid " /s"
|
msgid " /s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2783
|
#: bal/gui/qt/dialogs.py:2785
|
||||||
msgid "Loop"
|
msgid "Loop"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2785
|
#: bal/gui/qt/dialogs.py:2787
|
||||||
msgid "When the last QR code is reached, keep cycling from the first one instead of stopping."
|
msgid "When the last QR code is reached, keep cycling from the first one instead of stopping."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2795
|
#: bal/gui/qt/dialogs.py:2797
|
||||||
msgid "QR code size:"
|
msgid "QR code size:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2841
|
#: bal/gui/qt/dialogs.py:2845
|
||||||
msgid "Stop"
|
msgid "Stop"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2862
|
#: bal/gui/qt/dialogs.py:2866
|
||||||
msgid ""
|
msgid ""
|
||||||
"Scan the QR codes below with the will-opening device.\n"
|
"Scan the QR codes below with the will-opening device.\n"
|
||||||
"{} codes carry the whole transfer (any order works, duplicates are ignored)."
|
"{} codes carry the whole transfer (any order works, duplicates are ignored)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2884
|
#: bal/gui/qt/dialogs.py:2888
|
||||||
msgid "Frame {} of {}"
|
msgid "Frame {} of {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2907
|
#: bal/gui/qt/dialogs.py:2911
|
||||||
msgid "Export will"
|
msgid "Export will"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2917
|
#: bal/gui/qt/dialogs.py:2922
|
||||||
msgid "No will transaction to export."
|
msgid "No will transaction to export."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2924
|
#: bal/gui/qt/dialogs.py:2929
|
||||||
msgid "Export:"
|
msgid "Export:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2931
|
#: bal/gui/qt/dialogs.py:2936
|
||||||
msgid "Whole will"
|
msgid "Whole will"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2934
|
#: bal/gui/qt/dialogs.py:2939
|
||||||
msgid "Export the full will items (all details/statuses) as JSON, or only the serialized transactions."
|
msgid "Export the full will items (all details/statuses) as JSON, or only the serialized transactions."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2945
|
#: bal/gui/qt/dialogs.py:2950
|
||||||
msgid "Send as:"
|
msgid "Send as:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2947 bal/gui/qt/dialogs.py:3184
|
#: bal/gui/qt/dialogs.py:2952 bal/gui/qt/dialogs.py:3208
|
||||||
msgid "File"
|
msgid "File"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2948 bal/gui/qt/dialogs.py:3185
|
#: bal/gui/qt/dialogs.py:2953 bal/gui/qt/dialogs.py:3209
|
||||||
msgid "QR Code"
|
msgid "QR Code"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2949 bal/gui/qt/dialogs.py:3186
|
#: bal/gui/qt/dialogs.py:2954 bal/gui/qt/dialogs.py:3210
|
||||||
msgid "Audio"
|
msgid "Audio"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2990
|
#: bal/gui/qt/dialogs.py:3005
|
||||||
msgid "Export the will as a JSON file. Uncheck \"Whole will\" above to export only the serialized transactions (comma-separated)."
|
msgid "Export the will as a JSON file. Uncheck \"Whole will\" above to export only the serialized transactions (comma-separated)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:2999
|
#: bal/gui/qt/dialogs.py:3014
|
||||||
msgid "Export…"
|
msgid "Export…"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3016 bal/gui/qt/dialogs.py:3242
|
#: bal/gui/qt/dialogs.py:3032 bal/gui/qt/dialogs.py:3271
|
||||||
#: bal/gui/qt/window.py:1787 bal/gui/qt/window.py:1800
|
#: bal/gui/qt/window.py:1787 bal/gui/qt/window.py:1800
|
||||||
msgid "Audio MODEM plugin is not available."
|
msgid "Audio MODEM plugin is not available."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3020 bal/gui/qt/dialogs.py:3246
|
#: bal/gui/qt/dialogs.py:3036 bal/gui/qt/dialogs.py:3275
|
||||||
msgid "Speed (KB/sec):"
|
msgid "Speed (KB/sec):"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3031
|
#: bal/gui/qt/dialogs.py:3047
|
||||||
msgid "Send"
|
msgid "Send"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3076 bal/gui/qt/dialogs.py:3110
|
#: bal/gui/qt/dialogs.py:3100 bal/gui/qt/dialogs.py:3134
|
||||||
#: bal/gui/qt/dialogs.py:3135
|
#: bal/gui/qt/dialogs.py:3159
|
||||||
msgid "No will transaction matches the selected filter."
|
msgid "No will transaction matches the selected filter."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3099
|
#: bal/gui/qt/dialogs.py:3123
|
||||||
msgid "item(s)"
|
msgid "item(s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3099
|
#: bal/gui/qt/dialogs.py:3123
|
||||||
msgid "transaction(s)"
|
msgid "transaction(s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3101
|
#: bal/gui/qt/dialogs.py:3125
|
||||||
msgid "{} {} will be exported."
|
msgid "{} {} will be exported."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3104
|
#: bal/gui/qt/dialogs.py:3128
|
||||||
msgid "{} {} will be sent."
|
msgid "{} {} will be sent."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3128 bal/gui/qt/dialogs.py:3131
|
#: bal/gui/qt/dialogs.py:3152 bal/gui/qt/dialogs.py:3155
|
||||||
#: bal/gui/qt/dialogs.py:3282 bal/gui/qt/dialogs.py:3285
|
#: bal/gui/qt/dialogs.py:3311 bal/gui/qt/dialogs.py:3314
|
||||||
msgid "Invalid audio speed."
|
msgid "Invalid audio speed."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3167
|
#: bal/gui/qt/dialogs.py:3191
|
||||||
msgid "Import will"
|
msgid "Import will"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3173
|
#: bal/gui/qt/dialogs.py:3197
|
||||||
msgid ""
|
msgid ""
|
||||||
"Choose how the will was exported: from a file, QR codes or audio.\n"
|
"Choose how the will was exported: from a file, QR codes or audio.\n"
|
||||||
"The import never touches the live will."
|
"The import never touches the live will."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3182
|
#: bal/gui/qt/dialogs.py:3206
|
||||||
msgid "Import from:"
|
msgid "Import from:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3218
|
#: bal/gui/qt/dialogs.py:3246
|
||||||
msgid "Import the JSON will file written by the Export ▶ File option. The will opens in a read-only preview window."
|
msgid "Import the JSON will file written by the Export ▶ File option. The will opens in a read-only preview window."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3225
|
#: bal/gui/qt/dialogs.py:3253
|
||||||
msgid "Choose will file…"
|
msgid "Choose will file…"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3255
|
#: bal/gui/qt/dialogs.py:3284
|
||||||
msgid "Waiting for the audio transfer…"
|
msgid "Waiting for the audio transfer…"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3258
|
#: bal/gui/qt/dialogs.py:3287
|
||||||
msgid "Receive by audio…"
|
msgid "Receive by audio…"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3299
|
#: bal/gui/qt/dialogs.py:3328
|
||||||
msgid "Receiving…"
|
msgid "Receiving…"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3319
|
#: bal/gui/qt/dialogs.py:3348
|
||||||
msgid "No transaction data received."
|
msgid "No transaction data received."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3337
|
#: bal/gui/qt/dialogs.py:3366
|
||||||
msgid "Waiting for audio ({:.1f} kbps)…"
|
msgid "Waiting for audio ({:.1f} kbps)…"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3410
|
#: bal/gui/qt/dialogs.py:3439
|
||||||
msgid "Could not parse a transferred will item: {}"
|
msgid "Could not parse a transferred will item: {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3430
|
#: bal/gui/qt/dialogs.py:3459
|
||||||
msgid "Could not parse a transferred transaction: {}"
|
msgid "Could not parse a transferred transaction: {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3441
|
#: bal/gui/qt/dialogs.py:3470
|
||||||
msgid "The imported will contains no valid transaction in this wallet."
|
msgid "The imported will contains no valid transaction in this wallet."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3452
|
#: bal/gui/qt/dialogs.py:3481
|
||||||
msgid "{} imported transaction(s) are not valid in this wallet and were skipped."
|
msgid "{} imported transaction(s) are not valid in this wallet and were skipped."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3552
|
#: bal/gui/qt/dialogs.py:3581
|
||||||
msgid ""
|
msgid ""
|
||||||
"Show the will QR codes to the camera, one after another.\n"
|
"Show the will QR codes to the camera, one after another.\n"
|
||||||
"After the first code, every new code is captured automatically.\n"
|
"After the first code, every new code is captured automatically.\n"
|
||||||
"The first frame sets the total number of codes; duplicates are ignored."
|
"The first frame sets the total number of codes; duplicates are ignored."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3562 bal/gui/qt/dialogs.py:3740
|
#: bal/gui/qt/dialogs.py:3591 bal/gui/qt/dialogs.py:3769
|
||||||
msgid "Waiting for the first frame…"
|
msgid "Waiting for the first frame…"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3579
|
#: bal/gui/qt/dialogs.py:3608
|
||||||
msgid "…or paste/type the frame text here"
|
msgid "…or paste/type the frame text here"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3583
|
#: bal/gui/qt/dialogs.py:3612
|
||||||
msgid "Add frame"
|
msgid "Add frame"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3589 bal/gui/qt/dialogs.py:3832
|
#: bal/gui/qt/dialogs.py:3618 bal/gui/qt/dialogs.py:3861
|
||||||
msgid "Scan with camera…"
|
msgid "Scan with camera…"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3591
|
#: bal/gui/qt/dialogs.py:3620
|
||||||
msgid "Start the live camera. While it runs, every new QR code shown to the camera is captured automatically."
|
msgid "Start the live camera. While it runs, every new QR code shown to the camera is captured automatically."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3598
|
#: bal/gui/qt/dialogs.py:3627
|
||||||
msgid "Reset"
|
msgid "Reset"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3605
|
#: bal/gui/qt/dialogs.py:3634
|
||||||
msgid "Review and Sign…"
|
msgid "Review and Sign…"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3624
|
#: bal/gui/qt/dialogs.py:3653
|
||||||
msgid "The scanned code belongs to a different transfer ({} frames, {}). The import was reset; scan the first code again."
|
msgid "The scanned code belongs to a different transfer ({} frames, {}). The import was reset; scan the first code again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3715
|
#: bal/gui/qt/dialogs.py:3744
|
||||||
msgid "All {} frames stored."
|
msgid "All {} frames stored."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3721
|
#: bal/gui/qt/dialogs.py:3750
|
||||||
msgid "Stored {} of {} frames."
|
msgid "Stored {} of {} frames."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3786
|
#: bal/gui/qt/dialogs.py:3815
|
||||||
msgid "Cannot start QR scanner, no usable camera found."
|
msgid "Cannot start QR scanner, no usable camera found."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3791
|
#: bal/gui/qt/dialogs.py:3820
|
||||||
msgid "Stop scanning"
|
msgid "Stop scanning"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3838
|
#: bal/gui/qt/dialogs.py:3867
|
||||||
msgid "Camera error: {}"
|
msgid "Camera error: {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3884
|
#: bal/gui/qt/dialogs.py:3913
|
||||||
msgid "The scanned code belongs to a different transfer ({} frames, {}). The import was reset; show the first code again."
|
msgid "The scanned code belongs to a different transfer ({} frames, {}). The import was reset; show the first code again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3928
|
#: bal/gui/qt/dialogs.py:3957
|
||||||
msgid "The transferred will contains no transactions."
|
msgid "The transferred will contains no transactions."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3957
|
#: bal/gui/qt/dialogs.py:3986
|
||||||
msgid "Review and sign imported will"
|
msgid "Review and sign imported will"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:3969
|
#: bal/gui/qt/dialogs.py:3998
|
||||||
msgid "Enter your wallet password to sign the imported transactions."
|
msgid "Enter your wallet password to sign the imported transactions."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:4016
|
#: bal/gui/qt/dialogs.py:4045
|
||||||
msgid "Skip"
|
msgid "Skip"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:4032
|
#: bal/gui/qt/dialogs.py:4061
|
||||||
msgid "Save signed file…"
|
msgid "Save signed file…"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:4035
|
#: bal/gui/qt/dialogs.py:4064
|
||||||
msgid "Show signed QR…"
|
msgid "Show signed QR…"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:4059
|
#: bal/gui/qt/dialogs.py:4088
|
||||||
msgid "Transaction {} of {}"
|
msgid "Transaction {} of {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:4061
|
#: bal/gui/qt/dialogs.py:4090
|
||||||
msgid "TXID: {}"
|
msgid "TXID: {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:4064
|
#: bal/gui/qt/dialogs.py:4093
|
||||||
msgid "unknown"
|
msgid "unknown"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:4070
|
#: bal/gui/qt/dialogs.py:4099
|
||||||
msgid "(no outputs)"
|
msgid "(no outputs)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:4084
|
#: bal/gui/qt/dialogs.py:4113
|
||||||
msgid "unknown (partial transaction)"
|
msgid "unknown (partial transaction)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:4086
|
#: bal/gui/qt/dialogs.py:4115
|
||||||
msgid ""
|
msgid ""
|
||||||
"Total outputs: {}\n"
|
"Total outputs: {}\n"
|
||||||
"Fee: {}"
|
"Fee: {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:4097
|
#: bal/gui/qt/dialogs.py:4126
|
||||||
msgid ""
|
msgid ""
|
||||||
"Signed {} of {} transactions.\n"
|
"Signed {} of {} transactions.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Save a signed file to carry to the broadcast device, or show the signed transactions as QR codes."
|
"Save a signed file to carry to the broadcast device, or show the signed transactions as QR codes."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:4116
|
#: bal/gui/qt/dialogs.py:4145
|
||||||
msgid "Could not sign the transaction: {}"
|
msgid "Could not sign the transaction: {}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:4135
|
#: bal/gui/qt/dialogs.py:4164
|
||||||
msgid "Signed will saved."
|
msgid "Signed will saved."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bal/gui/qt/dialogs.py:4146
|
#: bal/gui/qt/dialogs.py:4175
|
||||||
msgid "No signed transaction to show."
|
msgid "No signed transaction to show."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
|||||||
# ./make-release.sh # read version from bal/manifest.json
|
# ./make-release.sh # read version from bal/manifest.json
|
||||||
# ./make-release.sh v0.6.2 # bump manifest to 0.6.2, then release
|
# ./make-release.sh v0.6.2 # bump manifest to 0.6.2, then release
|
||||||
#
|
#
|
||||||
# Requires: git, gpg, curl, python3, sha256sum
|
# Requires: git, gpg, curl, python3, sha256sum, Babel for python3 (pip install babel)
|
||||||
# Optional: ruff (lint skipped if not installed)
|
# Optional: ruff (lint skipped if not installed)
|
||||||
# Credentials: ~/.git-credentials or GITEA_USER / GITEA_TOKEN env vars
|
# Credentials: ~/.git-credentials or GITEA_USER / GITEA_TOKEN env vars
|
||||||
|
|
||||||
@@ -33,6 +33,12 @@ else
|
|||||||
NEW_VER=""
|
NEW_VER=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Babel is needed by the i18n tests (step 3) and by build_zip.py, which
|
||||||
|
# compiles the translation catalogs into the zip (step 5). Check it up front
|
||||||
|
# so a release never stops half-way.
|
||||||
|
python3 -c "import babel" 2>/dev/null \
|
||||||
|
|| die "Babel is missing for $(command -v python3): pip install babel"
|
||||||
|
|
||||||
echo "=== Release ${TAG} ==="
|
echo "=== Release ${TAG} ==="
|
||||||
echo "Current manifest version: ${CURRENT_VER}"
|
echo "Current manifest version: ${CURRENT_VER}"
|
||||||
[ -n "$NEW_VER" ] && echo "New version (will bump): ${NEW_VER}"
|
[ -n "$NEW_VER" ] && echo "New version (will bump): ${NEW_VER}"
|
||||||
@@ -68,6 +74,8 @@ if QT_QPA_PLATFORM=offscreen PYTHONPATH=electrum-src python3 -m pytest \
|
|||||||
tests/test_group_d_alarms.py tests/test_group_e_mock_karen7.py \
|
tests/test_group_d_alarms.py tests/test_group_e_mock_karen7.py \
|
||||||
tests/test_group_f_heir_change_rebuild.py tests/test_group_g_basic_calendar.py \
|
tests/test_group_f_heir_change_rebuild.py tests/test_group_g_basic_calendar.py \
|
||||||
tests/test_group_h_v048.py \
|
tests/test_group_h_v048.py \
|
||||||
|
tests/test_i18n.py tests/test_translations.py \
|
||||||
|
tests/test_cli_*.py tests/test_import_will_details.py \
|
||||||
-q 2>&1; then
|
-q 2>&1; then
|
||||||
echo "All tests passed."
|
echo "All tests passed."
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -6,6 +6,12 @@ target-version = "py312"
|
|||||||
select =["E", "W", "F", "I", "N", "B", "INT"] # INT: gettext rules (see bal/i18n.py)
|
select =["E", "W", "F", "I", "N", "B", "INT"] # INT: gettext rules (see bal/i18n.py)
|
||||||
ignore = ["E501"]
|
ignore = ["E501"]
|
||||||
|
|
||||||
|
[tool.ruff.lint.isort]
|
||||||
|
# Classify the plugin package explicitly: otherwise ruff decides from where it
|
||||||
|
# is run / how the project root is detected, and the same import block is
|
||||||
|
# "sorted" on one machine and I001 on another.
|
||||||
|
known-first-party = ["bal"]
|
||||||
|
|
||||||
[tool.ruff.lint.pep8-naming]
|
[tool.ruff.lint.pep8-naming]
|
||||||
classmethod-decorators = ["classmethod", "classproperty"] # electrum.util.classproperty uses cls
|
classmethod-decorators = ["classmethod", "classproperty"] # electrum.util.classproperty uses cls
|
||||||
|
|
||||||
|
|||||||
136
tests/test_core_status_language_neutral.py
Normal file
136
tests/test_core_status_language_neutral.py
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
"""
|
||||||
|
Stored will data must not depend on the GUI language (rule in bal/i18n.py).
|
||||||
|
|
||||||
|
Covers the two findings of the i18n review:
|
||||||
|
|
||||||
|
* the status history of a new will item is saved as English "New" (not
|
||||||
|
``_("New")``), and histories saved by test builds as "Nuovo"/"Nuevo" are
|
||||||
|
mapped back to "New" on load;
|
||||||
|
* the push helper no longer writes transient fields (``txs``, ``txsids`` and
|
||||||
|
the translated ``broadcast_status``) into the will item's executor record,
|
||||||
|
and such fields saved by older versions are dropped on load.
|
||||||
|
|
||||||
|
Run (standalone or with pytest):
|
||||||
|
QT_QPA_PLATFORM=offscreen PYTHONPATH=electrum-src \
|
||||||
|
python3 tests/test_core_status_language_neutral.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir))
|
||||||
|
|
||||||
|
from electrum.transaction import Transaction
|
||||||
|
|
||||||
|
from bal.core.will import WillItem
|
||||||
|
from bal.core.willexecutors import Willexecutors
|
||||||
|
|
||||||
|
# WillItem parses a raw tx and calls add_info_from_wallet; no live wallet here.
|
||||||
|
_patcher = patch.object(Transaction, "add_info_from_wallet")
|
||||||
|
_patcher.start()
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
_VALID_TX_HEX = (
|
||||||
|
"01000000012a5c9a94fcde98f5581cd00162c60a13936ceb75389ea65b"
|
||||||
|
"f38633b424eb4031000000006c493046022100a82bbc57a0136751e543"
|
||||||
|
"3f41cf000b3f1a99c6744775e76ec764fb78c54ee100022100f9e80b7d"
|
||||||
|
"e89de861dc6fb0c1429d5da72c2b6b2ee2406bc9bfb1beedd729d98501"
|
||||||
|
"2102e61d176da16edd1d258a200ad9759ef63adf8e14cd97f53227bae3"
|
||||||
|
"5cdb84d2f6ffffffff0140420f00000000001976a914230ac37834073a"
|
||||||
|
"42146f11ef8414ae929feaafc388ac00000000"
|
||||||
|
)
|
||||||
|
URL = "https://we.example"
|
||||||
|
|
||||||
|
|
||||||
|
def _item(status="", we=None):
|
||||||
|
return WillItem(
|
||||||
|
{"tx": _VALID_TX_HEX, "heirs": {}, "willexecutor": we, "status": status}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------ #
|
||||||
|
# Status history "New"
|
||||||
|
# ------------------------------------------------------------------ #
|
||||||
|
|
||||||
|
def test_builders_store_english_new():
|
||||||
|
"""window.py and the CLI controller must not translate the stored status."""
|
||||||
|
for rel in ("bal/gui/qt/window.py", "bal/cli/controller.py"):
|
||||||
|
src = (ROOT / rel).read_text(encoding="utf-8")
|
||||||
|
assert re.search(r'tx\["status"\]\s*=\s*"New"', src), rel
|
||||||
|
assert not re.search(r'tx\["status"\]\s*=\s*_\(', src), rel
|
||||||
|
|
||||||
|
|
||||||
|
def test_translated_new_is_mapped_back_on_load():
|
||||||
|
assert _item("Nuovo.Signed.Pushed").status == "New.Signed.Pushed"
|
||||||
|
assert _item("Nuevo").status == "New"
|
||||||
|
assert _item("New.Signed").status == "New.Signed"
|
||||||
|
|
||||||
|
|
||||||
|
def test_only_the_leading_new_is_touched():
|
||||||
|
assert _item(".Nuovo").status == ".Nuovo"
|
||||||
|
assert _item("Signed.Nuovo").status == "Signed.Nuovo"
|
||||||
|
|
||||||
|
|
||||||
|
def test_translated_new_labels_match_the_catalogs():
|
||||||
|
"""Every catalog's translation of "New" must be recognised on load."""
|
||||||
|
found = set()
|
||||||
|
for po in (ROOT / "bal" / "locale").glob("*/LC_MESSAGES/bal.po"):
|
||||||
|
text = po.read_text(encoding="utf-8")
|
||||||
|
m = re.search(r'^msgid "New"\nmsgstr "(.*)"$', text, re.MULTILINE)
|
||||||
|
if m and m.group(1):
|
||||||
|
found.add(m.group(1))
|
||||||
|
assert found, "no catalog translates 'New'"
|
||||||
|
assert found <= set(WillItem.TRANSLATED_NEW_LABELS), found
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------ #
|
||||||
|
# Transient push fields
|
||||||
|
# ------------------------------------------------------------------ #
|
||||||
|
|
||||||
|
class FakeItem:
|
||||||
|
def __init__(self):
|
||||||
|
self.we = {"url": URL, "selected": True, "address": "a", "base_fee": 1}
|
||||||
|
self.tx = "rawtx"
|
||||||
|
|
||||||
|
def get_status(self, name):
|
||||||
|
return name in ("VALID", "COMPLETE")
|
||||||
|
|
||||||
|
|
||||||
|
def test_push_helper_does_not_modify_the_will_item():
|
||||||
|
item = FakeItem()
|
||||||
|
before = dict(item.we)
|
||||||
|
out = Willexecutors.get_willexecutor_transactions({"t1": item})
|
||||||
|
assert out[URL]["txsids"] == ["t1"]
|
||||||
|
assert "broadcast_status" in out[URL]
|
||||||
|
assert item.we == before
|
||||||
|
assert out[URL] is not item.we
|
||||||
|
|
||||||
|
|
||||||
|
def test_transient_fields_saved_by_older_versions_are_dropped_on_load():
|
||||||
|
we = {
|
||||||
|
"url": URL,
|
||||||
|
"selected": True,
|
||||||
|
"txs": "raw\n",
|
||||||
|
"txsids": ["t1"],
|
||||||
|
"broadcast_status": "Riuscito",
|
||||||
|
}
|
||||||
|
item = _item("New", we)
|
||||||
|
assert item.we == {"url": URL, "selected": True}
|
||||||
|
assert "broadcast_status" not in item.to_dict()["willexecutor"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_clean_executor_record_is_kept_as_is():
|
||||||
|
we = {"url": URL, "selected": True}
|
||||||
|
assert _item("New", we).we is we
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
for name in sorted(dir()):
|
||||||
|
if name.startswith("test_"):
|
||||||
|
globals()[name]()
|
||||||
|
print(f" [OK] {name}")
|
||||||
|
print("[OK] All language-neutral status tests passed")
|
||||||
Reference in New Issue
Block a user