From d3234bb91564ee8327b111e0acf2a83153929c25 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Thu, 18 Aug 2016 21:55:34 +0300 Subject: [PATCH] WalletManager::openWalletAsync in progress --- main.qml | 81 ++++++++++++++++++++----------- src/libwalletqt/WalletManager.cpp | 34 ++++++++++++- src/libwalletqt/WalletManager.h | 33 +++++++++++-- 3 files changed, 114 insertions(+), 34 deletions(-) diff --git a/main.qml b/main.qml index faeaf123..bf30266d 100644 --- a/main.qml +++ b/main.qml @@ -49,9 +49,10 @@ ApplicationWindow { property bool rightPanelExpanded: false property bool osx: false property alias persistentSettings : persistentSettings - property var wallet; + property var currentWallet; property var transaction; property alias password : passwordDialog.password + property bool walletOpeningWithPassword: false @@ -145,26 +146,9 @@ ApplicationWindow { var wallet_path = walletPath(); console.log("opening wallet at: ", wallet_path); - wallet = walletManager.openWallet(wallet_path, appWindow.password, + walletManager.openWalletAsync(wallet_path, appWindow.password, persistentSettings.testnet); - if (wallet.status !== Wallet.Status_Ok) { - console.error("Error opening wallet with empty password: ", wallet.errorString); - console.log("closing wallet...") - walletManager.closeWallet(wallet) - console.log("wallet closed") - // try to open wallet with password; - passwordDialog.open(); - return; - } - - console.log("Wallet opened successfully: ", wallet.errorString); } - // subscribing for wallet updates - wallet.updated.connect(onWalletUpdate); - wallet.refreshed.connect(onWalletRefresh); - - console.log("initializing with daemon address..") - wallet.initAsync(persistentSettings.daemon_address, 0); } @@ -174,6 +158,50 @@ ApplicationWindow { return wallet_path; } + function onWalletOpened(wallet) { + console.log(">>> wallet opened: " + wallet) + + if (wallet.status !== Wallet.Status_Ok) { + if (!appWindow.walletOpeningWithPassword) { + console.error("Error opening wallet with empty password: ", wallet.errorString); + console.log("closing wallet async...") + walletManager.closeWalletAsync(wallet) + // try to open wallet with password; + appWindow.walletOpeningWithPassword = true + passwordDialog.open(); + } else { + // opening with password but password doesn't match + console.error("Error opening wallet with password: ", wallet.errorString); + informationPopup.title = qsTr("Error") + translationManager.emptyString; + informationPopup.text = qsTr("Couldn't open wallet: ") + wallet.errorString; + informationPopup.icon = StandardIcon.Critical + informationPopup.open() + informationPopup.onCloseCallback = appWindow.initialize + walletManager.closeWallet(wallet); + } + return; + } + + // wallet opened successfully, subscribing for wallet updates + currentWallet = wallet +// wallet.updated.connect(appWindow.onWalletUpdate) +// wallet.refreshed.connect(appWindow.onWalletRefresh) + // currentWallet.refreshed.connect(onWalletRefresh) + var connectResult = currentWallet.refreshed.connect(function() { + console.log("QML: refreshed") + }) + + console.log("connected to refreshed: " + connectResult); + currentWallet.updated.connect(onWalletUpdate) + console.log("initializing with daemon address: ", persistentSettings.daemon_address) + currentWallet.initAsync(persistentSettings.daemon_address, 0); + + } + + + function onWalletClosed(walletAddress) { + console.log(">>> wallet closed: " + walletAddress) + } function onWalletUpdate() { console.log(">>> wallet updated") @@ -283,6 +311,9 @@ ApplicationWindow { x = (Screen.width - width) / 2 y = (Screen.height - height) / 2 // + walletManager.walletOpened.connect(onWalletOpened); + walletManager.walletClosed.connect(onWalletClosed); + rootItem.state = walletsFound() ? "normal" : "wizard"; if (rootItem.state === "normal") { initialize(persistentSettings) @@ -342,16 +373,8 @@ ApplicationWindow { var wallet_path = walletPath(); console.log("opening wallet with password: ", wallet_path); - wallet = walletManager.openWallet(wallet_path, password, persistentSettings.testnet); - if (wallet.status !== Wallet.Status_Ok) { - console.error("Error opening wallet with password: ", wallet.errorString); - informationPopup.title = qsTr("Error") + translationManager.emptyString; - informationPopup.text = qsTr("Couldn't open wallet: ") + wallet.errorString; - informationPopup.icon = StandardIcon.Critical - informationPopup.open() - informationPopup.onCloseCallback = appWindow.initialize - walletManager.closeWallet(wallet); - } + walletManager.openWalletAsync(wallet_path, password, persistentSettings.testnet); + } onRejected: { appWindow.enableUI(false) diff --git a/src/libwalletqt/WalletManager.cpp b/src/libwalletqt/WalletManager.cpp index a7742bca..50a61553 100644 --- a/src/libwalletqt/WalletManager.cpp +++ b/src/libwalletqt/WalletManager.cpp @@ -6,6 +6,7 @@ #include #include #include +#include @@ -42,6 +43,20 @@ Wallet *WalletManager::openWallet(const QString &path, const QString &password, return wallet; } +void WalletManager::openWalletAsync(const QString &path, const QString &password, bool testnet) +{ + QFuture future = QtConcurrent::run(this, &WalletManager::openWallet, + path, password, testnet); + QFutureWatcher * watcher = new QFutureWatcher(); + watcher->setFuture(future); + connect(watcher, &QFutureWatcher::finished, + this, [this, watcher]() { + QFuture future = watcher->future(); + watcher->deleteLater(); + emit walletOpened(future.result()); + }); +} + Wallet *WalletManager::recoveryWallet(const QString &path, const QString &memo, bool testnet) { @@ -51,9 +66,26 @@ Wallet *WalletManager::recoveryWallet(const QString &path, const QString &memo, } -void WalletManager::closeWallet(Wallet *wallet) +QString WalletManager::closeWallet(Wallet *wallet) { + QString result = wallet->address(); delete wallet; + return result; +} + +void WalletManager::closeWalletAsync(Wallet *wallet) +{ + QFuture future = QtConcurrent::run(this, &WalletManager::closeWallet, + wallet); + QFutureWatcher * watcher = new QFutureWatcher(); + watcher->setFuture(future); + + connect(watcher, &QFutureWatcher::finished, + this, [this, watcher]() { + QFuture future = watcher->future(); + watcher->deleteLater(); + emit future.result(); + }); } bool WalletManager::walletExists(const QString &path) const diff --git a/src/libwalletqt/WalletManager.h b/src/libwalletqt/WalletManager.h index 29df9048..27224b5f 100644 --- a/src/libwalletqt/WalletManager.h +++ b/src/libwalletqt/WalletManager.h @@ -16,15 +16,38 @@ public: // wizard: createWallet path; Q_INVOKABLE Wallet * createWallet(const QString &path, const QString &password, const QString &language, bool testnet = false); - // just for future use + + /*! + * \brief openWallet - opens wallet by given path + * \param path - wallet filename + * \param password - wallet password. Empty string in wallet isn't password protected + * \param testnet - determines if we running testnet + * \return wallet object pointer + */ Q_INVOKABLE Wallet * openWallet(const QString &path, const QString &password, bool testnet = false); + /*! + * \brief openWalletAsync - asynchronous version of "openWallet". Returns immediately. "walletOpened" signal + * emitted when wallet opened; + */ + Q_INVOKABLE void openWalletAsync(const QString &path, const QString &password, bool testnet = false); + // wizard: recoveryWallet path; hint: internally it recorvers wallet and set password = "" Q_INVOKABLE Wallet * recoveryWallet(const QString &path, const QString &memo, bool testnet = false); - //! utils: close wallet to free memory - Q_INVOKABLE void closeWallet(Wallet * wallet); + /*! + * \brief closeWallet - closes wallet and frees memory + * \param wallet + * \return wallet address + */ + Q_INVOKABLE QString closeWallet(Wallet * wallet); + + /*! + * \brief closeWalletAsync - asynchronous version of "closeWallet" + * \param wallet - wallet pointer; + */ + Q_INVOKABLE void closeWalletAsync(Wallet * wallet); //! checks is given filename is a wallet; Q_INVOKABLE bool walletExists(const QString &path) const; @@ -50,8 +73,10 @@ public: signals: -public slots: + void walletOpened(Wallet * wallet); + void walletClosed(const QString &walletAddress); +public slots: private: explicit WalletManager(QObject *parent = 0);