From 1dd1679711e1041379a47d0946c19e66d705f53f Mon Sep 17 00:00:00 2001 From: Wukong Date: Fri, 16 Jul 2021 01:26:57 -0700 Subject: [PATCH] Show an OpenWallet dialog upon launching JoinMarketQT --- .gitignore | 2 +- jmqtui/jmqtui/__init__.py | 2 + jmqtui/jmqtui/open_wallet_dialog.py | 136 ++++++++++++++++ jmqtui/jmqtui/open_wallet_dialog.ui | 236 ++++++++++++++++++++++++++++ jmqtui/setup.py | 16 ++ requirements/gui.txt | 2 + scripts/joinmarket-qt.py | 38 +++++ test/lint/lint-python.sh | 5 +- 8 files changed, 435 insertions(+), 2 deletions(-) create mode 100644 jmqtui/jmqtui/__init__.py create mode 100644 jmqtui/jmqtui/open_wallet_dialog.py create mode 100644 jmqtui/jmqtui/open_wallet_dialog.ui create mode 100644 jmqtui/setup.py diff --git a/.gitignore b/.gitignore index 344f7c0..fcf935b 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,4 @@ scripts/jm-tx-history.txt scripts/snicker/joinmarket.cfg scripts/snicker/snicker-proposals.txt scripts/snicker/candidates.txt - +.qt_for_python/ diff --git a/jmqtui/jmqtui/__init__.py b/jmqtui/jmqtui/__init__.py new file mode 100644 index 0000000..ce1b436 --- /dev/null +++ b/jmqtui/jmqtui/__init__.py @@ -0,0 +1,2 @@ +from .open_wallet_dialog import ( + Ui_OpenWalletDialog) diff --git a/jmqtui/jmqtui/open_wallet_dialog.py b/jmqtui/jmqtui/open_wallet_dialog.py new file mode 100644 index 0000000..ebdbb8e --- /dev/null +++ b/jmqtui/jmqtui/open_wallet_dialog.py @@ -0,0 +1,136 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'open_wallet_dialog.ui' +## +## Created by: Qt User Interface Compiler version 5.14.2 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide2.QtCore import (QCoreApplication, QDate, QDateTime, QMetaObject, + QObject, QPoint, QRect, QSize, QTime, QUrl, Qt) +from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QCursor, QFont, + QFontDatabase, QIcon, QKeySequence, QLinearGradient, QPalette, QPainter, + QPixmap, QRadialGradient) +from PySide2.QtWidgets import * + + +class Ui_OpenWalletDialog(object): + def setupUi(self, OpenWalletDialog): + if not OpenWalletDialog.objectName(): + OpenWalletDialog.setObjectName(u"OpenWalletDialog") + OpenWalletDialog.resize(590, 301) + sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(OpenWalletDialog.sizePolicy().hasHeightForWidth()) + OpenWalletDialog.setSizePolicy(sizePolicy) + OpenWalletDialog.setFocusPolicy(Qt.TabFocus) + OpenWalletDialog.setModal(True) + self.verticalLayout = QVBoxLayout(OpenWalletDialog) + self.verticalLayout.setSpacing(10) + self.verticalLayout.setObjectName(u"verticalLayout") + self.verticalLayout.setContentsMargins(20, 20, 20, 20) + self.horizontalLayout = QHBoxLayout() + self.horizontalLayout.setSpacing(10) + self.horizontalLayout.setObjectName(u"horizontalLayout") + self.label = QLabel(OpenWalletDialog) + self.label.setObjectName(u"label") + sizePolicy1 = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) + sizePolicy1.setHorizontalStretch(0) + sizePolicy1.setVerticalStretch(0) + sizePolicy1.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth()) + self.label.setSizePolicy(sizePolicy1) + + self.horizontalLayout.addWidget(self.label) + + self.walletFileEdit = QLineEdit(OpenWalletDialog) + self.walletFileEdit.setObjectName(u"walletFileEdit") + sizePolicy2 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) + sizePolicy2.setHorizontalStretch(0) + sizePolicy2.setVerticalStretch(0) + sizePolicy2.setHeightForWidth(self.walletFileEdit.sizePolicy().hasHeightForWidth()) + self.walletFileEdit.setSizePolicy(sizePolicy2) + self.walletFileEdit.setMinimumSize(QSize(400, 0)) + + self.horizontalLayout.addWidget(self.walletFileEdit) + + self.chooseWalletButton = QPushButton(OpenWalletDialog) + self.chooseWalletButton.setObjectName(u"chooseWalletButton") + sizePolicy1.setHeightForWidth(self.chooseWalletButton.sizePolicy().hasHeightForWidth()) + self.chooseWalletButton.setSizePolicy(sizePolicy1) + + self.horizontalLayout.addWidget(self.chooseWalletButton) + + self.horizontalLayout.setStretch(1, 1) + + self.verticalLayout.addLayout(self.horizontalLayout) + + self.horizontalLayout_2 = QHBoxLayout() + self.horizontalLayout_2.setSpacing(10) + self.horizontalLayout_2.setObjectName(u"horizontalLayout_2") + self.label_2 = QLabel(OpenWalletDialog) + self.label_2.setObjectName(u"label_2") + sizePolicy1.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth()) + self.label_2.setSizePolicy(sizePolicy1) + + self.horizontalLayout_2.addWidget(self.label_2) + + self.passphraseEdit = QLineEdit(OpenWalletDialog) + self.passphraseEdit.setObjectName(u"passphraseEdit") + self.passphraseEdit.setMinimumSize(QSize(200, 0)) + self.passphraseEdit.setEchoMode(QLineEdit.Password) + + self.horizontalLayout_2.addWidget(self.passphraseEdit) + + self.horizontalSpacer = QSpacerItem(90, 20, QSizePolicy.Fixed, QSizePolicy.Minimum) + + self.horizontalLayout_2.addItem(self.horizontalSpacer) + + self.horizontalLayout_2.setStretch(1, 1) + + self.verticalLayout.addLayout(self.horizontalLayout_2) + + self.verticalSpacer = QSpacerItem(20, 150, QSizePolicy.Minimum, QSizePolicy.Minimum) + + self.verticalLayout.addItem(self.verticalSpacer) + + self.horizontalLayout_3 = QHBoxLayout() + self.horizontalLayout_3.setSpacing(10) + self.horizontalLayout_3.setObjectName(u"horizontalLayout_3") + self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) + + self.horizontalLayout_3.addItem(self.horizontalSpacer_2) + + self.buttonBox = QDialogButtonBox(OpenWalletDialog) + self.buttonBox.setObjectName(u"buttonBox") + self.buttonBox.setOrientation(Qt.Horizontal) + self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok) + + self.horizontalLayout_3.addWidget(self.buttonBox) + + self.horizontalLayout_3.setStretch(0, 1) + + self.verticalLayout.addLayout(self.horizontalLayout_3) + + self.verticalLayout.setStretch(2, 1) + QWidget.setTabOrder(self.passphraseEdit, self.chooseWalletButton) + QWidget.setTabOrder(self.chooseWalletButton, self.walletFileEdit) + + self.retranslateUi(OpenWalletDialog) + self.buttonBox.accepted.connect(OpenWalletDialog.accept) + self.buttonBox.rejected.connect(OpenWalletDialog.reject) + + QMetaObject.connectSlotsByName(OpenWalletDialog) + # setupUi + + def retranslateUi(self, OpenWalletDialog): + OpenWalletDialog.setWindowTitle(QCoreApplication.translate("OpenWalletDialog", u"JoinMarket - Open Wallet", None)) + self.label.setText(QCoreApplication.translate("OpenWalletDialog", u"Wallet:", None)) + self.walletFileEdit.setText(QCoreApplication.translate("OpenWalletDialog", u"wallet.jmdat", None)) + self.walletFileEdit.setPlaceholderText("") + self.chooseWalletButton.setText(QCoreApplication.translate("OpenWalletDialog", u"Choose...", None)) + self.label_2.setText(QCoreApplication.translate("OpenWalletDialog", u"Passphrase:", None)) + # retranslateUi + diff --git a/jmqtui/jmqtui/open_wallet_dialog.ui b/jmqtui/jmqtui/open_wallet_dialog.ui new file mode 100644 index 0000000..06335af --- /dev/null +++ b/jmqtui/jmqtui/open_wallet_dialog.ui @@ -0,0 +1,236 @@ + + + OpenWalletDialog + + + + 0 + 0 + 590 + 301 + + + + + 0 + 0 + + + + Qt::TabFocus + + + JoinMarket - Open Wallet + + + true + + + + 10 + + + 20 + + + 20 + + + 20 + + + 20 + + + + + 10 + + + + + + 0 + 0 + + + + Wallet: + + + + + + + + 0 + 0 + + + + + 400 + 0 + + + + wallet.jmdat + + + + + + + + + + + 0 + 0 + + + + Choose... + + + + + + + + + 10 + + + + + + 0 + 0 + + + + Passphrase: + + + + + + + + 200 + 0 + + + + QLineEdit::Password + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 90 + 20 + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 20 + 150 + + + + + + + + 10 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + passphraseEdit + chooseWalletButton + walletFileEdit + + + + + buttonBox + accepted() + OpenWalletDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + OpenWalletDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/jmqtui/setup.py b/jmqtui/setup.py new file mode 100644 index 0000000..a1f6fe1 --- /dev/null +++ b/jmqtui/setup.py @@ -0,0 +1,16 @@ +from setuptools import setup +import os + +setup(name='joinmarketui', + version='0.9.2dev', + description='Joinmarket client library for Bitcoin coinjoins', + url='http://github.com/Joinmarket-Org/joinmarket-clientserver/jmfg', + author='', + author_email='', + license='GPL', + packages=['jmqtui'], + install_requires=['PyQt5!=5.15.0,!=5.15.1,!=5.15.2,!=6.0'], + python_requires='>=3.6', + zip_safe=False) + +os.system('pyside2-uic jmqtui/open_wallet_dialog.ui -o jmqtui/open_wallet_dialog.py') diff --git a/requirements/gui.txt b/requirements/gui.txt index 1398c11..5b16452 100644 --- a/requirements/gui.txt +++ b/requirements/gui.txt @@ -5,3 +5,5 @@ PySide2!=5.15.0,!=5.15.1,!=5.15.2,!=6.0 PyQt5!=5.15.0,!=5.15.1,!=5.15.2,!=6.0 qrcode[pil] https://github.com/sunu/qt5reactor/archive/58410aaead2185e9917ae9cac9c50fe7b70e4a60.zip#egg=qt5reactor + +-e ./jmqtui \ No newline at end of file diff --git a/scripts/joinmarket-qt.py b/scripts/joinmarket-qt.py index 73751e2..8afb104 100755 --- a/scripts/joinmarket-qt.py +++ b/scripts/joinmarket-qt.py @@ -108,6 +108,25 @@ handler = QtHandler() handler.setFormatter(logging.Formatter("%(levelname)s:%(message)s")) log.addHandler(handler) + +from jmqtui import Ui_OpenWalletDialog +class JMOpenWalletDialog(QDialog, Ui_OpenWalletDialog): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.setupUi(self) + + self.chooseWalletButton.clicked.connect(self.chooseWalletFile) + + def chooseWalletFile(self): + wallets_path = os.path.join(jm_single().datadir, 'wallets') + (filename, _) = QFileDialog.getOpenFileName(self, + 'Choose Wallet File', + wallets_path, + options=QFileDialog.DontUseNativeDialog) + if filename: + self.walletFileEdit.setText(filename) + + class HelpLabel(QLabel): def __init__(self, text, help_text, wtitle): @@ -2354,6 +2373,25 @@ mainWindow.setWindowTitle(appWindowTitle + suffix) tabWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) mainWindow.setCentralWidget(tabWidget) tabWidget.currentChanged.connect(onTabChange) + mainWindow.show() reactor.runReturn() + +# Upon launching the app, allow the user to choose a wallet to open +openWalletDialog = JMOpenWalletDialog() +openWalletDialog.show() + +if openWalletDialog.exec_() == QDialog.Accepted: + wallet_path = openWalletDialog.walletFileEdit.text() + if not os.path.isabs(wallet_path): + wallet_path = os.path.join(jm_single().datadir, 'wallets', wallet_path) + + try: + mainWindow.loadWalletFromBlockchain(wallet_path, openWalletDialog.passphraseEdit.text()) + except Exception as e: + JMQtMessageBox(None, + str(e), + mbtype='warn', + title="Error") + sys.exit(app.exec_()) diff --git a/test/lint/lint-python.sh b/test/lint/lint-python.sh index 66e09f1..dbb9059 100755 --- a/test/lint/lint-python.sh +++ b/test/lint/lint-python.sh @@ -1,6 +1,9 @@ #!/usr/bin/env bash # Based on Bitcoin Core's test/lint/lint-python.sh +# The python files in jmqtui/jmqtui are auto generated. +EXCLUDE_PATTERNS="jmqtui/jmqtui/*.py" + if ! command -v flake8 > /dev/null; then echo "Skipping Python linting since flake8 is not installed." exit 0 @@ -10,7 +13,7 @@ elif flake8 --version | grep -q "Python 2"; then fi if [[ $# == 0 ]]; then - flake8 $(git ls-files "*.py") + flake8 $(git ls-files "*.py") --extend-exclude "${EXCLUDE_PATTERNS}" else flake8 "$@" fi