aboutsummaryrefslogtreecommitdiff
path: root/src/qt
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2012-04-04 05:03:07 -0700
committerPieter Wuille <pieter.wuille@gmail.com>2012-04-04 05:03:07 -0700
commitb0a7e05a45a925d78efd00ecca6dce9b7a9530f9 (patch)
tree13d0f8f8650b545b767c3e6b8de3e2effa385f2f /src/qt
parentcadae3588c5553b8c7ef76c14d07041f639fb926 (diff)
parent5cccb13dad589b66957772ee36b3be0ef06ed0dc (diff)
downloadbitcoin-b0a7e05a45a925d78efd00ecca6dce9b7a9530f9.tar.xz
Merge pull request #1019 from laanwj/2012_03_uirefactor
Streamline UI ↔ Core interface
Diffstat (limited to 'src/qt')
-rw-r--r--src/qt/addressbookpage.cpp2
-rw-r--r--src/qt/addresstablemodel.cpp11
-rw-r--r--src/qt/addresstablemodel.h6
-rw-r--r--src/qt/bitcoin.cpp96
-rw-r--r--src/qt/bitcoingui.cpp26
-rw-r--r--src/qt/bitcoingui.h4
-rw-r--r--src/qt/clientmodel.cpp18
-rw-r--r--src/qt/clientmodel.h3
-rw-r--r--src/qt/guiutil.cpp12
-rw-r--r--src/qt/guiutil.h8
-rw-r--r--src/qt/transactiondesc.cpp2
-rw-r--r--src/qt/walletmodel.cpp17
-rw-r--r--src/qt/walletmodel.h7
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();
};