diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2012-04-04 05:03:07 -0700 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2012-04-04 05:03:07 -0700 |
commit | b0a7e05a45a925d78efd00ecca6dce9b7a9530f9 (patch) | |
tree | 13d0f8f8650b545b767c3e6b8de3e2effa385f2f /src/qt | |
parent | cadae3588c5553b8c7ef76c14d07041f639fb926 (diff) | |
parent | 5cccb13dad589b66957772ee36b3be0ef06ed0dc (diff) |
Merge pull request #1019 from laanwj/2012_03_uirefactor
Streamline UI ↔ Core interface
Diffstat (limited to 'src/qt')
-rw-r--r-- | src/qt/addressbookpage.cpp | 2 | ||||
-rw-r--r-- | src/qt/addresstablemodel.cpp | 11 | ||||
-rw-r--r-- | src/qt/addresstablemodel.h | 6 | ||||
-rw-r--r-- | src/qt/bitcoin.cpp | 96 | ||||
-rw-r--r-- | src/qt/bitcoingui.cpp | 26 | ||||
-rw-r--r-- | src/qt/bitcoingui.h | 4 | ||||
-rw-r--r-- | src/qt/clientmodel.cpp | 18 | ||||
-rw-r--r-- | src/qt/clientmodel.h | 3 | ||||
-rw-r--r-- | src/qt/guiutil.cpp | 12 | ||||
-rw-r--r-- | src/qt/guiutil.h | 8 | ||||
-rw-r--r-- | src/qt/transactiondesc.cpp | 2 | ||||
-rw-r--r-- | src/qt/walletmodel.cpp | 17 | ||||
-rw-r--r-- | src/qt/walletmodel.h | 7 |
13 files changed, 105 insertions, 107 deletions
diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index cb185beae5..88212835de 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -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); diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 8fd6d52b7e..198a857b2d 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -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 diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h index 0743300137..7fd07cfb81 100644 --- a/src/qt/addresstablemodel.h +++ b/src/qt/addresstablemodel.h @@ -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(); }; diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 6ee7fed5c9..394e4a7661 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -5,6 +5,7 @@ #include "clientmodel.h" #include "walletmodel.h" #include "optionsmodel.h" +#include "guiutil.h" #include "headers.h" #include "init.h" @@ -12,7 +13,6 @@ #include <QApplication> #include <QMessageBox> -#include <QThread> #include <QTextCodec> #include <QLocale> #include <QTranslator> @@ -21,27 +21,35 @@ #include <boost/interprocess/ipc/message_queue.hpp> -// Need a global reference for the notifications to find the GUI -BitcoinGUI *guiref; -QSplashScreen *splashref; +#if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED) +#define _BITCOIN_QT_PLUGINS_INCLUDED +#define __INSURE__ +#include <QtPlugin> +Q_IMPORT_PLUGIN(qcncodecs) +Q_IMPORT_PLUGIN(qjpcodecs) +Q_IMPORT_PLUGIN(qtwcodecs) +Q_IMPORT_PLUGIN(qkrcodecs) +Q_IMPORT_PLUGIN(qtaccessiblewidgets) +#endif -int MyMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y) -{ - // Message from AppInit2(), always in main thread before main window is constructed - QMessageBox::critical(0, QString::fromStdString(caption), - QString::fromStdString(message), - QMessageBox::Ok, QMessageBox::Ok); - return 4; -} +// Need a global reference for the notifications to find the GUI +static BitcoinGUI *guiref; +static QSplashScreen *splashref; +static WalletModel *walletmodel; +static ClientModel *clientmodel; -int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y) +int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style) { // Message from network thread if(guiref) { - QMetaObject::invokeMethod(guiref, "error", Qt::QueuedConnection, + bool modal = (style & wxMODAL); + // in case of modal message, use blocking connection to wait for user to click OK + QMetaObject::invokeMethod(guiref, "error", + modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection, Q_ARG(QString, QString::fromStdString(caption)), - Q_ARG(QString, QString::fromStdString(message))); + Q_ARG(QString, QString::fromStdString(message)), + Q_ARG(bool, modal)); } else { @@ -51,7 +59,7 @@ int ThreadSafeMessageBox(const std::string& message, const std::string& caption, return 4; } -bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindow* parent) +bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption) { if(!guiref) return false; @@ -59,15 +67,7 @@ bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindo return true; bool payFee = false; - // Call slot on GUI thread. - // If called from another thread, use a blocking QueuedConnection. - Qt::ConnectionType connectionType = Qt::DirectConnection; - if(QThread::currentThread() != QCoreApplication::instance()->thread()) - { - connectionType = Qt::BlockingQueuedConnection; - } - - QMetaObject::invokeMethod(guiref, "askFee", connectionType, + QMetaObject::invokeMethod(guiref, "askFee", GUIUtil::blockingGUIThreadConnection(), Q_ARG(qint64, nFeeRequired), Q_ARG(bool*, &payFee)); @@ -79,31 +79,22 @@ void ThreadSafeHandleURL(const std::string& strURL) if(!guiref) return; - // Call slot on GUI thread. - // If called from another thread, use a blocking QueuedConnection. - Qt::ConnectionType connectionType = Qt::DirectConnection; - if(QThread::currentThread() != QCoreApplication::instance()->thread()) - { - connectionType = Qt::BlockingQueuedConnection; - } - QMetaObject::invokeMethod(guiref, "handleURL", connectionType, + QMetaObject::invokeMethod(guiref, "handleURL", GUIUtil::blockingGUIThreadConnection(), Q_ARG(QString, QString::fromStdString(strURL))); } -void CalledSetStatusBar(const std::string& strText, int nField) -{ - // Only used for built-in mining, which is disabled, simple ignore -} - -void UIThreadCall(boost::function0<void> fn) +void MainFrameRepaint() { - // Only used for built-in mining, which is disabled, simple ignore + if(clientmodel) + QMetaObject::invokeMethod(clientmodel, "update", Qt::QueuedConnection); + if(walletmodel) + QMetaObject::invokeMethod(walletmodel, "update", Qt::QueuedConnection); } -void MainFrameRepaint() +void AddressBookRepaint() { - if(guiref) - QMetaObject::invokeMethod(guiref, "refreshStatusBar", Qt::QueuedConnection); + if(walletmodel) + QMetaObject::invokeMethod(walletmodel, "updateAddressList", Qt::QueuedConnection); } void InitMessage(const std::string &message) @@ -115,6 +106,11 @@ void InitMessage(const std::string &message) } } +void QueueShutdown() +{ + QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection); +} + /* Translate string to current locale using Qt. */ @@ -221,22 +217,24 @@ int main(int argc, char *argv[]) try { + BitcoinGUI window; + guiref = &window; if(AppInit2(argc, argv)) { { - // Put this in a block, so that BitcoinGUI is cleaned up properly before - // calling Shutdown() in case of exceptions. + // Put this in a block, so that the Model objects are cleaned up before + // calling Shutdown(). optionsModel.Upgrade(); // Must be done after AppInit2 - BitcoinGUI window; if (splashref) splash.finish(&window); ClientModel clientModel(&optionsModel); + clientmodel = &clientModel; WalletModel walletModel(pwalletMain, &optionsModel); + walletmodel = &walletModel; - guiref = &window; window.setClientModel(&clientModel); window.setWalletModel(&walletModel); @@ -273,7 +271,11 @@ int main(int argc, char *argv[]) #endif app.exec(); + window.setClientModel(0); + window.setWalletModel(0); guiref = 0; + clientmodel = 0; + walletmodel = 0; } Shutdown(NULL); } diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 00bb5bd158..a60b585225 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -339,7 +339,7 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int))); // Report errors from network/worker thread - connect(clientModel, SIGNAL(error(QString,QString)), this, SLOT(error(QString,QString))); + connect(clientModel, SIGNAL(error(QString,QString, bool)), this, SLOT(error(QString,QString,bool))); } } @@ -349,7 +349,7 @@ void BitcoinGUI::setWalletModel(WalletModel *walletModel) if(walletModel) { // Report errors from wallet thread - connect(walletModel, SIGNAL(error(QString,QString)), this, SLOT(error(QString,QString))); + connect(walletModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool))); // Put transaction list in tabs transactionView->setModel(walletModel); @@ -552,23 +552,15 @@ 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) +void BitcoinGUI::error(const QString &title, const QString &message, bool modal) { // Report errors from network/worker thread - notificator->notify(Notificator::Critical, title, message); + if(modal) + { + QMessageBox::critical(this, title, message, QMessageBox::Ok, QMessageBox::Ok); + } else { + notificator->notify(Notificator::Critical, title, message); + } } void BitcoinGUI::changeEvent(QEvent *e) diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index dbc32640b8..c684d7cc3a 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -113,11 +113,9 @@ 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); + void error(const QString &title, const QString &message, bool modal); /** Asks the user whether to pay the transaction fee or to cancel the transaction. It is currently not possible to pass a return value to another thread through BlockingQueuedConnection, so an indirected pointer is used. diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 5a0b4aa83c..8163da0915 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -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 diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 5a12c4fcd8..6366b4d617 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -43,6 +43,7 @@ private: int cachedNumConnections; int cachedNumBlocks; + QString cachedStatusBar; int numBlocksAtStartup; @@ -51,7 +52,7 @@ signals: void numBlocksChanged(int count); //! Asynchronous error notification - void error(const QString &title, const QString &message); + void error(const QString &title, const QString &message, bool modal); public slots: diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index ac69bd07e9..ad530a78e4 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -17,6 +17,7 @@ #include <QClipboard> #include <QFileDialog> #include <QDesktopServices> +#include <QThread> QString GUIUtil::dateTimeStr(qint64 nTime) { @@ -184,3 +185,14 @@ QString GUIUtil::getSaveFileName(QWidget *parent, const QString &caption, return result; } +Qt::ConnectionType GUIUtil::blockingGUIThreadConnection() +{ + if(QThread::currentThread() != QCoreApplication::instance()->thread()) + { + return Qt::BlockingQueuedConnection; + } + else + { + return Qt::DirectConnection; + } +} diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 75ba53f206..06426d76bc 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -60,6 +60,14 @@ public: const QString &dir=QString(), const QString &filter=QString(), QString *selectedSuffixOut=0); + + /** Get connection type to call object slot in GUI thread with invokeMethod. The call will be blocking. + + @returns If called from the GUI thread, return a Qt::DirectConnection. + If called from another thread, return a Qt::BlockingQueuedConnection. + */ + static Qt::ConnectionType blockingGUIThreadConnection(); + }; #endif // GUIUTIL_H diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 4cb2e68d0f..c32a006f71 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -4,7 +4,7 @@ #include "bitcoinunits.h" #include "headers.h" -#include "qtui.h" +#include "ui_interface.h" #include <QString> diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 8344a653d5..6cc023792d 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -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()); @@ -142,7 +140,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie } return TransactionCreationFailed; } - if(!ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString(), NULL)) + if(!ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString())) { return Aborted; } @@ -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); } diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index e894842499..c4468171a8 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -3,7 +3,7 @@ #include <QObject> -#include "util.h" +#include "allocators.h" /* for SecureString */ class OptionsModel; class AddressTableModel; @@ -135,12 +135,11 @@ signals: void requireUnlock(); // Asynchronous error notification - void error(const QString &title, const QString &message); + void error(const QString &title, const QString &message, bool modal); public slots: - -private slots: void update(); + void updateAddressList(); }; |