@@ -95,21 +95,23 @@ class TransactionTablePriv
9595 */
9696 QList<TransactionRecord> cachedWallet;
9797
98- bool fQueueNotifications = false ;
98+ /* * True when model finishes loading all wallet transactions on start */
99+ bool m_loaded = false ;
100+ /* * True when transactions are being notified, for instance when scanning */
101+ bool m_loading = false ;
99102 std::vector< TransactionNotification > vQueueNotifications;
100103
101104 void NotifyTransactionChanged (const uint256 &hash, ChangeType status);
102105 void NotifyAddressBookChanged (const CTxDestination &address, const std::string &label, bool isMine, const std::string &purpose, ChangeType status);
103- void ShowProgress ( const std::string &title, int nProgress );
106+ void DispatchNotifications ( );
104107
105108 /* Query entire wallet anew from core.
106109 */
107110 void refreshWallet (interfaces::Wallet& wallet)
108111 {
109- qDebug () << " TransactionTablePriv::refreshWallet" ;
110112 parent->beginResetModel ();
113+ assert (!m_loaded);
111114 try {
112- cachedWallet.clear ();
113115 for (const auto & wtx : wallet.getWalletTxs ()) {
114116 if (TransactionRecord::showTransaction ()) {
115117 cachedWallet.append (TransactionRecord::decomposeTransaction (wallet, wtx));
@@ -119,6 +121,8 @@ class TransactionTablePriv
119121 QMessageBox::critical (nullptr , PACKAGE_NAME, QString (" Failed to refresh wallet table: " ) + QString::fromStdString (e.what ()));
120122 }
121123 parent->endResetModel ();
124+ m_loaded = true ;
125+ DispatchNotifications ();
122126 }
123127
124128 /* Update our model of the wallet incrementally, to synchronize our model of the wallet
@@ -267,12 +271,12 @@ TransactionTableModel::TransactionTableModel(WalletModel *parent):
267271 fProcessingQueuedTransactions(false ),
268272 cachedChainLockHeight(-1 )
269273{
274+ subscribeToCoreSignals ();
275+
270276 columns << QString () << QString () << tr (" Date" ) << tr (" Type" ) << tr (" Address / Label" ) << BitcoinUnits::getAmountColumnTitle (walletModel->getOptionsModel ()->getDisplayUnit ());
271277 priv->refreshWallet (walletModel->wallet ());
272278
273279 connect (walletModel->getOptionsModel (), &OptionsModel::displayUnitChanged, this , &TransactionTableModel::updateDisplayUnit);
274-
275- subscribeToCoreSignals ();
276280}
277281
278282TransactionTableModel::~TransactionTableModel ()
@@ -793,7 +797,7 @@ void TransactionTablePriv::NotifyTransactionChanged(const uint256 &hash, ChangeT
793797
794798 TransactionNotification notification (hash, status, showTransaction);
795799
796- if (fQueueNotifications )
800+ if (!m_loaded || m_loading )
797801 {
798802 vQueueNotifications.push_back (notification);
799803 return ;
@@ -812,43 +816,41 @@ void TransactionTablePriv::NotifyAddressBookChanged(const CTxDestination &addres
812816 assert (invoked);
813817}
814818
815- void TransactionTablePriv::ShowProgress ( const std::string &title, int nProgress )
819+ void TransactionTablePriv::DispatchNotifications ( )
816820{
817- if (nProgress == 0 )
818- fQueueNotifications = true ;
821+ if (!m_loaded || m_loading) return ;
819822
820- if (nProgress == 100 )
821- {
822- fQueueNotifications = false ;
823- if (vQueueNotifications.size () < 10000 ) {
824- if (vQueueNotifications.size () > 10 ) { // prevent balloon spam, show maximum 10 balloons
825- bool invoked = QMetaObject::invokeMethod (parent, " setProcessingQueuedTransactions" , Qt::QueuedConnection, Q_ARG (bool , true ));
823+ if (vQueueNotifications.size () < 10000 ) {
824+ if (vQueueNotifications.size () > 10 ) { // prevent balloon spam, show maximum 10 balloons
825+ bool invoked = QMetaObject::invokeMethod (parent, " setProcessingQueuedTransactions" , Qt::QueuedConnection, Q_ARG (bool , true ));
826+ assert (invoked);
827+ }
828+ for (unsigned int i = 0 ; i < vQueueNotifications.size (); ++i)
829+ {
830+ if (vQueueNotifications.size () - i <= 10 ) {
831+ bool invoked = QMetaObject::invokeMethod (parent, " setProcessingQueuedTransactions" , Qt::QueuedConnection, Q_ARG (bool , false ));
826832 assert (invoked);
827833 }
828- for (unsigned int i = 0 ; i < vQueueNotifications.size (); ++i)
829- {
830- if (vQueueNotifications.size () - i <= 10 ) {
831- bool invoked = QMetaObject::invokeMethod (parent, " setProcessingQueuedTransactions" , Qt::QueuedConnection, Q_ARG (bool , false ));
832- assert (invoked);
833- }
834834
835- vQueueNotifications[i].invoke (parent);
836- }
837- } else {
838- // it's much faster to just refresh the whole thing instead
839- bool invoked = QMetaObject::invokeMethod (parent, " refreshWallet" , Qt::QueuedConnection);
840- assert (invoked);
835+ vQueueNotifications[i].invoke (parent);
841836 }
842- vQueueNotifications.clear ();
837+ } else {
838+ // it's much faster to just refresh the whole thing instead
839+ bool invoked = QMetaObject::invokeMethod (parent, " refreshWallet" , Qt::QueuedConnection);
840+ assert (invoked);
843841 }
842+ vQueueNotifications.clear ();
844843}
845844
846845void TransactionTableModel::subscribeToCoreSignals ()
847846{
848847 // Connect signals to wallet
849848 m_handler_transaction_changed = walletModel->wallet ().handleTransactionChanged (std::bind (&TransactionTablePriv::NotifyTransactionChanged, priv, std::placeholders::_1, std::placeholders::_2));
850849 m_handler_address_book_changed = walletModel->wallet ().handleAddressBookChanged (std::bind (&TransactionTablePriv::NotifyAddressBookChanged, priv, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
851- m_handler_show_progress = walletModel->wallet ().handleShowProgress (std::bind (&TransactionTablePriv::ShowProgress, priv, std::placeholders::_1, std::placeholders::_2));
850+ m_handler_show_progress = walletModel->wallet ().handleShowProgress ([this ](const std::string&, int progress) {
851+ priv->m_loading = progress < 100 ;
852+ priv->DispatchNotifications ();
853+ });
852854}
853855
854856void TransactionTableModel::unsubscribeFromCoreSignals ()
0 commit comments