From 467c31ea0a76860f0c3357670c8525f2d950e8d6 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 5 Jun 2011 16:03:29 +0200 Subject: [PATCH] show messages from core/net thread --- bitcoin.pro | 3 +- core/include/externui.h | 45 +++++++++++++++++++++++++++ core/include/headers.h | 2 +- gui/include/bitcoingui.h | 7 +++-- gui/include/clientmodel.h | 3 ++ gui/src/bitcoin.cpp | 65 ++++++++++++++++++++++++++++++++++++++- gui/src/bitcoingui.cpp | 49 ++++++++++++++++++++--------- gui/src/clientmodel.cpp | 10 +++++- 8 files changed, 163 insertions(+), 21 deletions(-) create mode 100644 core/include/externui.h diff --git a/bitcoin.pro b/bitcoin.pro index e2f282a3f..9a3570aa5 100644 --- a/bitcoin.pro +++ b/bitcoin.pro @@ -62,7 +62,8 @@ HEADERS += gui/include/bitcoingui.h \ gui/include/transactionrecord.h \ gui/include/guiconstants.h \ gui/include/optionsmodel.h \ - gui/include/monitoreddatamapper.h + gui/include/monitoreddatamapper.h \ + core/include/externui.h SOURCES += gui/src/bitcoin.cpp gui/src/bitcoingui.cpp \ gui/src/transactiontablemodel.cpp \ gui/src/addresstablemodel.cpp \ diff --git a/core/include/externui.h b/core/include/externui.h new file mode 100644 index 000000000..e58ccc224 --- /dev/null +++ b/core/include/externui.h @@ -0,0 +1,45 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_EXTERNUI_H +#define BITCOIN_EXTERNUI_H + +#include + +typedef void wxWindow; +#define wxYES 0x00000002 +#define wxOK 0x00000004 +#define wxNO 0x00000008 +#define wxYES_NO (wxYES|wxNO) +#define wxCANCEL 0x00000010 +#define wxAPPLY 0x00000020 +#define wxCLOSE 0x00000040 +#define wxOK_DEFAULT 0x00000000 +#define wxYES_DEFAULT 0x00000000 +#define wxNO_DEFAULT 0x00000080 +#define wxCANCEL_DEFAULT 0x80000000 +#define wxICON_EXCLAMATION 0x00000100 +#define wxICON_HAND 0x00000200 +#define wxICON_WARNING wxICON_EXCLAMATION +#define wxICON_ERROR wxICON_HAND +#define wxICON_QUESTION 0x00000400 +#define wxICON_INFORMATION 0x00000800 +#define wxICON_STOP wxICON_HAND +#define wxICON_ASTERISK wxICON_INFORMATION +#define wxICON_MASK (0x00000100|0x00000200|0x00000400|0x00000800) +#define wxFORWARD 0x00001000 +#define wxBACKWARD 0x00002000 +#define wxRESET 0x00004000 +#define wxHELP 0x00008000 +#define wxMORE 0x00010000 +#define wxSETUP 0x00020000 + +extern int MyMessageBox(const std::string& message, const std::string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); +#define wxMessageBox MyMessageBox +extern int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); +extern bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindow* parent); +extern void CalledSetStatusBar(const std::string& strText, int nField); +extern void UIThreadCall(boost::function0 fn); +extern void MainFrameRepaint(); + +#endif diff --git a/core/include/headers.h b/core/include/headers.h index d40c5ed0a..33aeef338 100644 --- a/core/include/headers.h +++ b/core/include/headers.h @@ -127,7 +127,7 @@ #include "uibase.h" #include "ui.h" #else -#include "noui.h" +#include "externui.h" #endif #include "init.h" diff --git a/gui/include/bitcoingui.h b/gui/include/bitcoingui.h index 8b45dace0..c2c786b28 100644 --- a/gui/include/bitcoingui.h +++ b/gui/include/bitcoingui.h @@ -11,6 +11,8 @@ class ClientModel; QT_BEGIN_NAMESPACE class QLabel; class QLineEdit; +class QTableView; +class QAbstractItemModel; QT_END_NAMESPACE class BitcoinGUI : public QMainWindow @@ -33,7 +35,6 @@ protected: void closeEvent(QCloseEvent *event); private: - TransactionTableModel *transaction_model; ClientModel *model; QLineEdit *address; @@ -51,10 +52,12 @@ private: QAction *openBitcoin; QSystemTrayIcon *trayIcon; + QList transactionViews; void createActions(); QWidget *createTabs(); void createTrayIcon(); + void setTabsModel(QAbstractItemModel *transaction_model); public slots: void setBalance(qint64 balance); @@ -62,6 +65,7 @@ public slots: void setNumConnections(int count); void setNumBlocks(int count); void setNumTransactions(int count); + void error(const QString &title, const QString &message); private slots: void sendcoinsClicked(); @@ -72,7 +76,6 @@ private slots: void newAddressClicked(); void copyClipboardClicked(); void trayIconActivated(QSystemTrayIcon::ActivationReason reason); - void error(const QString &title, const QString &message); }; #endif diff --git a/gui/include/clientmodel.h b/gui/include/clientmodel.h index d68b34fe9..09d1fc921 100644 --- a/gui/include/clientmodel.h +++ b/gui/include/clientmodel.h @@ -5,6 +5,7 @@ class OptionsModel; class AddressTableModel; +class TransactionTableModel; class ClientModel : public QObject { @@ -25,6 +26,7 @@ public: OptionsModel *getOptionsModel(); AddressTableModel *getAddressTableModel(); + TransactionTableModel *getTransactionTableModel(); qint64 getBalance(); QString getAddress(); @@ -39,6 +41,7 @@ public: private: OptionsModel *optionsModel; AddressTableModel *addressTableModel; + TransactionTableModel *transactionTableModel; signals: void balanceChanged(qint64 balance); diff --git a/gui/src/bitcoin.cpp b/gui/src/bitcoin.cpp index 663590d01..dc3e8070b 100644 --- a/gui/src/bitcoin.cpp +++ b/gui/src/bitcoin.cpp @@ -5,22 +5,85 @@ #include "clientmodel.h" #include "util.h" #include "init.h" +#include "externui.h" #include +#include + +// Need a global reference to process net thread +BitcoinGUI *guiref; + +int MyMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y) +{ + // Message from main thread + printf("MyMessageBox\n"); + if(guiref) + { + guiref->error(QString::fromStdString(caption), + QString::fromStdString(message)); + } + else + { + QMessageBox::critical(0, QString::fromStdString(caption), + QString::fromStdString(message), + QMessageBox::Ok, QMessageBox::Ok); + } + return 4; +} + +int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y) +{ + // Message from network thread + if(guiref) + { + QMetaObject::invokeMethod(guiref, "error", Qt::QueuedConnection, + Q_ARG(QString, QString::fromStdString(caption)), + Q_ARG(QString, QString::fromStdString(message))); + } + else + { + printf("%s: %s\n", caption.c_str(), message.c_str()); + fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str()); + } + return 4; +} + +bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindow* parent) +{ + // Query from network thread + // TODO + return true; +} + +void CalledSetStatusBar(const std::string& strText, int nField) +{ + // Only used for built-in mining, which is disabled, simple ignore +} + +void UIThreadCall(boost::function0 fn) +{ + // Only used for built-in mining, which is disabled, simple ignore +} + +void MainFrameRepaint() +{ +} int main(int argc, char *argv[]) { QApplication app(argc, argv); app.setQuitOnLastWindowClosed(false); + BitcoinGUI window; + guiref = &window; try { if(AppInit2(argc, argv)) { ClientModel model; - BitcoinGUI window; window.setModel(&model); window.show(); + guiref = 0; /* Depending on settings: QApplication::setQuitOnLastWindowClosed(false); */ int retval = app.exec(); diff --git a/gui/src/bitcoingui.cpp b/gui/src/bitcoingui.cpp index b2aee6b31..b68720462 100644 --- a/gui/src/bitcoingui.cpp +++ b/gui/src/bitcoingui.cpp @@ -95,7 +95,6 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): vbox->addLayout(hbox_address); vbox->addLayout(hbox_balance); - transaction_model = new TransactionTableModel(this); vbox->addWidget(createTabs()); QWidget *centralwidget = new QWidget(this); @@ -169,6 +168,9 @@ void BitcoinGUI::setModel(ClientModel *model) // Report errors from network/worker thread connect(model, SIGNAL(error(QString,QString)), this, SLOT(error(QString,QString))); + + // Put transaction list in tabs + setTabsModel(model->getTransactionTableModel()); } void BitcoinGUI::createTrayIcon() @@ -199,18 +201,32 @@ void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason) QWidget *BitcoinGUI::createTabs() { - QStringList tab_filters, tab_labels; - tab_filters << "^." - << "^["+TransactionTableModel::Sent+TransactionTableModel::Received+"]" - << "^["+TransactionTableModel::Sent+"]" - << "^["+TransactionTableModel::Received+"]"; + QStringList tab_labels; tab_labels << tr("All transactions") << tr("Sent/Received") << tr("Sent") << tr("Received"); - QTabWidget *tabs = new QTabWidget(this); + QTabWidget *tabs = new QTabWidget(this); for(int i = 0; i < tab_labels.size(); ++i) + { + QTableView *view = new QTableView(this); + tabs->addTab(view, tab_labels.at(i)); + transactionViews.append(view); + } + + return tabs; +} + +void BitcoinGUI::setTabsModel(QAbstractItemModel *transaction_model) +{ + QStringList tab_filters; + tab_filters << "^." + << "^["+TransactionTableModel::Sent+TransactionTableModel::Received+"]" + << "^["+TransactionTableModel::Sent+"]" + << "^["+TransactionTableModel::Received+"]"; + + for(int i = 0; i < transactionViews.size(); ++i) { QSortFilterProxyModel *proxy_model = new QSortFilterProxyModel(this); proxy_model->setSourceModel(transaction_model); @@ -219,7 +235,7 @@ QWidget *BitcoinGUI::createTabs() proxy_model->setFilterRegExp(QRegExp(tab_filters.at(i))); proxy_model->setSortRole(Qt::EditRole); - QTableView *transaction_table = new QTableView(this); + QTableView *transaction_table = transactionViews.at(i); transaction_table->setModel(proxy_model); transaction_table->setSelectionBehavior(QAbstractItemView::SelectRows); transaction_table->setSelectionMode(QAbstractItemView::ExtendedSelection); @@ -237,10 +253,7 @@ QWidget *BitcoinGUI::createTabs() TransactionTableModel::Debit, 79); transaction_table->horizontalHeader()->resizeSection( TransactionTableModel::Credit, 79); - - tabs->addTab(transaction_table, tab_labels.at(i)); } - return tabs; } void BitcoinGUI::sendcoinsClicked() @@ -248,7 +261,6 @@ void BitcoinGUI::sendcoinsClicked() SendCoinsDialog dlg; dlg.setModel(model); dlg.exec(); - qDebug() << "After close"; } void BitcoinGUI::addressbookClicked() @@ -329,9 +341,16 @@ void BitcoinGUI::setNumTransactions(int count) void BitcoinGUI::error(const QString &title, const QString &message) { // Report errors from network/worker thread - QMessageBox::critical(this, title, - message, - QMessageBox::Ok, QMessageBox::Ok); + if(trayIcon->supportsMessages()) + { + // Show as "balloon" message if possible + trayIcon->showMessage(title, message, QSystemTrayIcon::Critical); + } else { + // Fall back to old fashioned popup dialog if not + QMessageBox::critical(this, title, + message, + QMessageBox::Ok, QMessageBox::Ok); + } } void BitcoinGUI::changeEvent(QEvent *e) diff --git a/gui/src/clientmodel.cpp b/gui/src/clientmodel.cpp index 5f3517abd..8fd3599e9 100644 --- a/gui/src/clientmodel.cpp +++ b/gui/src/clientmodel.cpp @@ -3,11 +3,13 @@ #include "guiconstants.h" #include "optionsmodel.h" #include "addresstablemodel.h" +#include "transactiontablemodel.h" #include ClientModel::ClientModel(QObject *parent) : - QObject(parent), optionsModel(0), addressTableModel(0) + QObject(parent), optionsModel(0), addressTableModel(0), + transactionTableModel(0) { /* Until signal notifications is built into the bitcoin core, simply update everything after polling using a timer. @@ -18,6 +20,7 @@ ClientModel::ClientModel(QObject *parent) : optionsModel = new OptionsModel(this); addressTableModel = new AddressTableModel(this); + transactionTableModel = new TransactionTableModel(this); } qint64 ClientModel::getBalance() @@ -140,3 +143,8 @@ AddressTableModel *ClientModel::getAddressTableModel() { return addressTableModel; } + +TransactionTableModel *ClientModel::getTransactionTableModel() +{ + return transactionTableModel; +}