Update UI through async calls MainFrameRepaint and AddressBookRepaint instead of a timer.

- 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
This commit is contained in:
Wladimir J. van der Laan 2012-03-24 18:48:18 +01:00
parent 7e7bcce2d9
commit 98e6175874
13 changed files with 46 additions and 54 deletions

View file

@ -67,6 +67,10 @@ inline void MainFrameRepaint()
{
}
inline void AddressBookRepaint()
{
}
inline void InitMessage(const std::string &message)
{
}

View 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);

View 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

View 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();
};

View 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);
}

View 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

View 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);

View 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

View file

@ -43,6 +43,7 @@ private:
int cachedNumConnections;
int cachedNumBlocks;
QString cachedStatusBar;
int numBlocksAtStartup;

View 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);
}

View file

@ -138,9 +138,8 @@ signals:
void error(const QString &title, const QString &message);
public slots:
private slots:
void update();
void updateAddressList();
};

View 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);

View 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());