diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index 09a53a587..9fb5fa810 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -1,85 +1,88 @@ # Copyright (c) 2013-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. bin_PROGRAMS += qt/test/test_bitcoin-qt TESTS += qt/test/test_bitcoin-qt TEST_QT_MOC_CPP = \ qt/test/moc_bitcoinaddressvalidatortests.cpp \ qt/test/moc_compattests.cpp \ qt/test/moc_guiutiltests.cpp \ qt/test/moc_rpcnestedtests.cpp \ qt/test/moc_uritests.cpp if ENABLE_WALLET TEST_QT_MOC_CPP += \ + qt/test/moc_addressbooktests.cpp \ qt/test/moc_paymentservertests.cpp \ qt/test/moc_wallettests.cpp endif TEST_QT_H = \ + qt/test/addressbooktests.h \ qt/test/bitcoinaddressvalidatortests.h \ qt/test/compattests.h \ qt/test/guiutiltests.h \ qt/test/rpcnestedtests.h \ qt/test/uritests.h \ qt/test/util.h \ qt/test/paymentrequestdata.h \ qt/test/paymentservertests.h \ qt/test/wallettests.h TEST_BITCOIN_CPP = \ test/test_bitcoin.cpp TEST_BITCOIN_H = \ test/test_bitcoin.h qt_test_test_bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ $(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS) qt_test_test_bitcoin_qt_SOURCES = \ qt/test/bitcoinaddressvalidatortests.cpp \ qt/test/compattests.cpp \ qt/test/guiutiltests.cpp \ qt/test/rpcnestedtests.cpp \ qt/test/test_main.cpp \ qt/test/uritests.cpp \ qt/test/util.cpp \ $(TEST_QT_H) \ $(TEST_BITCOIN_CPP) \ $(TEST_BITCOIN_H) if ENABLE_WALLET qt_test_test_bitcoin_qt_SOURCES += \ + qt/test/addressbooktests.cpp \ qt/test/paymentservertests.cpp \ qt/test/wallettests.cpp \ wallet/test/wallet_test_fixture.cpp endif nodist_qt_test_test_bitcoin_qt_SOURCES = $(TEST_QT_MOC_CPP) qt_test_test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER) if ENABLE_WALLET qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_UTIL) $(LIBBITCOIN_WALLET) endif if ENABLE_ZMQ qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) \ $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \ $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) qt_test_test_bitcoin_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) CLEAN_BITCOIN_QT_TEST = $(TEST_QT_MOC_CPP) qt/test/*.gcda qt/test/*.gcno CLEANFILES += $(CLEAN_BITCOIN_QT_TEST) test_bitcoin_qt : qt/test/test_bitcoin-qt$(EXEEXT) test_bitcoin_qt_check : qt/test/test_bitcoin-qt$(EXEEXT) FORCE $(MAKE) check-TESTS TESTS=$^ test_bitcoin_qt_clean: FORCE rm -f $(CLEAN_BITCOIN_QT_TEST) $(qt_test_test_bitcoin_qt_OBJECTS) diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h index 0fbb904a0..9ee6fb190 100644 --- a/src/qt/addressbookpage.h +++ b/src/qt/addressbookpage.h @@ -1,88 +1,88 @@ // Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_ADDRESSBOOKPAGE_H #define BITCOIN_QT_ADDRESSBOOKPAGE_H #include class AddressBookSortFilterProxyModel; class AddressTableModel; class PlatformStyle; namespace Ui { class AddressBookPage; } QT_BEGIN_NAMESPACE class QItemSelection; class QMenu; class QModelIndex; QT_END_NAMESPACE /** Widget that shows a list of sending or receiving addresses. */ class AddressBookPage : public QDialog { Q_OBJECT public: enum Tabs { SendingTab = 0, ReceivingTab = 1 }; enum Mode { ForSelection, /**< Open address book to pick address */ ForEditing /**< Open address book for editing */ }; explicit AddressBookPage(const PlatformStyle *platformStyle, Mode mode, - Tabs tab, QWidget *parent); + Tabs tab, QWidget *parent = nullptr); ~AddressBookPage(); void setModel(AddressTableModel *model); const QString &getReturnValue() const { return returnValue; } public Q_SLOTS: void done(int retval) override; private: Ui::AddressBookPage *ui; AddressTableModel *model; Mode mode; Tabs tab; QString returnValue; AddressBookSortFilterProxyModel *proxyModel; QMenu *contextMenu; // to be able to explicitly disable it QAction *deleteAction; QString newAddressToSelect; private Q_SLOTS: /** Delete currently selected address entry */ void on_deleteAddress_clicked(); /** * Create a new address for receiving coins and / or add a new address book * entry. */ void on_newAddress_clicked(); /** Copy address of currently selected address entry to clipboard */ void on_copyAddress_clicked(); /** * Copy label of currently selected address entry to clipboard (no button) */ void onCopyLabelAction(); /** Edit currently selected address entry (no button) */ void onEditAction(); /** Export button clicked */ void on_exportButton_clicked(); /** Set button states based on selected tab and selection */ void selectionChanged(); /** Spawn contextual menu (right mouse menu) for address book entry */ void contextualMenu(const QPoint &point); /** New entry/entries were added to address table */ void selectNewAddress(const QModelIndex &parent, int begin, int /*end*/); Q_SIGNALS: void sendCoins(QString addr); }; #endif // BITCOIN_QT_ADDRESSBOOKPAGE_H diff --git a/src/qt/editaddressdialog.h b/src/qt/editaddressdialog.h index 2e03e8a87..1c96ac4c2 100644 --- a/src/qt/editaddressdialog.h +++ b/src/qt/editaddressdialog.h @@ -1,63 +1,63 @@ // Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_EDITADDRESSDIALOG_H #define BITCOIN_QT_EDITADDRESSDIALOG_H #include class AddressTableModel; namespace Ui { class EditAddressDialog; } QT_BEGIN_NAMESPACE class QDataWidgetMapper; QT_END_NAMESPACE /** * Dialog for editing an address and associated information. */ class EditAddressDialog : public QDialog { Q_OBJECT public: enum Mode { NewReceivingAddress, NewSendingAddress, EditReceivingAddress, EditSendingAddress }; - explicit EditAddressDialog(Mode mode, QWidget *parent); + explicit EditAddressDialog(Mode mode, QWidget *parent = nullptr); ~EditAddressDialog(); void setModel(AddressTableModel *model); void loadRow(int row); QString getAddress() const; void setAddress(const QString &address); public Q_SLOTS: void accept() override; private: bool saveCurrentRow(); /** * Return a descriptive string when adding an already-existing address * fails. */ QString getDuplicateAddressWarning() const; Ui::EditAddressDialog *ui; QDataWidgetMapper *mapper; Mode mode; AddressTableModel *model; QString address; }; #endif // BITCOIN_QT_EDITADDRESSDIALOG_H diff --git a/src/qt/test/CMakeLists.txt b/src/qt/test/CMakeLists.txt index c5e84dde2..226d02538 100644 --- a/src/qt/test/CMakeLists.txt +++ b/src/qt/test/CMakeLists.txt @@ -1,35 +1,36 @@ # Copyright (c) 2018 The Bitcoin developers project(test_bitcoin-qt) include(TestSuite) create_test_suite(bitcoin-qt) add_dependencies(check check-bitcoin-qt) add_test_to_suite(bitcoin-qt test_bitcoin-qt + addressbooktests.cpp bitcoinaddressvalidatortests.cpp compattests.cpp guiutiltests.cpp rpcnestedtests.cpp test_main.cpp uritests.cpp util.cpp # Test framework ../../test/test_bitcoin.cpp ) target_link_libraries(test_bitcoin-qt bitcoin-qt-base Qt5::Test) # Wallet if(BUILD_BITCOIN_WALLET) # Add wallet functionality to test_bitcoin-qt target_sources(test_bitcoin-qt PRIVATE paymentservertests.cpp wallettests.cpp ../../wallet/test/wallet_test_fixture.cpp ) target_link_libraries(test_bitcoin-qt wallet) endif() diff --git a/src/qt/test/addressbooktests.cpp b/src/qt/test/addressbooktests.cpp new file mode 100644 index 000000000..116917b58 --- /dev/null +++ b/src/qt/test/addressbooktests.cpp @@ -0,0 +1,146 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +namespace { + +/** + * Fill the edit address dialog box with data, submit it, and ensure that + * the resulting message meets expectations. + */ +void EditAddressAndSubmit(EditAddressDialog *dialog, const QString &label, + const QString &address, QString expected_msg) { + QString warning_text; + + dialog->findChild("labelEdit")->setText(label); + dialog->findChild("addressEdit")->setText(address); + + ConfirmMessage(&warning_text, 5); + dialog->accept(); + QCOMPARE(warning_text, expected_msg); +} + +/** + * Test adding various send addresses to the address book. + * + * There are three cases tested: + * + * - new_address: a new address which should add as a send address + * successfully. + * - existing_s_address: an existing sending address which won't add + * successfully. + * - existing_r_address: an existing receiving address which won't add + * successfully. + * + * In each case, verify the resulting state of the address book and optionally + * the warning message presented to the user. + */ +void TestAddAddressesToSendBook() { + TestChain100Setup test; + CWallet wallet(Params(), "mock", WalletDatabase::CreateMock()); + bool firstRun; + wallet.LoadWallet(firstRun); + + auto build_address = [&wallet]() { + CKey key; + key.MakeNewKey(true); + CTxDestination dest(GetDestinationForKey( + key.GetPubKey(), wallet.m_default_address_type)); + + return std::make_pair( + dest, QString::fromStdString(EncodeCashAddr(dest, Params()))); + }; + + CTxDestination r_key_dest, s_key_dest; + + // Add a preexisting "receive" entry in the address book. + QString preexisting_r_address; + QString r_label("already here (r)"); + + // Add a preexisting "send" entry in the address book. + QString preexisting_s_address; + QString s_label("already here (s)"); + + // Define a new address (which should add to the address book successfully). + QString new_address; + + std::tie(r_key_dest, preexisting_r_address) = build_address(); + std::tie(s_key_dest, preexisting_s_address) = build_address(); + std::tie(std::ignore, new_address) = build_address(); + + { + LOCK(wallet.cs_wallet); + wallet.SetAddressBook(r_key_dest, r_label.toStdString(), "receive"); + wallet.SetAddressBook(s_key_dest, s_label.toStdString(), "send"); + } + + auto check_addbook_size = [&wallet](int expected_size) { + QCOMPARE(static_cast(wallet.mapAddressBook.size()), expected_size); + }; + + // We should start with the two addresses we added earlier and nothing else. + check_addbook_size(2); + + // Initialize relevant QT models. + std::unique_ptr platformStyle( + PlatformStyle::instantiate("other")); + auto node = interfaces::MakeNode(); + OptionsModel optionsModel(*node); + AddWallet(&wallet); + WalletModel walletModel(std::move(node->getWallets()[0]), *node, + platformStyle.get(), &optionsModel); + RemoveWallet(&wallet); + EditAddressDialog editAddressDialog(EditAddressDialog::NewSendingAddress); + editAddressDialog.setModel(walletModel.getAddressTableModel()); + + EditAddressAndSubmit( + &editAddressDialog, QString("uhoh"), preexisting_r_address, + QString( + "Address \"%1\" already exists as a receiving address with label " + "\"%2\" and so cannot be added as a sending address.") + .arg(preexisting_r_address) + .arg(r_label)); + + check_addbook_size(2); + + EditAddressAndSubmit( + &editAddressDialog, QString("uhoh, different"), preexisting_s_address, + QString( + "The entered address \"%1\" is already in the address book with " + "label \"%2\".") + .arg(preexisting_s_address) + .arg(s_label)); + + check_addbook_size(2); + + // Submit a new address which should add successfully - we expect the + // warning message to be blank. + EditAddressAndSubmit(&editAddressDialog, QString("new"), new_address, + QString("")); + + check_addbook_size(3); +} + +} // namespace + +void AddressBookTests::addressBookTests() { + TestAddAddressesToSendBook(); +} diff --git a/src/qt/test/addressbooktests.h b/src/qt/test/addressbooktests.h new file mode 100644 index 000000000..51dcb5a9d --- /dev/null +++ b/src/qt/test/addressbooktests.h @@ -0,0 +1,14 @@ +#ifndef BITCOIN_QT_TEST_ADDRESSBOOKTESTS_H +#define BITCOIN_QT_TEST_ADDRESSBOOKTESTS_H + +#include +#include + +class AddressBookTests : public QObject { + Q_OBJECT + +private Q_SLOTS: + void addressBookTests(); +}; + +#endif // BITCOIN_QT_TEST_ADDRESSBOOKTESTS_H diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index f29b57855..197451af2 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -1,112 +1,117 @@ // Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #if defined(HAVE_CONFIG_H) #include #endif #include #include #include #include #include #include #include #include #include #ifdef ENABLE_WALLET +#include #include #include #endif #include #include #include #include #if defined(QT_STATICPLUGIN) #include #if defined(QT_QPA_PLATFORM_MINIMAL) Q_IMPORT_PLUGIN(QMinimalIntegrationPlugin); #endif #if defined(QT_QPA_PLATFORM_XCB) Q_IMPORT_PLUGIN(QXcbIntegrationPlugin); #elif defined(QT_QPA_PLATFORM_WINDOWS) Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin); #elif defined(QT_QPA_PLATFORM_COCOA) Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin); #endif #endif extern void noui_connect(); // This is all you need to run all the tests int main(int argc, char *argv[]) { SetupEnvironment(); SetupNetworking(); SelectParams(CBaseChainParams::MAIN); noui_connect(); ClearDatadirCache(); fs::path pathTemp = fs::temp_directory_path() / strprintf("test_bitcoin-qt_%lu_%i", (unsigned long)GetTime(), (int)GetRand(100000)); fs::create_directories(pathTemp); gArgs.ForceSetArg("-datadir", pathTemp.string()); bool fInvalid = false; // Prefer the "minimal" platform for the test instead of the normal default // platform ("xcb", "windows", or "cocoa") so tests can't unintentionally // interfere with any background GUIs and don't require extra resources. setenv("QT_QPA_PLATFORM", "minimal", 0); // Don't remove this, it's needed to access // QApplication:: and QCoreApplication:: in the tests QApplication app(argc, argv); app.setApplicationName("BitcoinABC-Qt-test"); // This is necessary to initialize openssl on the test framework // (at least on Darwin). SSL_library_init(); URITests test1; if (QTest::qExec(&test1) != 0) { fInvalid = true; } #ifdef ENABLE_WALLET PaymentServerTests test2; if (QTest::qExec(&test2) != 0) { fInvalid = true; } #endif RPCNestedTests test3; if (QTest::qExec(&test3) != 0) { fInvalid = true; } CompatTests test4; if (QTest::qExec(&test4) != 0) { fInvalid = true; } GUIUtilTests test5; if (QTest::qExec(&test5) != 0) { fInvalid = true; } BitcoinAddressValidatorTests test6; if (QTest::qExec(&test6) != 0) { fInvalid = true; } #ifdef ENABLE_WALLET WalletTests test7; if (QTest::qExec(&test7) != 0) { fInvalid = true; } + AddressBookTests test8; + if (QTest::qExec(&test8) != 0) { + fInvalid = true; + } #endif fs::remove_all(pathTemp); return fInvalid; } diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 6dc6a39e5..f4d821ae8 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -1,295 +1,299 @@ // Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_QT_WALLETMODEL_H #define BITCOIN_QT_WALLETMODEL_H #include #include #include #include #include #include #include #include class AddressTableModel; class OptionsModel; class PlatformStyle; class RecentRequestsTableModel; class TransactionTableModel; class WalletModelTransaction; class CCoinControl; class CKeyID; class COutPoint; class COutput; class CPubKey; namespace interfaces { class Node; } // namespace interfaces QT_BEGIN_NAMESPACE class QTimer; QT_END_NAMESPACE class SendCoinsRecipient { public: explicit SendCoinsRecipient() : amount(), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) {} explicit SendCoinsRecipient(const QString &addr, const QString &_label, const Amount _amount, const QString &_message) : address(addr), label(_label), amount(_amount), message(_message), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) {} // If from an unauthenticated payment request, this is used for storing the // addresses, e.g. address-A
address-B
address-C. // Info: As we don't need to process addresses in here when using payment // requests, we can abuse it for displaying an address list. // TOFO: This is a hack, should be replaced with a cleaner solution! QString address; QString label; Amount amount; // If from a payment request, this is used for storing the memo QString message; // If from a payment request, paymentRequest.IsInitialized() will be true PaymentRequestPlus paymentRequest; // Empty if no authentication or invalid signature/cert/etc. QString authenticatedMerchant; // memory only bool fSubtractFeeFromAmount; static const int CURRENT_VERSION = 1; int nVersion; ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream &s, Operation ser_action) { std::string sAddress = address.toStdString(); std::string sLabel = label.toStdString(); std::string sMessage = message.toStdString(); std::string sPaymentRequest; if (!ser_action.ForRead() && paymentRequest.IsInitialized()) { paymentRequest.SerializeToString(&sPaymentRequest); } std::string sAuthenticatedMerchant = authenticatedMerchant.toStdString(); READWRITE(this->nVersion); READWRITE(sAddress); READWRITE(sLabel); READWRITE(amount); READWRITE(sMessage); READWRITE(sPaymentRequest); READWRITE(sAuthenticatedMerchant); if (ser_action.ForRead()) { address = QString::fromStdString(sAddress); label = QString::fromStdString(sLabel); message = QString::fromStdString(sMessage); if (!sPaymentRequest.empty()) { paymentRequest.parse(QByteArray::fromRawData( sPaymentRequest.data(), sPaymentRequest.size())); } authenticatedMerchant = QString::fromStdString(sAuthenticatedMerchant); } } }; /** Interface to Bitcoin wallet from Qt view code. */ class WalletModel : public QObject { Q_OBJECT public: explicit WalletModel(std::unique_ptr wallet, interfaces::Node &node, const PlatformStyle *platformStyle, OptionsModel *optionsModel, QObject *parent = nullptr); ~WalletModel(); // Returned by sendCoins enum StatusCode { OK, InvalidAmount, InvalidAddress, AmountExceedsBalance, AmountWithFeeExceedsBalance, DuplicateAddress, // Error returned when wallet is still locked TransactionCreationFailed, TransactionCommitFailed, AbsurdFee, PaymentRequestExpired }; enum EncryptionStatus { // !wallet->IsCrypted() Unencrypted, // wallet->IsCrypted() && wallet->IsLocked() Locked, // wallet->IsCrypted() && !wallet->IsLocked() Unlocked }; OptionsModel *getOptionsModel(); AddressTableModel *getAddressTableModel(); TransactionTableModel *getTransactionTableModel(); RecentRequestsTableModel *getRecentRequestsTableModel(); EncryptionStatus getEncryptionStatus() const; // Check address for validity bool validateAddress(const QString &address); // Return status record for SendCoins, contains error id + information struct SendCoinsReturn { SendCoinsReturn(StatusCode _status = OK, QString _reasonCommitFailed = "") : status(_status), reasonCommitFailed(_reasonCommitFailed) {} StatusCode status; QString reasonCommitFailed; }; // prepare transaction for getting txfee before sending coins SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl &coinControl); // Send coins to a list of recipients SendCoinsReturn sendCoins(WalletModelTransaction &transaction); // Wallet encryption bool setWalletEncrypted(bool encrypted, const SecureString &passphrase); // Passphrase only needed when unlocking bool setWalletLocked(bool locked, const SecureString &passPhrase = SecureString()); bool changePassphrase(const SecureString &oldPass, const SecureString &newPass); // RAI object for unlocking wallet, returned by requestUnlock() class UnlockContext { public: UnlockContext(WalletModel *wallet, bool valid, bool relock); ~UnlockContext(); bool isValid() const { return valid; } // Copy operator and constructor transfer the context UnlockContext(const UnlockContext &obj) { CopyFrom(obj); } UnlockContext &operator=(const UnlockContext &rhs) { CopyFrom(rhs); return *this; } private: WalletModel *wallet; bool valid; // mutable, as it can be set to false by copying mutable bool relock; void CopyFrom(const UnlockContext &rhs); }; UnlockContext requestUnlock(); void loadReceiveRequests(std::vector &vReceiveRequests); bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest); static bool isWalletEnabled(); interfaces::Node &node() const { return m_node; } interfaces::Wallet &wallet() const { return *m_wallet; } const CChainParams &getChainParams() const; QString getWalletName() const; bool isMultiwallet(); + AddressTableModel *getAddressTableModel() const { + return addressTableModel; + } + private: std::unique_ptr m_wallet; std::unique_ptr m_handler_status_changed; std::unique_ptr m_handler_address_book_changed; std::unique_ptr m_handler_transaction_changed; std::unique_ptr m_handler_show_progress; std::unique_ptr m_handler_watch_only_changed; interfaces::Node &m_node; bool fHaveWatchOnly; bool fForceCheckBalanceChanged; // Wallet has an options model for wallet-specific options (transaction fee, // for example) OptionsModel *optionsModel; AddressTableModel *addressTableModel; TransactionTableModel *transactionTableModel; RecentRequestsTableModel *recentRequestsTableModel; // Cache some values to be able to detect changes interfaces::WalletBalances m_cached_balances; EncryptionStatus cachedEncryptionStatus; int cachedNumBlocks; QTimer *pollTimer; void subscribeToCoreSignals(); void unsubscribeFromCoreSignals(); void checkBalanceChanged(const interfaces::WalletBalances &new_balances); Q_SIGNALS: // Signal that balance in wallet changed void balanceChanged(const interfaces::WalletBalances &balances); // Encryption status of wallet changed void encryptionStatusChanged(); // Signal emitted when wallet needs to be unlocked // It is valid behaviour for listeners to keep the wallet locked after this // signal; this means that the unlocking failed or was cancelled. void requireUnlock(); // Fired when a message should be reported to the user void message(const QString &title, const QString &message, unsigned int style); // Coins sent: from wallet, to recipient, in (serialized) transaction: void coinsSent(WalletModel *wallet, SendCoinsRecipient recipient, QByteArray transaction); // Show progress dialog e.g. for rescan void showProgress(const QString &title, int nProgress); // Watch-only address added void notifyWatchonlyChanged(bool fHaveWatchonly); public Q_SLOTS: /** Wallet status might have changed. */ void updateStatus(); /** New transaction, or transaction changed status. */ void updateTransaction(); /** New, updated or removed address book entry. */ void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status); /** Watch-only added. */ void updateWatchOnlyFlag(bool fHaveWatchonly); /** * Current, immature or unconfirmed balance might have changed - emit * 'balanceChanged' if so. */ void pollBalanceChanged(); }; #endif // BITCOIN_QT_WALLETMODEL_H