From 3d6e1befe63a54cdb9c59cd35e5640e791f0fcdf Mon Sep 17 00:00:00 2001 From: zebra-lucky Date: Thu, 16 Oct 2025 16:37:06 +0300 Subject: [PATCH] Qt: add async JMPasswordDialog --- scripts/joinmarket-qt.py | 37 ++++++---------------- scripts/qtsupport.py | 66 ++++++++++++++++++++++++++++++++-------- 2 files changed, 64 insertions(+), 39 deletions(-) diff --git a/scripts/joinmarket-qt.py b/scripts/joinmarket-qt.py index bf3410e..531e7a3 100755 --- a/scripts/joinmarket-qt.py +++ b/scripts/joinmarket-qt.py @@ -80,7 +80,7 @@ from jmclient.wallet import BaseWallet from qtsupport import ScheduleWizard, TumbleRestartWizard, config_tips,\ config_types, QtHandler, XStream, Buttons, OkButton, CancelButton,\ - PasswordDialog, MyTreeWidget, JMQtMessageBox, BLUE_FG,\ + JMPasswordDialog, MyTreeWidget, JMQtMessageBox, BLUE_FG,\ donation_more_message, BitcoinAmountEdit, JMIntValidator,\ ReceiveBIP78Dialog, QRCodePopup @@ -2332,29 +2332,8 @@ class JMMainWindow(QMainWindow): title="Error")) async def getPassword(self) -> str: - pd = PasswordDialog() - while True: - for child in pd.findChildren(QLineEdit): - child.clear() - pd.findChild(QLineEdit).setFocus() - pd_return = pd.exec_() - if pd_return == QDialog.Rejected: - return None - elif pd.new_pw.text() != pd.conf_pw.text(): - await JMQtMessageBox(self, - "Passphrases don't match.", - mbtype='warn', - title="Error") - continue - elif pd.new_pw.text() == "": - await JMQtMessageBox(self, - "Passphrase must not be empty.", - mbtype='warn', - title="Error") - continue - break - self.textpassword = str(pd.new_pw.text()) - return self.textpassword.encode('utf-8') + self.textpassword = textpassword = await JMPasswordDialog(parent=self) + return textpassword.encode('utf-8') if textpassword else textpassword def getWalletFileName(self) -> str: walletname, ok = QInputDialog.getText(self, 'Choose wallet name', @@ -2383,10 +2362,14 @@ class JMMainWindow(QMainWindow): self, seed_recovery_warning, mbtype='info', title='Show wallet seed phrase', informative_text=text)) - def promptUseMnemonicExtension(self) -> bool: - msg = "Would you like to use a two-factor mnemonic recovery phrase?\nIf you don\'t know what this is press No." - reply = QMessageBox.question(self, 'Use mnemonic extension?', + async def promptUseMnemonicExtension(self) -> bool: + msg = ("Would you like to use a two-factor mnemonic recovery " + "phrase?\nIf you don\'t know what this is press No.") + reply = JMQtMessageBox.question(self, 'Use mnemonic extension?', msg, QMessageBox.Yes, QMessageBox.No) + reply = await JMQtMessageBox( + self, msg, title='Use mnemonic extension?', + mbtype='question') return reply == QMessageBox.Yes def promptInputMnemonicExtension(self) -> Optional[str]: diff --git a/scripts/qtsupport.py b/scripts/qtsupport.py index 9c2a8b9..c61bbbc 100644 --- a/scripts/qtsupport.py +++ b/scripts/qtsupport.py @@ -153,12 +153,12 @@ async def JMQtMessageBox(parent, msg, mbtype='info', title='', detailed_text=None, informative_text=None, finished_cb=None): title = "JoinmarketQt - " + title - result_fut = asyncio.get_event_loop().create_future() class JMQtDMessageBox(QMessageBox): def __init__(self, parent): QMessageBox.__init__(self, parent=parent) + self.result_fut = asyncio.get_event_loop().create_future() self.setSizeGripEnabled(True) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.layout().setSizeConstraint(QLayout.SetMaximumSize) @@ -184,7 +184,11 @@ async def JMQtMessageBox(parent, msg, mbtype='info', title='', @QtCore.Slot(QMessageBox.StandardButton) def on_finished(self, button): - result_fut.set_result(button) + self.result_fut.set_result(button) + + async def result(self): + await self.result_fut + return self.result_fut.result() mb = JMQtDMessageBox(parent) if mbtype == 'question': @@ -210,7 +214,7 @@ async def JMQtMessageBox(parent, msg, mbtype='info', title='', mb.setDefaultButton(QMessageBox.NoButton) mb.finished.connect(mb.on_finished) mb.open() - result = await result_fut + result = await mb.result() if finished_cb is not None: finished_cb(result) return result @@ -391,17 +395,55 @@ def make_password_dialog(self, msg): return vbox -class PasswordDialog(QDialog): +async def JMPasswordDialog(parent): - def __init__(self): - super().__init__() - self.initUI() + class PasswordDialog(QDialog): - def initUI(self): - self.setWindowTitle('Create a new passphrase') - msg = "Enter a new passphrase" - self.setLayout(make_password_dialog(self, msg)) - self.show() + def __init__(self, parent=None): + super().__init__(parent=parent) + self.result_fut = asyncio.get_event_loop().create_future() + self.initUI() + + + def initUI(self): + self.setWindowTitle('Create a new passphrase') + msg = "Enter a new passphrase" + self.setLayout(make_password_dialog(self, msg)) + self.show() + + @QtCore.Slot(QMessageBox.StandardButton) + def on_finished(self, result): + self.result_fut.set_result(result) + + async def result(self): + await self.result_fut + return self.result_fut.result() + + while True: + pd = PasswordDialog(parent=parent) + pd.finished.connect(pd.on_finished) + for child in pd.findChildren(QLineEdit): + child.clear() + pd.findChild(QLineEdit).setFocus() + pd.open() + pd_return = await pd.result() + if pd_return == QDialog.Rejected: + return None + elif pd.new_pw.text() != pd.conf_pw.text(): + await JMQtMessageBox(parent, + "Passphrases don't match.", + mbtype='warn', + title="Error") + continue + elif pd.new_pw.text() == "": + await JMQtMessageBox(parent, + "Passphrase must not be empty.", + mbtype='warn', + title="Error") + continue + break + textpassword = str(pd.new_pw.text()) + return textpassword class MyTreeWidget(QTreeWidget):