Update UI through async calls MainFrameRepaint and AddressBookRepaint instead of...
authorWladimir J. van der Laan <laanwj@gmail.com>
Sat, 24 Mar 2012 17:48:18 +0000 (18:48 +0100)
committerWladimir J. van der Laan <laanwj@gmail.com>
Wed, 4 Apr 2012 07:35:01 +0000 (09:35 +0200)
- Overall, this is better design
- This fixes problems with the address book UI not updating when the address book is changed through RPC
- Move Statusbar change detection responsibility to ClientModel

13 files changed:
src/noui.h
src/qt/addressbookpage.cpp
src/qt/addresstablemodel.cpp
src/qt/addresstablemodel.h
src/qt/bitcoin.cpp
src/qt/bitcoingui.cpp
src/qt/bitcoingui.h
src/qt/clientmodel.cpp
src/qt/clientmodel.h
src/qt/walletmodel.cpp
src/qt/walletmodel.h
src/qtui.h
src/wallet.cpp

index 458fc64..e4faa2e 100644 (file)
@@ -67,6 +67,10 @@ inline void MainFrameRepaint()
 {
 }
 
+inline void AddressBookRepaint()
+{
+}
+
 inline void InitMessage(const std::string &message)
 {
 }
index cb185be..8821283 100644 (file)
@@ -94,8 +94,6 @@ void AddressBookPage::setModel(AddressTableModel *model)
     this->model = model;
     if(!model)
         return;
-    // Refresh list from core
-    model->updateList();
 
     proxyModel = new QSortFilterProxyModel(this);
     proxyModel->setSourceModel(model);
index 8fd6d52..198a857 100644 (file)
@@ -231,7 +231,7 @@ QModelIndex AddressTableModel::index(int row, int column, const QModelIndex & pa
     }
 }
 
-void AddressTableModel::updateList()
+void AddressTableModel::update()
 {
     // Update address book model from Bitcoin core
     beginResetModel();
@@ -285,10 +285,9 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
     {
         return QString();
     }
-    // Add entry and update list
+    // Add entry
     CRITICAL_BLOCK(wallet->cs_wallet)
         wallet->SetAddressBookName(strAddress, strLabel);
-    updateList();
     return QString::fromStdString(strAddress);
 }
 
@@ -306,15 +305,9 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex & paren
     {
         wallet->DelAddressBookName(rec->address.toStdString());
     }
-    updateList();
     return true;
 }
 
-void AddressTableModel::update()
-{
-
-}
-
 /* Look up label for address in address book, if not found return empty string.
  */
 QString AddressTableModel::labelForAddress(const QString &address) const
index 0743300..7fd07cf 100644 (file)
@@ -56,10 +56,6 @@ public:
      */
     QString addRow(const QString &type, const QString &label, const QString &address);
 
-    /* Update address list from core. Invalidates any indices.
-     */
-    void updateList();
-
     /* Look up label for address in address book, if not found return empty string.
      */
     QString labelForAddress(const QString &address) const;
@@ -82,6 +78,8 @@ signals:
     void defaultAddressChanged(const QString &address);
 
 public slots:
+    /* Update address list from core. Invalidates any indices.
+     */
     void update();
 };
 
index 0f7c96e..f330fee 100644 (file)
@@ -33,8 +33,10 @@ Q_IMPORT_PLUGIN(qtaccessiblewidgets)
 #endif
 
 // Need a global reference for the notifications to find the GUI
-BitcoinGUI *guiref;
-QSplashScreen *splashref;
+static BitcoinGUI *guiref;
+static QSplashScreen *splashref;
+static WalletModel *walletmodel;
+static ClientModel *clientmodel;
 
 int MyMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y)
 {
@@ -98,8 +100,16 @@ void UIThreadCall(boost::function0<void> fn)
 
 void MainFrameRepaint()
 {
-    if(guiref)
-        QMetaObject::invokeMethod(guiref, "refreshStatusBar", Qt::QueuedConnection);
+    if(clientmodel)
+        QMetaObject::invokeMethod(clientmodel, "update", Qt::QueuedConnection);
+    if(walletmodel)
+        QMetaObject::invokeMethod(walletmodel, "update", Qt::QueuedConnection);
+}
+
+void AddressBookRepaint()
+{
+    if(walletmodel)
+        QMetaObject::invokeMethod(walletmodel, "updateAddressList", Qt::QueuedConnection);
 }
 
 void InitMessage(const std::string &message)
@@ -230,7 +240,9 @@ int main(int argc, char *argv[])
                     splash.finish(&window);
 
                 ClientModel clientModel(&optionsModel);
+                clientmodel = &clientModel;
                 WalletModel walletModel(pwalletMain, &optionsModel);
+                walletmodel = &walletModel;
 
                 guiref = &window;
                 window.setClientModel(&clientModel);
@@ -270,6 +282,8 @@ int main(int argc, char *argv[])
                 app.exec();
 
                 guiref = 0;
+                clientmodel = 0;
+                walletmodel = 0;
             }
             Shutdown(NULL);
         }
index cf4e43c..f2d1318 100644 (file)
@@ -538,19 +538,6 @@ void BitcoinGUI::setNumBlocks(int count)
     progressBar->setToolTip(tooltip);
 }
 
-void BitcoinGUI::refreshStatusBar()
-{
-    /* Might display multiple times in the case of multiple alerts
-    static QString prevStatusBar;
-    QString newStatusBar = clientModel->getStatusBarWarnings();
-    if (prevStatusBar != newStatusBar)
-    {
-        prevStatusBar = newStatusBar;
-        error(tr("Network Alert"), newStatusBar);
-    }*/
-    setNumBlocks(clientModel->getNumBlocks());
-}
-
 void BitcoinGUI::error(const QString &title, const QString &message)
 {
     // Report errors from network/worker thread
index dbc3264..2130bab 100644 (file)
@@ -113,8 +113,6 @@ public slots:
        @see WalletModel::EncryptionStatus
     */
     void setEncryptionStatus(int status);
-    /** Set the status bar text if there are any warnings (removes sync progress bar if applicable) */
-    void refreshStatusBar();
 
     /** Notify the user of an error in the network or transaction handling code. */
     void error(const QString &title, const QString &message);
index 5a0b4aa..8163da0 100644 (file)
@@ -6,19 +6,12 @@
 
 #include "headers.h"
 
-#include <QTimer>
 #include <QDateTime>
 
 ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
     QObject(parent), optionsModel(optionsModel),
     cachedNumConnections(0), cachedNumBlocks(0)
 {
-    // Until signal notifications is built into the bitcoin core,
-    //  simply update everything after polling using a timer.
-    QTimer *timer = new QTimer(this);
-    connect(timer, SIGNAL(timeout()), this, SLOT(update()));
-    timer->start(MODEL_UPDATE_DELAY);
-
     numBlocksAtStartup = -1;
 }
 
@@ -47,14 +40,23 @@ void ClientModel::update()
 {
     int newNumConnections = getNumConnections();
     int newNumBlocks = getNumBlocks();
+    QString newStatusBar = getStatusBarWarnings();
 
     if(cachedNumConnections != newNumConnections)
         emit numConnectionsChanged(newNumConnections);
-    if(cachedNumBlocks != newNumBlocks)
+    if(cachedNumBlocks != newNumBlocks || cachedStatusBar != newStatusBar)
+    {
+        // Simply emit a numBlocksChanged for now in case the status message changes,
+        // so that the view updates the status bar.
+        // TODO: It should send a notification.
+        //    (However, this might generate looped notifications and needs to be thought through and tested carefully)
+        //    error(tr("Network Alert"), newStatusBar);
         emit numBlocksChanged(newNumBlocks);
+    }
 
     cachedNumConnections = newNumConnections;
     cachedNumBlocks = newNumBlocks;
+    cachedStatusBar = newStatusBar;
 }
 
 bool ClientModel::isTestNet() const
index 5a12c4f..3dfbcec 100644 (file)
@@ -43,6 +43,7 @@ private:
 
     int cachedNumConnections;
     int cachedNumBlocks;
+    QString cachedStatusBar;
 
     int numBlocksAtStartup;
 
index 8344a65..0841854 100644 (file)
@@ -7,7 +7,6 @@
 #include "headers.h"
 #include "db.h" // for BackupWallet
 
-#include <QTimer>
 #include <QSet>
 
 WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) :
@@ -16,12 +15,6 @@ WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *p
     cachedBalance(0), cachedUnconfirmedBalance(0), cachedNumTransactions(0),
     cachedEncryptionStatus(Unencrypted)
 {
-    // Until signal notifications is built into the bitcoin core,
-    //  simply update everything after polling using a timer.
-    QTimer *timer = new QTimer(this);
-    connect(timer, SIGNAL(timeout()), this, SLOT(update()));
-    timer->start(MODEL_UPDATE_DELAY);
-
     addressTableModel = new AddressTableModel(wallet, this);
     transactionTableModel = new TransactionTableModel(wallet, this);
 }
@@ -69,6 +62,11 @@ void WalletModel::update()
     addressTableModel->update();
 }
 
+void WalletModel::updateAddressList()
+{
+    addressTableModel->update();
+}
+
 bool WalletModel::validateAddress(const QString &address)
 {
     CBitcoinAddress addressParsed(address.toStdString());
@@ -164,9 +162,6 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
         }
     }
 
-    // Update our model of the address table
-    addressTableModel->updateList();
-
     return SendCoinsReturn(OK, 0, hex);
 }
 
index e894842..6a85abd 100644 (file)
@@ -138,9 +138,8 @@ signals:
     void error(const QString &title, const QString &message);
 
 public slots:
-
-private slots:
     void update();
+    void updateAddressList();
 };
 
 
index 9791ba5..70952da 100644 (file)
@@ -44,6 +44,7 @@ extern void ThreadSafeHandleURL(const std::string& strURL);
 extern void CalledSetStatusBar(const std::string& strText, int nField);
 extern void UIThreadCall(boost::function0<void> fn);
 extern void MainFrameRepaint();
+extern void AddressBookRepaint();
 extern void InitMessage(const std::string &message);
 extern std::string _(const char* psz);
 
index 27ed722..3bdb4bb 100644 (file)
@@ -1279,6 +1279,7 @@ int CWallet::LoadWallet(bool& fFirstRunRet)
 bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& strName)
 {
     mapAddressBook[address] = strName;
+    AddressBookRepaint();
     if (!fFileBacked)
         return false;
     return CWalletDB(strWalletFile).WriteName(address.ToString(), strName);
@@ -1287,6 +1288,7 @@ bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& s
 bool CWallet::DelAddressBookName(const CBitcoinAddress& address)
 {
     mapAddressBook.erase(address);
+    AddressBookRepaint();
     if (!fFileBacked)
         return false;
     return CWalletDB(strWalletFile).EraseName(address.ToString());