Skip to content

Commit e7a3f69

Browse files
w0xltshaavanfurszy
committed
gui: Add Wallet Restore in the GUI
Co-authored-by: Shashwat Vangani <[email protected]> Co-authored-by: furszy <[email protected]>
1 parent b11ab25 commit e7a3f69

File tree

4 files changed

+96
-1
lines changed

4 files changed

+96
-1
lines changed

src/qt/bitcoingui.cpp

+32-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include <QCursor>
4848
#include <QDateTime>
4949
#include <QDragEnterEvent>
50+
#include <QInputDialog>
5051
#include <QKeySequence>
5152
#include <QListWidget>
5253
#include <QMenu>
@@ -348,6 +349,12 @@ void BitcoinGUI::createActions()
348349
m_create_wallet_action->setEnabled(false);
349350
m_create_wallet_action->setStatusTip(tr("Create a new wallet"));
350351

352+
//: Name of the menu item that restores wallet from a backup file.
353+
m_restore_wallet_action = new QAction(tr("Restore Wallet…"), this);
354+
m_restore_wallet_action->setEnabled(false);
355+
//: Status tip for Restore Wallet menu item
356+
m_restore_wallet_action->setStatusTip(tr("Restore a wallet from a backup file"));
357+
351358
m_close_all_wallets_action = new QAction(tr("Close All Wallets…"), this);
352359
m_close_all_wallets_action->setStatusTip(tr("Close all wallets"));
353360

@@ -412,6 +419,27 @@ void BitcoinGUI::createActions()
412419
action->setEnabled(false);
413420
}
414421
});
422+
connect(m_restore_wallet_action, &QAction::triggered, [this] {
423+
//: Name of the wallet data file format.
424+
QString name_data_file = tr("Wallet Data");
425+
426+
//: The title for Restore Wallet File Windows
427+
QString title_windows = tr("Load Wallet Backup");
428+
429+
QString backup_file = GUIUtil::getOpenFileName(this, title_windows, QString(), name_data_file + QLatin1String(" (*.dat)"), nullptr);
430+
if (backup_file.isEmpty()) return;
431+
432+
bool wallet_name_ok;
433+
//: Title of the Restore Wallet input dialog (where the wallet name is entered)
434+
QString wallet_name = QInputDialog::getText(this, tr("Restore Name"), tr("Wallet Name:"), QLineEdit::Normal, "", &wallet_name_ok);
435+
if (!wallet_name_ok || wallet_name.isEmpty()) return;
436+
437+
auto activity = new RestoreWalletActivity(m_wallet_controller, this);
438+
connect(activity, &RestoreWalletActivity::restored, this, &BitcoinGUI::setCurrentWallet, Qt::QueuedConnection);
439+
440+
auto backup_file_path = fs::PathFromString(backup_file.toStdString());
441+
activity->restore(backup_file_path, wallet_name.toStdString());
442+
});
415443
connect(m_close_wallet_action, &QAction::triggered, [this] {
416444
m_wallet_controller->closeWallet(walletFrame->currentWalletModel(), this);
417445
});
@@ -450,8 +478,10 @@ void BitcoinGUI::createMenuBar()
450478
file->addAction(m_close_wallet_action);
451479
file->addAction(m_close_all_wallets_action);
452480
file->addSeparator();
453-
file->addAction(openAction);
454481
file->addAction(backupWalletAction);
482+
file->addAction(m_restore_wallet_action);
483+
file->addSeparator();
484+
file->addAction(openAction);
455485
file->addAction(signMessageAction);
456486
file->addAction(verifyMessageAction);
457487
file->addAction(m_load_psbt_action);
@@ -642,6 +672,7 @@ void BitcoinGUI::setWalletController(WalletController* wallet_controller)
642672
m_create_wallet_action->setEnabled(true);
643673
m_open_wallet_action->setEnabled(true);
644674
m_open_wallet_action->setMenu(m_open_wallet_menu);
675+
m_restore_wallet_action->setEnabled(true);
645676

646677
GUIUtil::ExceptionSafeConnect(wallet_controller, &WalletController::walletAdded, this, &BitcoinGUI::addWallet);
647678
connect(wallet_controller, &WalletController::walletRemoved, this, &BitcoinGUI::removeWallet);

src/qt/bitcoingui.h

+1
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ class BitcoinGUI : public QMainWindow
157157
QAction* m_create_wallet_action{nullptr};
158158
QAction* m_open_wallet_action{nullptr};
159159
QMenu* m_open_wallet_menu{nullptr};
160+
QAction* m_restore_wallet_action{nullptr};
160161
QAction* m_close_wallet_action{nullptr};
161162
QAction* m_close_all_wallets_action{nullptr};
162163
QAction* m_wallet_selector_label_action = nullptr;

src/qt/walletcontroller.cpp

+43
Original file line numberDiff line numberDiff line change
@@ -373,3 +373,46 @@ void LoadWalletsActivity::load()
373373
QTimer::singleShot(0, this, [this] { Q_EMIT finished(); });
374374
});
375375
}
376+
377+
RestoreWalletActivity::RestoreWalletActivity(WalletController* wallet_controller, QWidget* parent_widget)
378+
: WalletControllerActivity(wallet_controller, parent_widget)
379+
{
380+
}
381+
382+
void RestoreWalletActivity::restore(const fs::path& backup_file, const std::string& wallet_name)
383+
{
384+
QString name = QString::fromStdString(wallet_name);
385+
386+
showProgressDialog(
387+
//: Title of progress window which is displayed when wallets are being restored.
388+
tr("Restore Wallet"),
389+
/*: Descriptive text of the restore wallets progress window which indicates to
390+
the user that wallets are currently being restored.*/
391+
tr("Restoring Wallet <b>%1</b>…").arg(name.toHtmlEscaped()));
392+
393+
QTimer::singleShot(0, worker(), [this, backup_file, wallet_name] {
394+
std::unique_ptr<interfaces::Wallet> wallet = node().walletLoader().restoreWallet(backup_file, wallet_name, m_error_message, m_warning_message);
395+
396+
if (wallet) m_wallet_model = m_wallet_controller->getOrCreateWallet(std::move(wallet));
397+
398+
QTimer::singleShot(0, this, &RestoreWalletActivity::finish);
399+
});
400+
}
401+
402+
void RestoreWalletActivity::finish()
403+
{
404+
if (!m_error_message.empty()) {
405+
//: Title of message box which is displayed when the wallet could not be restored.
406+
QMessageBox::critical(m_parent_widget, tr("Restore wallet failed"), QString::fromStdString(m_error_message.translated));
407+
} else if (!m_warning_message.empty()) {
408+
//: Title of message box which is displayed when the wallet is restored with some warning.
409+
QMessageBox::warning(m_parent_widget, tr("Restore wallet warning"), QString::fromStdString(Join(m_warning_message, Untranslated("\n")).translated));
410+
} else {
411+
//: Title of message box which is displayed when the wallet is successfully restored.
412+
QMessageBox::information(m_parent_widget, tr("Restore wallet message"), QString::fromStdString(Untranslated("Wallet restored successfully \n").translated));
413+
}
414+
415+
if (m_wallet_model) Q_EMIT restored(m_wallet_model);
416+
417+
Q_EMIT finished();
418+
}

src/qt/walletcontroller.h

+20
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ class Node;
3333
class Wallet;
3434
} // namespace interfaces
3535

36+
namespace fs {
37+
class path;
38+
}
39+
3640
class AskPassphraseDialog;
3741
class CreateWalletActivity;
3842
class CreateWalletDialog;
@@ -155,4 +159,20 @@ class LoadWalletsActivity : public WalletControllerActivity
155159
void load();
156160
};
157161

162+
class RestoreWalletActivity : public WalletControllerActivity
163+
{
164+
Q_OBJECT
165+
166+
public:
167+
RestoreWalletActivity(WalletController* wallet_controller, QWidget* parent_widget);
168+
169+
void restore(const fs::path& backup_file, const std::string& wallet_name);
170+
171+
Q_SIGNALS:
172+
void restored(WalletModel* wallet_model);
173+
174+
private:
175+
void finish();
176+
};
177+
158178
#endif // BITCOIN_QT_WALLETCONTROLLER_H

0 commit comments

Comments
 (0)