diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index ba076a4aea0bc..9dc74a7ed7e5f 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -23,6 +23,7 @@ #include #include #include +#include // Amount column is right-aligned it contains numbers @@ -74,14 +75,18 @@ class TransactionTablePriv void refreshWallet(interfaces::Wallet& wallet) { qDebug() << "TransactionTablePriv::refreshWallet"; - cachedWallet.clear(); - { + parent->beginResetModel(); + try { + cachedWallet.clear(); for (const auto& wtx : wallet.getWalletTxs()) { if (TransactionRecord::showTransaction()) { cachedWallet.append(TransactionRecord::decomposeTransaction(wallet, wtx)); } } + } catch(const std::exception& e) { + QMessageBox::critical(nullptr, PACKAGE_NAME, QString("Failed to refresh wallet table: ") + QString::fromStdString(e.what())); } + parent->endResetModel(); } /* Update our model of the wallet incrementally, to synchronize our model of the wallet @@ -244,6 +249,11 @@ TransactionTableModel::~TransactionTableModel() delete priv; } +void TransactionTableModel::refreshWallet() +{ + priv->refreshWallet(walletModel->wallet()); +} + /** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */ void TransactionTableModel::updateAmountColumnTitle() { @@ -803,18 +813,24 @@ static void ShowProgress(TransactionTableModel *ttm, const std::string &title, i if (nProgress == 100) { fQueueNotifications = false; - if (vQueueNotifications.size() > 10) { // prevent balloon spam, show maximum 10 balloons - bool invoked = QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true)); - assert(invoked); - } - for (unsigned int i = 0; i < vQueueNotifications.size(); ++i) - { - if (vQueueNotifications.size() - i <= 10) { - bool invoked = QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, false)); + if (vQueueNotifications.size() < 10000) { + if (vQueueNotifications.size() > 10) { // prevent balloon spam, show maximum 10 balloons + bool invoked = QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true)); assert(invoked); } + for (unsigned int i = 0; i < vQueueNotifications.size(); ++i) + { + if (vQueueNotifications.size() - i <= 10) { + bool invoked = QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, false)); + assert(invoked); + } - vQueueNotifications[i].invoke(ttm); + vQueueNotifications[i].invoke(ttm); + } + } else { + // it's much faster to just refresh the whole thing instead + bool invoked = QMetaObject::invokeMethod(ttm, "refreshWallet", Qt::QueuedConnection); + assert(invoked); } std::vector().swap(vQueueNotifications); // clear } diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 5d1f6aadc1e74..16e85b935ea06 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -113,6 +113,8 @@ class TransactionTableModel : public QAbstractTableModel QVariant txAddressDecoration(const TransactionRecord *wtx) const; public Q_SLOTS: + /* Refresh the whole wallet, helpful for huge notification queues */ + void refreshWallet(); /* New transaction, or transaction changed status */ void updateTransaction(const QString &hash, int status, bool showTransaction); void updateAddressBook(const QString &address, const QString &label,