diff options
65 files changed, 631 insertions, 308 deletions
diff --git a/.gitignore b/.gitignore index b11949171e..a34921b3ac 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,10 @@ src/test_bitcoin Makefile bitcoin-qt +# Unit-tests +Makefile.test +bitcoin-qt_test + # Resources cpp qrc_*.cpp @@ -3,7 +3,7 @@ Bitcoin integration/staging tree http://www.bitcoin.org -Copyright (c) 2009-2012 Bitcoin Developers +Copyright (c) 2009-2013 Bitcoin Developers What is Bitcoin? ---------------- diff --git a/bitcoin-qt.pro b/bitcoin-qt.pro index 5042adfbdf..bf41314052 100644 --- a/bitcoin-qt.pro +++ b/bitcoin-qt.pro @@ -30,10 +30,8 @@ contains(RELEASE, 1) { macx:QMAKE_OBJECTIVE_CFLAGS += -mmacosx-version-min=10.5 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk !win32:!macx { - # Linux: static link + # Linux: static link and extra security (see: https://wiki.debian.org/Hardening) LIBS += -Wl,-Bstatic -Wl,-z,relro -Wl,-z,now - # for extra security (see: https://wiki.debian.org/Hardening) - QMAKE_CXXFLAGS *= -D_FORTIFY_SOURCE=2 } } @@ -44,6 +42,8 @@ contains(RELEASE, 1) { # Exclude on Windows cross compile with MinGW 4.2.x, as it will result in a non-working executable! # This can be enabled for Windows, when we switch to MinGW >= 4.4.x. } +# for extra security (see: https://wiki.debian.org/Hardening): this flag is GCC compiler-specific +QMAKE_CXXFLAGS *= -D_FORTIFY_SOURCE=2 # for extra security on Windows: enable ASLR and DEP via GCC linker flags win32:QMAKE_LFLAGS *= -Wl,--dynamicbase -Wl,--nxcompat # on Windows: enable GCC large address aware linker flag diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 230a248422..4a6cc42efc 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -194,70 +194,70 @@ Value stop(const Array& params, bool fHelp) static const CRPCCommand vRPCCommands[] = -{ // name function safemd unlocked - // ------------------------ ----------------------- ------ -------- - { "help", &help, true, true }, - { "stop", &stop, true, true }, - { "getblockcount", &getblockcount, true, false }, - { "getconnectioncount", &getconnectioncount, true, false }, - { "getpeerinfo", &getpeerinfo, true, false }, - { "addnode", &addnode, true, true }, - { "getaddednodeinfo", &getaddednodeinfo, true, true }, - { "getdifficulty", &getdifficulty, true, false }, - { "getgenerate", &getgenerate, true, false }, - { "setgenerate", &setgenerate, true, false }, - { "gethashespersec", &gethashespersec, true, false }, - { "getinfo", &getinfo, true, false }, - { "getmininginfo", &getmininginfo, true, false }, - { "getnewaddress", &getnewaddress, true, false }, - { "getaccountaddress", &getaccountaddress, true, false }, - { "setaccount", &setaccount, true, false }, - { "getaccount", &getaccount, false, false }, - { "getaddressesbyaccount", &getaddressesbyaccount, true, false }, - { "sendtoaddress", &sendtoaddress, false, false }, - { "getreceivedbyaddress", &getreceivedbyaddress, false, false }, - { "getreceivedbyaccount", &getreceivedbyaccount, false, false }, - { "listreceivedbyaddress", &listreceivedbyaddress, false, false }, - { "listreceivedbyaccount", &listreceivedbyaccount, false, false }, - { "backupwallet", &backupwallet, true, false }, - { "keypoolrefill", &keypoolrefill, true, false }, - { "walletpassphrase", &walletpassphrase, true, false }, - { "walletpassphrasechange", &walletpassphrasechange, false, false }, - { "walletlock", &walletlock, true, false }, - { "encryptwallet", &encryptwallet, false, false }, - { "validateaddress", &validateaddress, true, false }, - { "getbalance", &getbalance, false, false }, - { "move", &movecmd, false, false }, - { "sendfrom", &sendfrom, false, false }, - { "sendmany", &sendmany, false, false }, - { "addmultisigaddress", &addmultisigaddress, false, false }, - { "createmultisig", &createmultisig, true, true }, - { "getrawmempool", &getrawmempool, true, false }, - { "getblock", &getblock, false, false }, - { "getblockhash", &getblockhash, false, false }, - { "gettransaction", &gettransaction, false, false }, - { "listtransactions", &listtransactions, false, false }, - { "listaddressgroupings", &listaddressgroupings, false, false }, - { "signmessage", &signmessage, false, false }, - { "verifymessage", &verifymessage, false, false }, - { "getwork", &getwork, true, false }, - { "listaccounts", &listaccounts, false, false }, - { "settxfee", &settxfee, false, false }, - { "getblocktemplate", &getblocktemplate, true, false }, - { "submitblock", &submitblock, false, false }, - { "listsinceblock", &listsinceblock, false, false }, - { "dumpprivkey", &dumpprivkey, true, false }, - { "importprivkey", &importprivkey, false, false }, - { "listunspent", &listunspent, false, false }, - { "getrawtransaction", &getrawtransaction, false, false }, - { "createrawtransaction", &createrawtransaction, false, false }, - { "decoderawtransaction", &decoderawtransaction, false, false }, - { "signrawtransaction", &signrawtransaction, false, false }, - { "sendrawtransaction", &sendrawtransaction, false, false }, - { "gettxoutsetinfo", &gettxoutsetinfo, true, false }, - { "gettxout", &gettxout, true, false }, - { "lockunspent", &lockunspent, false, false }, - { "listlockunspent", &listlockunspent, false, false }, +{ // name actor (function) okSafeMode threadSafe + // ------------------------ ----------------------- ---------- ---------- + { "help", &help, true, true }, + { "stop", &stop, true, true }, + { "getblockcount", &getblockcount, true, false }, + { "getconnectioncount", &getconnectioncount, true, false }, + { "getpeerinfo", &getpeerinfo, true, false }, + { "addnode", &addnode, true, true }, + { "getaddednodeinfo", &getaddednodeinfo, true, true }, + { "getdifficulty", &getdifficulty, true, false }, + { "getgenerate", &getgenerate, true, false }, + { "setgenerate", &setgenerate, true, false }, + { "gethashespersec", &gethashespersec, true, false }, + { "getinfo", &getinfo, true, false }, + { "getmininginfo", &getmininginfo, true, false }, + { "getnewaddress", &getnewaddress, true, false }, + { "getaccountaddress", &getaccountaddress, true, false }, + { "setaccount", &setaccount, true, false }, + { "getaccount", &getaccount, false, false }, + { "getaddressesbyaccount", &getaddressesbyaccount, true, false }, + { "sendtoaddress", &sendtoaddress, false, false }, + { "getreceivedbyaddress", &getreceivedbyaddress, false, false }, + { "getreceivedbyaccount", &getreceivedbyaccount, false, false }, + { "listreceivedbyaddress", &listreceivedbyaddress, false, false }, + { "listreceivedbyaccount", &listreceivedbyaccount, false, false }, + { "backupwallet", &backupwallet, true, false }, + { "keypoolrefill", &keypoolrefill, true, false }, + { "walletpassphrase", &walletpassphrase, true, false }, + { "walletpassphrasechange", &walletpassphrasechange, false, false }, + { "walletlock", &walletlock, true, false }, + { "encryptwallet", &encryptwallet, false, false }, + { "validateaddress", &validateaddress, true, false }, + { "getbalance", &getbalance, false, false }, + { "move", &movecmd, false, false }, + { "sendfrom", &sendfrom, false, false }, + { "sendmany", &sendmany, false, false }, + { "addmultisigaddress", &addmultisigaddress, false, false }, + { "createmultisig", &createmultisig, true, true }, + { "getrawmempool", &getrawmempool, true, false }, + { "getblock", &getblock, false, false }, + { "getblockhash", &getblockhash, false, false }, + { "gettransaction", &gettransaction, false, false }, + { "listtransactions", &listtransactions, false, false }, + { "listaddressgroupings", &listaddressgroupings, false, false }, + { "signmessage", &signmessage, false, false }, + { "verifymessage", &verifymessage, false, false }, + { "getwork", &getwork, true, false }, + { "listaccounts", &listaccounts, false, false }, + { "settxfee", &settxfee, false, false }, + { "getblocktemplate", &getblocktemplate, true, false }, + { "submitblock", &submitblock, false, false }, + { "listsinceblock", &listsinceblock, false, false }, + { "dumpprivkey", &dumpprivkey, true, false }, + { "importprivkey", &importprivkey, false, false }, + { "listunspent", &listunspent, false, false }, + { "getrawtransaction", &getrawtransaction, false, false }, + { "createrawtransaction", &createrawtransaction, false, false }, + { "decoderawtransaction", &decoderawtransaction, false, false }, + { "signrawtransaction", &signrawtransaction, false, false }, + { "sendrawtransaction", &sendrawtransaction, false, false }, + { "gettxoutsetinfo", &gettxoutsetinfo, true, false }, + { "gettxout", &gettxout, true, false }, + { "lockunspent", &lockunspent, false, false }, + { "listlockunspent", &listlockunspent, false, false }, }; CRPCTable::CRPCTable() @@ -1072,7 +1072,7 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s // Execute Value result; { - if (pcmd->unlocked) + if (pcmd->threadSafe) result = pcmd->actor(params, false); else { LOCK2(cs_main, pwalletMain->cs_wallet); diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 36bfbe3eef..6a3554aea6 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -95,7 +95,7 @@ public: std::string name; rpcfn_type actor; bool okSafeMode; - bool unlocked; + bool threadSafe; }; /** diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 9b11f0b351..62234b9117 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -44,6 +44,7 @@ namespace Checkpoints (193000, uint256("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")) (210000, uint256("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")) (216116, uint256("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")) + (225430, uint256("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")) ; static const CCheckpointData data = { &mapCheckpoints, diff --git a/src/init.cpp b/src/init.cpp index 5b8436651a..63610b17fb 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -608,13 +608,11 @@ bool AppInit2() // ********************************************************* Step 5: verify wallet database integrity - uiInterface.InitMessage(_("Verifying wallet integrity...")); + uiInterface.InitMessage(_("Verifying wallet...")); if (!bitdb.Open(GetDataDir())) { - string msg = strprintf(_("Error initializing database environment %s!" - " To recover, BACKUP THAT DIRECTORY, then remove" - " everything from it except for wallet.dat."), strDataDir.c_str()); + string msg = strprintf(_("Error initializing wallet database environment %s!"), strDataDir.c_str()); return InitError(msg); } @@ -826,7 +824,7 @@ bool AppInit2() break; } - uiInterface.InitMessage(_("Verifying database...")); + uiInterface.InitMessage(_("Verifying blocks...")); if (!VerifyDB()) { strLoadError = _("Corrupted block database detected"); break; @@ -985,7 +983,6 @@ bool AppInit2() // ********************************************************* Step 9: import blocks // scan for better chains in the block chain database, that are not yet connected in the active best chain - uiInterface.InitMessage(_("Importing blocks from block database...")); CValidationState state; if (!ConnectBestBlock(state)) strErrors << "Failed to connect best block"; diff --git a/src/main.cpp b/src/main.cpp index 9a06dbf13e..22baf0f3eb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2056,6 +2056,25 @@ bool CBlock::CheckBlock(CValidationState &state, bool fCheckPOW, bool fCheckMerk if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) return state.DoS(100, error("CheckBlock() : size limits failed")); + // Special short-term limits to avoid 10,000 BDB lock limit: + if (GetBlockTime() >= 1363867200 && // start enforcing 21 March 2013, noon GMT + GetBlockTime() < 1368576000) // stop enforcing 15 May 2013 00:00:00 + { + // Rule is: #unique txids referenced <= 4,500 + // ... to prevent 10,000 BDB lock exhaustion on old clients + set<uint256> setTxIn; + for (size_t i = 0; i < vtx.size(); i++) + { + setTxIn.insert(vtx[i].GetHash()); + if (i == 0) continue; // skip coinbase txin + BOOST_FOREACH(const CTxIn& txin, vtx[i].vin) + setTxIn.insert(txin.prevout.hash); + } + size_t nTxids = setTxIn.size(); + if (nTxids > 4500) + return error("CheckBlock() : 15 May maxlocks violation"); + } + // Check proof of work matches claimed amount if (fCheckPOW && !CheckProofOfWork(GetHash(), nBits)) return state.DoS(50, error("CheckBlock() : proof of work failed")); @@ -4136,6 +4155,10 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey) // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity: nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize)); + // Special compatibility rule before 15 May: limit size to 500,000 bytes: + if (GetAdjustedTime() < 1368576000) + nBlockMaxSize = std::min(nBlockMaxSize, (unsigned int)(MAX_BLOCK_SIZE_GEN)); + // How much of the block should be dedicated to high-priority transactions, // included regardless of the fees they pay unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", 27000); diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index f4696d5a3b..9e35e51bbf 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -8,15 +8,15 @@ #include "csvmodelwriter.h" #include "guiutil.h" +#ifdef USE_QRCODE +#include "qrcodedialog.h" +#endif + #include <QSortFilterProxyModel> #include <QClipboard> #include <QMessageBox> #include <QMenu> -#ifdef USE_QRCODE -#include "qrcodedialog.h" -#endif - AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : QDialog(parent), ui(new Ui::AddressBookPage), @@ -65,6 +65,7 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : QAction *copyAddressAction = new QAction(ui->copyToClipboard->text(), this); QAction *copyLabelAction = new QAction(tr("Copy &Label"), this); QAction *editAction = new QAction(tr("&Edit"), this); + QAction *sendCoinsAction = new QAction(tr("Send &Coins"), this); QAction *showQRCodeAction = new QAction(ui->showQRCode->text(), this); QAction *signMessageAction = new QAction(ui->signMessage->text(), this); QAction *verifyMessageAction = new QAction(ui->verifyMessage->text(), this); @@ -78,6 +79,8 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : if(tab == SendingTab) contextMenu->addAction(deleteAction); contextMenu->addSeparator(); + if(tab == SendingTab) + contextMenu->addAction(sendCoinsAction); #ifdef USE_QRCODE contextMenu->addAction(showQRCodeAction); #endif @@ -91,6 +94,7 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(onCopyLabelAction())); connect(editAction, SIGNAL(triggered()), this, SLOT(onEditAction())); connect(deleteAction, SIGNAL(triggered()), this, SLOT(on_deleteButton_clicked())); + connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(onSendCoins_clicked())); connect(showQRCodeAction, SIGNAL(triggered()), this, SLOT(on_showQRCode_clicked())); connect(signMessageAction, SIGNAL(triggered()), this, SLOT(on_signMessage_clicked())); connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(on_verifyMessage_clicked())); @@ -206,6 +210,18 @@ void AddressBookPage::on_verifyMessage_clicked() } } +void AddressBookPage::onSendCoins_clicked() +{ + QTableView *table = ui->tableView; + QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); + + foreach (QModelIndex index, indexes) + { + QString address = index.data().toString(); + emit sendCoins(address); + } +} + void AddressBookPage::on_newAddressButton_clicked() { if(!model) diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h index c676d1e941..c6653a5e8a 100644 --- a/src/qt/addressbookpage.h +++ b/src/qt/addressbookpage.h @@ -68,6 +68,8 @@ private slots: void on_signMessage_clicked(); /** Open the verify message tab in the Sign/Verify Message dialog with currently selected address */ void on_verifyMessage_clicked(); + /** Open send coins dialog for currently selected address (no button) */ + void onSendCoins_clicked(); /** Generate a QR Code from the currently selected address */ void on_showQRCode_clicked(); /** Copy label of currently selected address entry to clipboard (no button) */ @@ -85,6 +87,7 @@ private slots: signals: void signMessage(QString addr); void verifyMessage(QString addr); + void sendCoins(QString addr); }; #endif // ADDRESSBOOKPAGE_H diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 03b09cdceb..1801444521 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -1,4 +1,5 @@ #include "addresstablemodel.h" + #include "guiutil.h" #include "walletmodel.h" @@ -6,7 +7,6 @@ #include "base58.h" #include <QFont> -#include <QColor> const QString AddressTableModel::Send = "S"; const QString AddressTableModel::Receive = "R"; diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h index ae3e3b2f04..48baff5e54 100644 --- a/src/qt/addresstablemodel.h +++ b/src/qt/addresstablemodel.h @@ -14,6 +14,7 @@ class WalletModel; class AddressTableModel : public QAbstractTableModel { Q_OBJECT + public: explicit AddressTableModel(CWallet *wallet, WalletModel *parent = 0); ~AddressTableModel(); diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h index 338853ce22..9df002da2c 100644 --- a/src/qt/askpassphrasedialog.h +++ b/src/qt/askpassphrasedialog.h @@ -6,7 +6,6 @@ namespace Ui { class AskPassphraseDialog; } - class WalletModel; /** Multifunctional dialog to ask for passphrases. Used for encryption, unlocking, and changing the passphrase. diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 75e9b965b1..e3d51be54a 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -1,6 +1,9 @@ /* * W.J. van der Laan 2011-2012 */ + +#include <QApplication> + #include "bitcoingui.h" #include "clientmodel.h" #include "walletmodel.h" @@ -11,7 +14,6 @@ #include "ui_interface.h" #include "paymentserver.h" -#include <QApplication> #include <QMessageBox> #include <QTextCodec> #include <QLocale> diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index b13a87dd24..84ebb2483f 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -1,4 +1,4 @@ -<RCC> +<!DOCTYPE RCC><RCC version="1.0"> <qresource prefix="/icons"> <file alias="bitcoin">res/icons/bitcoin.png</file> <file alias="address-book">res/icons/address-book.png</file> diff --git a/src/qt/bitcoinaddressvalidator.h b/src/qt/bitcoinaddressvalidator.h index 9710d122b6..2b6a59367d 100644 --- a/src/qt/bitcoinaddressvalidator.h +++ b/src/qt/bitcoinaddressvalidator.h @@ -1,7 +1,7 @@ #ifndef BITCOINADDRESSVALIDATOR_H #define BITCOINADDRESSVALIDATOR_H -#include <QRegExpValidator> +#include <QValidator> /** Base48 entry widget validator. Corrects near-miss characters and refuses characters that are no part of base48. @@ -9,16 +9,13 @@ class BitcoinAddressValidator : public QValidator { Q_OBJECT + public: explicit BitcoinAddressValidator(QObject *parent = 0); State validate(QString &input, int &pos) const; static const int MaxAddressLength = 35; -signals: - -public slots: - }; #endif // BITCOINADDRESSVALIDATOR_H diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index 9514ec8465..4fa2ca508b 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -1,18 +1,14 @@ #include "bitcoinamountfield.h" + #include "qvaluecombobox.h" #include "bitcoinunits.h" - #include "guiconstants.h" -#include <QLabel> -#include <QLineEdit> -#include <QRegExpValidator> #include <QHBoxLayout> #include <QKeyEvent> #include <QDoubleSpinBox> -#include <QComboBox> #include <QApplication> -#include <qmath.h> +#include <qmath.h> // for qPow() BitcoinAmountField::BitcoinAmountField(QWidget *parent): QWidget(parent), amount(0), currentUnit(-1) @@ -149,6 +145,11 @@ void BitcoinAmountField::unitChanged(int idx) amount->setDecimals(BitcoinUnits::decimals(currentUnit)); amount->setMaximum(qPow(10, BitcoinUnits::amountDigits(currentUnit)) - qPow(10, -amount->decimals())); + if(currentUnit == BitcoinUnits::uBTC) + amount->setSingleStep(0.01); + else + amount->setSingleStep(0.001); + if(valid) { // If value was valid, re-place it in the widget with the new unit diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h index 4797c4c882..dacbb395ec 100644 --- a/src/qt/bitcoinamountfield.h +++ b/src/qt/bitcoinamountfield.h @@ -13,7 +13,9 @@ QT_END_NAMESPACE class BitcoinAmountField: public QWidget { Q_OBJECT + Q_PROPERTY(qint64 value READ value WRITE setValue NOTIFY textChanged USER true) + public: explicit BitcoinAmountField(QWidget *parent = 0); @@ -56,5 +58,4 @@ private slots: }; - #endif // BITCOINAMOUNTFIELD_H diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index f1bf5f5880..b9cd7f51d2 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -4,7 +4,11 @@ * W.J. van der Laan 2011-2012 * The Bitcoin Developers 2011-2012 */ + +#include <QApplication> + #include "bitcoingui.h" + #include "transactiontablemodel.h" #include "addressbookpage.h" #include "sendcoinsdialog.h" @@ -31,19 +35,13 @@ #include "macdockiconhandler.h" #endif -#include <QApplication> -#include <QMainWindow> #include <QMenuBar> #include <QMenu> #include <QIcon> -#include <QTabWidget> #include <QVBoxLayout> #include <QToolBar> #include <QStatusBar> #include <QLabel> -#include <QLineEdit> -#include <QPushButton> -#include <QLocale> #include <QMessageBox> #include <QProgressBar> #include <QStackedWidget> @@ -54,7 +52,10 @@ #include <QTimer> #include <QDragEnterEvent> #include <QUrl> +#include <QMimeData> #include <QStyle> +#include <QSettings> +#include <QDesktopWidget> #include <iostream> @@ -70,7 +71,7 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): rpcConsole(0), prevBlocks(0) { - resize(850, 550); + restoreWindowGeometry(); setWindowTitle(tr("Bitcoin") + " - " + tr("Wallet")); #ifndef Q_OS_MAC qApp->setWindowIcon(QIcon(":icons/bitcoin")); @@ -173,9 +174,11 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): rpcConsole = new RPCConsole(this); connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show())); - // Clicking on "Verify Message" in the address book sends you to the verify message tab + // Clicking on "Send Coins" in the address book sends you to the send coins tab + connect(addressBookPage, SIGNAL(sendCoins(QString)), this, SLOT(gotoSendCoinsPage(QString))); + // Clicking on "Verify Message" in the address book opens the verify message tab in the Sign/Verify Message dialog connect(addressBookPage, SIGNAL(verifyMessage(QString)), this, SLOT(gotoVerifyMessageTab(QString))); - // Clicking on "Sign Message" in the receive coins page sends you to the sign message tab + // Clicking on "Sign Message" in the receive coins page opens the sign message tab in the Sign/Verify Message dialog connect(receiveCoinsPage, SIGNAL(signMessage(QString)), this, SLOT(gotoSignMessageTab(QString))); // Install event filter to be able to catch status tip events (QEvent::StatusTip) @@ -186,6 +189,7 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): BitcoinGUI::~BitcoinGUI() { + saveWindowGeometry(); if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu) trayIcon->hide(); #ifdef Q_OS_MAC @@ -467,6 +471,28 @@ void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason) } #endif +void BitcoinGUI::saveWindowGeometry() +{ + QSettings settings; + settings.setValue("nWindowPos", pos()); + settings.setValue("nWindowSize", size()); +} + +void BitcoinGUI::restoreWindowGeometry() +{ + QSettings settings; + QPoint pos = settings.value("nWindowPos").toPoint(); + QSize size = settings.value("nWindowSize", QSize(850, 550)).toSize(); + if (!pos.x() && !pos.y()) + { + QRect screen = qApp->desktop()->screenGeometry(); + pos.setX((screen.width()-size.width())/2); + pos.setY((screen.height()-size.height())/2); + } + resize(size); + move(pos); +} + void BitcoinGUI::optionsClicked() { if(!clientModel || !clientModel->getOptionsModel()) @@ -759,13 +785,16 @@ void BitcoinGUI::gotoReceiveCoinsPage() connect(exportAction, SIGNAL(triggered()), receiveCoinsPage, SLOT(exportClicked())); } -void BitcoinGUI::gotoSendCoinsPage() +void BitcoinGUI::gotoSendCoinsPage(QString addr) { sendCoinsAction->setChecked(true); centralWidget->setCurrentWidget(sendCoinsPage); exportAction->setEnabled(false); disconnect(exportAction, SIGNAL(triggered()), 0, 0); + + if(!addr.isEmpty()) + sendCoinsPage->setAddress(addr); } void BitcoinGUI::gotoSignMessageTab(QString addr) diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 8ce0335bcd..af8dc0a1fe 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -17,13 +17,9 @@ class RPCConsole; QT_BEGIN_NAMESPACE class QLabel; -class QLineEdit; -class QTableView; -class QAbstractItemModel; class QModelIndex; class QProgressBar; class QStackedWidget; -class QUrl; QT_END_NAMESPACE /** @@ -33,6 +29,7 @@ QT_END_NAMESPACE class BitcoinGUI : public QMainWindow { Q_OBJECT + public: explicit BitcoinGUI(QWidget *parent = 0); ~BitcoinGUI(); @@ -111,6 +108,10 @@ private: void createTrayIcon(); /** Create system tray menu (or setup the dock menu) */ void createTrayIconMenu(); + /** Save window size and position */ + void saveWindowGeometry(); + /** Restore window size and position */ + void restoreWindowGeometry(); public slots: /** Set number of connections shown in the UI */ @@ -152,7 +153,7 @@ private slots: /** Switch to receive coins page */ void gotoReceiveCoinsPage(); /** Switch to send coins page */ - void gotoSendCoinsPage(); + void gotoSendCoinsPage(QString addr = ""); /** Show Sign/Verify Message dialog and switch to sign message tab */ void gotoSignMessageTab(QString addr = ""); diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 2c3d859c82..dc506f0497 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -31,8 +31,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Cannot obtain a lock on data directory %s. Bitcoin is probably already " "running."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Corrupted block database detected. Please restart the client with -reindex."), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Error initializing database environment %s! To recover, BACKUP THAT " "DIRECTORY, then remove everything from it except for wallet.dat."), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -43,6 +41,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Error: This transaction requires a transaction fee of at least %s because of " "its amount, complexity, or use of recently received funds!"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Execute command when a wallet transaction changes (%s in cmd is replaced by " +"TxID)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Execute command when the best block changes (%s in cmd is replaced by block " "hash)"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -97,7 +98,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write default address"), QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node(s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Connect through socks proxy"), QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, and disconnect"), +QT_TRANSLATE_NOOP("bitcoin-core", "Corrupted block database detected"), QT_TRANSLATE_NOOP("bitcoin-core", "Discover own IP address (default: 1 when listening and no -externalip)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Do you want to rebuild the block database now?"), QT_TRANSLATE_NOOP("bitcoin-core", "Don't generate coins"), QT_TRANSLATE_NOOP("bitcoin-core", "Done loading"), QT_TRANSLATE_NOOP("bitcoin-core", "Error initializing block database"), @@ -105,6 +108,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error loading block database"), QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat"), QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"), QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of Bitcoin"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error opening block database"), QT_TRANSLATE_NOOP("bitcoin-core", "Error"), QT_TRANSLATE_NOOP("bitcoin-core", "Error: Disk space is low!"), QT_TRANSLATE_NOOP("bitcoin-core", "Error: Transaction creation failed!"), @@ -190,7 +194,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: QT_TRANSLATE_NOOP("bitcoin-core", "Use proxy to reach tor hidden services (default: same as -proxy)"), QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network"), QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"), -QT_TRANSLATE_NOOP("bitcoin-core", "Verifying block database integrity..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Verifying database..."), QT_TRANSLATE_NOOP("bitcoin-core", "Verifying wallet integrity..."), QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart Bitcoin to complete"), QT_TRANSLATE_NOOP("bitcoin-core", "Warning"), diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h index 9b7c9e160e..6e96cef59d 100644 --- a/src/qt/bitcoinunits.h +++ b/src/qt/bitcoinunits.h @@ -9,6 +9,8 @@ */ class BitcoinUnits: public QAbstractListModel { + Q_OBJECT + public: explicit BitcoinUnits(QObject *parent); @@ -58,6 +60,7 @@ public: int rowCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const; ///@} + private: QList<BitcoinUnits::Unit> unitlist; }; diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 858fbe241f..ae66924181 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -1,4 +1,5 @@ #include "clientmodel.h" + #include "guiconstants.h" #include "optionsmodel.h" #include "addresstablemodel.h" diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index a3fe92048c..3ba34b2786 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -24,6 +24,7 @@ enum BlockSource { class ClientModel : public QObject { Q_OBJECT + public: explicit ClientModel(OptionsModel *optionsModel, QObject *parent = 0); ~ClientModel(); @@ -66,6 +67,7 @@ private: void subscribeToCoreSignals(); void unsubscribeFromCoreSignals(); + signals: void numConnectionsChanged(int count); void numBlocksChanged(int count, int countOfPeers); diff --git a/src/qt/csvmodelwriter.h b/src/qt/csvmodelwriter.h index 6c9dcbaf3b..c4504ee91a 100644 --- a/src/qt/csvmodelwriter.h +++ b/src/qt/csvmodelwriter.h @@ -14,6 +14,7 @@ QT_END_NAMESPACE class CSVModelWriter : public QObject { Q_OBJECT + public: explicit CSVModelWriter(const QString &filename, QObject *parent = 0); @@ -36,11 +37,6 @@ private: int role; }; QList<Column> columns; - -signals: - -public slots: - }; #endif // CSVMODELWRITER_H diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp index 5cfcb34b95..9abad7647c 100644 --- a/src/qt/editaddressdialog.cpp +++ b/src/qt/editaddressdialog.cpp @@ -1,5 +1,6 @@ #include "editaddressdialog.h" #include "ui_editaddressdialog.h" + #include "addresstablemodel.h" #include "guiutil.h" diff --git a/src/qt/editaddressdialog.h b/src/qt/editaddressdialog.h index 0e4183bd52..44e5023d25 100644 --- a/src/qt/editaddressdialog.h +++ b/src/qt/editaddressdialog.h @@ -3,15 +3,15 @@ #include <QDialog> -QT_BEGIN_NAMESPACE -class QDataWidgetMapper; -QT_END_NAMESPACE - namespace Ui { class EditAddressDialog; } class AddressTableModel; +QT_BEGIN_NAMESPACE +class QDataWidgetMapper; +QT_END_NAMESPACE + /** Dialog for editing an address and associated information. */ class EditAddressDialog : public QDialog diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 2cbd6435cb..06ccde3782 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -1,11 +1,14 @@ +#include <QApplication> + #include "guiutil.h" + #include "bitcoinaddressvalidator.h" #include "walletmodel.h" #include "bitcoinunits.h" + #include "util.h" #include "init.h" -#include <QString> #include <QDateTime> #include <QDoubleValidator> #include <QFont> @@ -13,7 +16,6 @@ #include <QUrl> #include <QTextDocument> // For Qt::escape #include <QAbstractItemView> -#include <QApplication> #include <QClipboard> #include <QFileDialog> #include <QDesktopServices> diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index db100bdb73..e2c7d18aa2 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -5,6 +5,8 @@ #include <QObject> #include <QMessageBox> +class SendCoinsRecipient; + QT_BEGIN_NAMESPACE class QFont; class QLineEdit; @@ -13,7 +15,6 @@ class QDateTime; class QUrl; class QAbstractItemView; QT_END_NAMESPACE -class SendCoinsRecipient; /** Utility functions used by the Bitcoin Qt UI. */ diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 39062d0a2c..e05c018c27 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -414,16 +414,8 @@ This product includes software developed by the OpenSSL Project for use in the O <source>Reindexing blocks on disk...</source> <translation>Reindexing blocks on disk...</translation> </message> - <message numerus="yes"> - <location line="+10"/> - <source>~%n block(s) remaining</source> - <translation> - <numerusform>~%n block remaining</numerusform> - <numerusform>~%n blocks remaining</numerusform> - </translation> - </message> <message> - <location line="-265"/> + <location line="-255"/> <source>&Export...</source> <translation>&Export...</translation> </message> @@ -469,12 +461,12 @@ This product includes software developed by the OpenSSL Project for use in the O </message> <message> <location line="-196"/> - <location line="+538"/> + <location line="+529"/> <source>Bitcoin</source> <translation>Bitcoin</translation> </message> <message> - <location line="-538"/> + <location line="-529"/> <source>Wallet</source> <translation>Wallet</translation> </message> @@ -553,17 +545,56 @@ This product includes software developed by the OpenSSL Project for use in the O </translation> </message> <message> - <location line="+45"/> - <source>Processed %1 of %2 blocks of transaction history (%3% done).</source> - <translation>Processed %1 of %2 blocks of transaction history (%3% done).</translation> + <location line="+39"/> + <source>Processed %1 of %2 (estimated) blocks of transaction history.</source> + <translation>Processed %1 of %2 (estimated) blocks of transaction history.</translation> </message> <message> - <location line="+7"/> + <location line="+4"/> <source>Processed %1 blocks of transaction history.</source> <translation>Processed %1 blocks of transaction history.</translation> </message> + <message numerus="yes"> + <location line="+20"/> + <source>%n hour(s)</source> + <translation> + <numerusform>%n hour</numerusform> + <numerusform>%n hours</numerusform> + </translation> + </message> + <message numerus="yes"> + <location line="+4"/> + <source>%n day(s)</source> + <translation> + <numerusform>%n day</numerusform> + <numerusform>%n days</numerusform> + </translation> + </message> + <message numerus="yes"> + <location line="+4"/> + <source>%n week(s)</source> + <translation> + <numerusform>%n week</numerusform> + <numerusform>%n weeks</numerusform> + </translation> + </message> <message> - <location line="+70"/> + <location line="+5"/> + <source>%1 behind</source> + <translation>%1 behind</translation> + </message> + <message> + <location line="+14"/> + <source>Last received block was generated %1 ago.</source> + <translation>Last received block was generated %1 ago.</translation> + </message> + <message> + <location line="+2"/> + <source>Transactions after this will not yet be visible.</source> + <translation>Transactions after this will not yet be visible.</translation> + </message> + <message> + <location line="+21"/> <source>Error</source> <translation>Error</translation> </message> @@ -578,7 +609,7 @@ This product includes software developed by the OpenSSL Project for use in the O <translation>Information</translation> </message> <message> - <location line="+66"/> + <location line="+68"/> <source>This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?</source> <translation>This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?</translation> </message> @@ -592,55 +623,18 @@ This product includes software developed by the OpenSSL Project for use in the O <source>The wallet data was successfully saved to the new location.</source> <translation>The wallet data was successfully saved to the new location.</translation> </message> - <message numerus="yes"> - <location line="-338"/> - <source>%n second(s) ago</source> - <translation> - <numerusform>%n second ago</numerusform> - <numerusform>%n seconds ago</numerusform> - </translation> - </message> - <message numerus="yes"> - <location line="+4"/> - <source>%n minute(s) ago</source> - <translation> - <numerusform>%n minute ago</numerusform> - <numerusform>%n minutes ago</numerusform> - </translation> - </message> - <message numerus="yes"> - <location line="+4"/> - <source>%n hour(s) ago</source> - <translation> - <numerusform>%n hour ago</numerusform> - <numerusform>%n hours ago</numerusform> - </translation> - </message> - <message numerus="yes"> - <location line="+4"/> - <source>%n day(s) ago</source> - <translation> - <numerusform>%n day ago</numerusform> - <numerusform>%n days ago</numerusform> - </translation> - </message> <message> - <location line="+6"/> + <location line="-348"/> <source>Up to date</source> <translation>Up to date</translation> </message> <message> - <location line="+7"/> + <location line="+32"/> <source>Catching up...</source> <translation>Catching up...</translation> </message> <message> - <location line="+10"/> - <source>Last received block was generated %1.</source> - <translation>Last received block was generated %1.</translation> - </message> - <message> - <location line="+97"/> + <location line="+110"/> <source>Confirm transaction fee</source> <translation>Confirm transaction fee</translation> </message> @@ -710,7 +704,7 @@ Address: %4 <translation>There was an error trying to save the wallet data to the new location.</translation> </message> <message> - <location filename="../bitcoin.cpp" line="+110"/> + <location filename="../bitcoin.cpp" line="+108"/> <source>A fatal error occurred. Bitcoin can no longer continue safely and will quit.</source> <translation>A fatal error occurred. Bitcoin can no longer continue safely and will quit.</translation> </message> @@ -718,7 +712,7 @@ Address: %4 <context> <name>ClientModel</name> <message> - <location filename="../clientmodel.cpp" line="+89"/> + <location filename="../clientmodel.cpp" line="+96"/> <source>Network Alert</source> <translation>Network Alert</translation> </message> @@ -751,7 +745,7 @@ Address: %4 <translation>The address associated with this address book entry. This can only be modified for sending addresses.</translation> </message> <message> - <location filename="../editaddressdialog.cpp" line="+20"/> + <location filename="../editaddressdialog.cpp" line="+21"/> <source>New receiving address</source> <translation>New receiving address</translation> </message> @@ -794,7 +788,7 @@ Address: %4 <context> <name>GUIUtil::HelpMessageBox</name> <message> - <location filename="../guiutil.cpp" line="+420"/> + <location filename="../guiutil.cpp" line="+422"/> <location line="+12"/> <source>Bitcoin-Qt</source> <translation>Bitcoin-Qt</translation> @@ -1008,7 +1002,7 @@ Address: %4 <translation>&Apply</translation> </message> <message> - <location filename="../optionsdialog.cpp" line="+55"/> + <location filename="../optionsdialog.cpp" line="+53"/> <source>default</source> <translation>default</translation> </message> @@ -1116,6 +1110,14 @@ Address: %4 </message> </context> <context> + <name>PaymentServer</name> + <message> + <location filename="../paymentserver.cpp" line="+107"/> + <source>Cannot start bitcoin: click-to-pay handler</source> + <translation>Cannot start bitcoin: click-to-pay handler</translation> + </message> +</context> +<context> <name>QRCodeDialog</name> <message> <location filename="../forms/qrcodedialog.ui" line="+14"/> @@ -1454,7 +1456,7 @@ Address: %4 </message> <message> <location line="+60"/> - <location filename="../sendcoinsentry.cpp" line="+25"/> + <location filename="../sendcoinsentry.cpp" line="+26"/> <source>Enter a label for this address to add it to your address book</source> <translation>Enter a label for this address to add it to your address book</translation> </message> @@ -1690,7 +1692,7 @@ Address: %4 <context> <name>TransactionDesc</name> <message> - <location filename="../transactiondesc.cpp" line="+19"/> + <location filename="../transactiondesc.cpp" line="+20"/> <source>Open until %1</source> <translation>Open until %1</translation> </message> @@ -1886,7 +1888,7 @@ Address: %4 <context> <name>TransactionTableModel</name> <message> - <location filename="../transactiontablemodel.cpp" line="+226"/> + <location filename="../transactiontablemodel.cpp" line="+225"/> <source>Date</source> <translation>Date</translation> </message> @@ -2010,7 +2012,7 @@ Address: %4 <context> <name>TransactionView</name> <message> - <location filename="../transactionview.cpp" line="+55"/> + <location filename="../transactionview.cpp" line="+52"/> <location line="+16"/> <source>All</source> <translation>All</translation> @@ -2106,7 +2108,7 @@ Address: %4 <translation>Show transaction details</translation> </message> <message> - <location line="+142"/> + <location line="+137"/> <source>Export Transaction Data</source> <translation>Export Transaction Data</translation> </message> @@ -2174,12 +2176,12 @@ Address: %4 <context> <name>bitcoin-core</name> <message> - <location filename="../bitcoinstrings.cpp" line="+90"/> + <location filename="../bitcoinstrings.cpp" line="+91"/> <source>Bitcoin version</source> <translation>Bitcoin version</translation> </message> <message> - <location line="+96"/> + <location line="+99"/> <source>Usage:</source> <translation>Usage:</translation> </message> @@ -2219,12 +2221,12 @@ Address: %4 <translation>Generate coins</translation> </message> <message> - <location line="-27"/> + <location line="-28"/> <source>Don't generate coins</source> <translation>Don't generate coins</translation> </message> <message> - <location line="+74"/> + <location line="+75"/> <source>Specify data directory</source> <translation>Specify data directory</translation> </message> @@ -2244,12 +2246,12 @@ Address: %4 <translation>Maintain at most <n> connections to peers (default: 125)</translation> </message> <message> - <location line="-47"/> + <location line="-50"/> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Connect to a node to retrieve peer addresses, and disconnect</translation> </message> <message> - <location line="+78"/> + <location line="+81"/> <source>Specify your own public address</source> <translation>Specify your own public address</translation> </message> @@ -2259,17 +2261,17 @@ Address: %4 <translation>Threshold for disconnecting misbehaving peers (default: 100)</translation> </message> <message> - <location line="-130"/> + <location line="-133"/> <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> <translation>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</translation> </message> <message> - <location line="-28"/> + <location line="-29"/> <source>An error occurred while setting up the RPC port %u for listening on IPv4: %s</source> <translation>An error occurred while setting up the RPC port %u for listening on IPv4: %s</translation> </message> <message> - <location line="+26"/> + <location line="+27"/> <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> <translation>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</translation> </message> @@ -2279,7 +2281,7 @@ Address: %4 <translation>Accept command line and JSON-RPC commands</translation> </message> <message> - <location line="+75"/> + <location line="+78"/> <source>Run in the background as a daemon and accept commands</source> <translation>Run in the background as a daemon and accept commands</translation> </message> @@ -2289,12 +2291,12 @@ Address: %4 <translation>Use the test network</translation> </message> <message> - <location line="-106"/> + <location line="-109"/> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Accept connections from outside (default: 1 if no -proxy or -connect)</translation> </message> <message> - <location line="-76"/> + <location line="-77"/> <source>%s, you must set a rpcpassword in the configuration file: %s It is recommended you use the following random password: @@ -2330,11 +2332,6 @@ If the file does not exist, create it with owner-readable-only file permissions. </message> <message> <location line="+3"/> - <source>Corrupted block database detected. Please restart the client with -reindex.</source> - <translation>Corrupted block database detected. Please restart the client with -reindex.</translation> - </message> - <message> - <location line="+2"/> <source>Error initializing database environment %s! To recover, BACKUP THAT DIRECTORY, then remove everything from it except for wallet.dat.</source> <translation>Error initializing database environment %s! To recover, BACKUP THAT DIRECTORY, then remove everything from it except for wallet.dat.</translation> </message> @@ -2349,6 +2346,11 @@ If the file does not exist, create it with owner-readable-only file permissions. <translation>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</translation> </message> <message> + <location line="+3"/> + <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> + <translation>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</translation> + </message> + <message> <location line="+11"/> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: 27000)</source> <translation>Set maximum size of high-priority/low-fee transactions in bytes (default: 27000)</translation> @@ -2405,10 +2407,20 @@ If the file does not exist, create it with owner-readable-only file permissions. </message> <message> <location line="+3"/> + <source>Corrupted block database detected</source> + <translation>Corrupted block database detected</translation> + </message> + <message> + <location line="+1"/> <source>Discover own IP address (default: 1 when listening and no -externalip)</source> <translation>Discover own IP address (default: 1 when listening and no -externalip)</translation> </message> <message> + <location line="+1"/> + <source>Do you want to rebuild the block database now?</source> + <translation>Do you want to rebuild the block database now?</translation> + </message> + <message> <location line="+3"/> <source>Error initializing block database</source> <translation>Error initializing block database</translation> @@ -2419,7 +2431,12 @@ If the file does not exist, create it with owner-readable-only file permissions. <translation>Error loading block database</translation> </message> <message> - <location line="+5"/> + <location line="+4"/> + <source>Error opening block database</source> + <translation>Error opening block database</translation> + </message> + <message> + <location line="+2"/> <source>Error: Disk space is low!</source> <translation>Error: Disk space is low!</translation> </message> @@ -2639,7 +2656,12 @@ If the file does not exist, create it with owner-readable-only file permissions. <translation>Username for JSON-RPC connections</translation> </message> <message> - <location line="+4"/> + <location line="+1"/> + <source>Verifying database...</source> + <translation>Verifying database...</translation> + </message> + <message> + <location line="+3"/> <source>Warning</source> <translation>Warning</translation> </message> @@ -2664,22 +2686,22 @@ If the file does not exist, create it with owner-readable-only file permissions. <translation>Password for JSON-RPC connections</translation> </message> <message> - <location line="-66"/> + <location line="-69"/> <source>Allow JSON-RPC connections from specified IP address</source> <translation>Allow JSON-RPC connections from specified IP address</translation> </message> <message> - <location line="+75"/> + <location line="+78"/> <source>Send commands to node running on <ip> (default: 127.0.0.1)</source> <translation>Send commands to node running on <ip> (default: 127.0.0.1)</translation> </message> <message> - <location line="-118"/> + <location line="-121"/> <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source> <translation>Execute command when the best block changes (%s in cmd is replaced by block hash)</translation> </message> <message> - <location line="+140"/> + <location line="+143"/> <source>Upgrade wallet to latest format</source> <translation>Upgrade wallet to latest format</translation> </message> @@ -2709,12 +2731,12 @@ If the file does not exist, create it with owner-readable-only file permissions. <translation>Server private key (default: server.pem)</translation> </message> <message> - <location line="-148"/> + <location line="-152"/> <source>Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</source> <translation>Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</translation> </message> <message> - <location line="+160"/> + <location line="+164"/> <source>This help message</source> <translation>This help message</translation> </message> @@ -2724,7 +2746,7 @@ If the file does not exist, create it with owner-readable-only file permissions. <translation>Unable to bind to %s on this computer (bind returned error %d, %s)</translation> </message> <message> - <location line="-84"/> + <location line="-87"/> <source>Connect through socks proxy</source> <translation>Connect through socks proxy</translation> </message> @@ -2734,12 +2756,12 @@ If the file does not exist, create it with owner-readable-only file permissions. <translation>Allow DNS lookups for -addnode, -seednode and -connect</translation> </message> <message> - <location line="+55"/> + <location line="+58"/> <source>Loading addresses...</source> <translation>Loading addresses...</translation> </message> <message> - <location line="-36"/> + <location line="-37"/> <source>Error loading wallet.dat: Wallet corrupted</source> <translation>Error loading wallet.dat: Wallet corrupted</translation> </message> @@ -2749,12 +2771,7 @@ If the file does not exist, create it with owner-readable-only file permissions. <translation>Error loading wallet.dat: Wallet requires newer version of Bitcoin</translation> </message> <message> - <location line="+86"/> - <source>Verifying block database integrity...</source> - <translation>Verifying block database integrity...</translation> - </message> - <message> - <location line="+1"/> + <location line="+88"/> <source>Verifying wallet integrity...</source> <translation>Verifying wallet integrity...</translation> </message> @@ -2764,12 +2781,12 @@ If the file does not exist, create it with owner-readable-only file permissions. <translation>Wallet needed to be rewritten: restart Bitcoin to complete</translation> </message> <message> - <location line="-90"/> + <location line="-91"/> <source>Error loading wallet.dat</source> <translation>Error loading wallet.dat</translation> </message> <message> - <location line="+31"/> + <location line="+32"/> <source>Invalid -proxy address: '%s'</source> <translation>Invalid -proxy address: '%s'</translation> </message> @@ -2784,7 +2801,7 @@ If the file does not exist, create it with owner-readable-only file permissions. <translation>Unknown -socks proxy version requested: %i</translation> </message> <message> - <location line="-89"/> + <location line="-92"/> <source>Cannot resolve -bind address: '%s'</source> <translation>Cannot resolve -bind address: '%s'</translation> </message> @@ -2794,7 +2811,7 @@ If the file does not exist, create it with owner-readable-only file permissions. <translation>Cannot resolve -externalip address: '%s'</translation> </message> <message> - <location line="+43"/> + <location line="+46"/> <source>Invalid amount for -paytxfee=<amount>: '%s'</source> <translation>Invalid amount for -paytxfee=<amount>: '%s'</translation> </message> @@ -2819,7 +2836,7 @@ If the file does not exist, create it with owner-readable-only file permissions. <translation>Loading block index...</translation> </message> <message> - <location line="-57"/> + <location line="-60"/> <source>Add a node to connect to and attempt to keep the connection open</source> <translation>Add a node to connect to and attempt to keep the connection open</translation> </message> @@ -2829,7 +2846,7 @@ If the file does not exist, create it with owner-readable-only file permissions. <translation>Unable to bind to %s on this computer. Bitcoin is probably already running.</translation> </message> <message> - <location line="+66"/> + <location line="+69"/> <source>Find peers using internet relay chat (default: 0)</source> <translation>Find peers using internet relay chat (default: 0)</translation> </message> @@ -2844,7 +2861,7 @@ If the file does not exist, create it with owner-readable-only file permissions. <translation>Loading wallet...</translation> </message> <message> - <location line="-52"/> + <location line="-55"/> <source>Cannot downgrade wallet</source> <translation>Cannot downgrade wallet</translation> </message> @@ -2859,17 +2876,17 @@ If the file does not exist, create it with owner-readable-only file permissions. <translation>Cannot write default address</translation> </message> <message> - <location line="+62"/> + <location line="+65"/> <source>Rescanning...</source> <translation>Rescanning...</translation> </message> <message> - <location line="-56"/> + <location line="-57"/> <source>Done loading</source> <translation>Done loading</translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>To use the %s option</source> <translation>To use the %s option</translation> </message> @@ -2879,7 +2896,7 @@ If the file does not exist, create it with owner-readable-only file permissions. <translation>Error</translation> </message> <message> - <location line="-29"/> + <location line="-32"/> <source>You must set rpcpassword=<password> in the configuration file: %s If the file does not exist, create it with owner-readable-only file permissions.</source> diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h index dd85e0c33d..5018456aa1 100644 --- a/src/qt/macdockiconhandler.h +++ b/src/qt/macdockiconhandler.h @@ -3,9 +3,11 @@ #include <QObject> +QT_BEGIN_NAMESPACE class QMenu; class QIcon; class QWidget; +QT_END_NAMESPACE #ifdef __OBJC__ @class DockIconClickEventHandler; @@ -18,6 +20,7 @@ class DockIconClickEventHandler; class MacDockIconHandler : public QObject { Q_OBJECT + public: ~MacDockIconHandler(); @@ -31,8 +34,6 @@ public: signals: void dockIconClicked(); -public slots: - private: MacDockIconHandler(); diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index 75684403eb..ea868401c0 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -1,4 +1,3 @@ - #include "macdockiconhandler.h" #include <QMenu> diff --git a/src/qt/monitoreddatamapper.cpp b/src/qt/monitoreddatamapper.cpp index 88948d07bf..4c201834cb 100644 --- a/src/qt/monitoreddatamapper.cpp +++ b/src/qt/monitoreddatamapper.cpp @@ -9,7 +9,6 @@ MonitoredDataMapper::MonitoredDataMapper(QObject *parent) : { } - void MonitoredDataMapper::addMapping(QWidget *widget, int section) { QDataWidgetMapper::addMapping(widget, section); diff --git a/src/qt/monitoreddatamapper.h b/src/qt/monitoreddatamapper.h index 33a874e73a..de55c86fcd 100644 --- a/src/qt/monitoreddatamapper.h +++ b/src/qt/monitoreddatamapper.h @@ -13,19 +13,18 @@ QT_END_NAMESPACE class MonitoredDataMapper : public QDataWidgetMapper { Q_OBJECT + public: explicit MonitoredDataMapper(QObject *parent=0); void addMapping(QWidget *widget, int section); void addMapping(QWidget *widget, int section, const QByteArray &propertyName); + private: void addChangeMonitor(QWidget *widget); signals: void viewModified(); - }; - - #endif // MONITOREDDATAMAPPER_H diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp index 628dca1591..397e7aa4a0 100644 --- a/src/qt/notificator.cpp +++ b/src/qt/notificator.cpp @@ -12,7 +12,7 @@ #include <QImageWriter> #ifdef USE_DBUS -#include <QtDBus/QtDBus> +#include <QtDBus> #include <stdint.h> #endif diff --git a/src/qt/notificator.h b/src/qt/notificator.h index 833b52cb15..d20673abb6 100644 --- a/src/qt/notificator.h +++ b/src/qt/notificator.h @@ -15,6 +15,7 @@ QT_END_NAMESPACE class Notificator: public QObject { Q_OBJECT + public: /** Create a new notificator. @note Ownership of trayIcon is not transferred to this object. @@ -25,13 +26,12 @@ public: // Message class enum Class { - Information, /**< Informational message */ - Warning, /**< Notify user of potential problem */ - Critical /**< An error occurred */ + Information, /**< Informational message */ + Warning, /**< Notify user of potential problem */ + Critical /**< An error occurred */ }; public slots: - /** Show notification message. @param[in] cls general message class @param[in] title title shown with message diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 6b98ab1929..4fa1f60922 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -10,8 +10,6 @@ #include <QIntValidator> #include <QLocale> #include <QMessageBox> -#include <QRegExp> -#include <QRegExpValidator> OptionsDialog::OptionsDialog(QWidget *parent) : QDialog(parent), diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 2457e38742..cd3170a306 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -1,11 +1,12 @@ #include "optionsmodel.h" -#include "bitcoinunits.h" -#include <QSettings> +#include "bitcoinunits.h" #include "init.h" #include "walletdb.h" #include "guiutil.h" +#include <QSettings> + OptionsModel::OptionsModel(QObject *parent) : QAbstractListModel(parent) { diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index bb32a0c33f..b287f479f8 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -3,10 +3,6 @@ #include <QWidget> -QT_BEGIN_NAMESPACE -class QModelIndex; -QT_END_NAMESPACE - namespace Ui { class OverviewPage; } @@ -15,6 +11,10 @@ class WalletModel; class TxViewDelegate; class TransactionFilterProxy; +QT_BEGIN_NAMESPACE +class QModelIndex; +QT_END_NAMESPACE + /** Overview ("home") page widget */ class OverviewPage : public QWidget { diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 05f2ac10e4..a92e6fc329 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -2,14 +2,15 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <QApplication> + #include "paymentserver.h" + #include "guiconstants.h" #include "ui_interface.h" #include "util.h" -#include <QApplication> #include <QByteArray> -#include <QCoreApplication> #include <QDataStream> #include <QDebug> #include <QFileOpenEvent> @@ -59,7 +60,7 @@ bool PaymentServer::ipcSendCommandLine() { bool fResult = false; - const QStringList& args = QCoreApplication::arguments(); + const QStringList& args = qApp->arguments(); for (int i = 1; i < args.size(); i++) { if (!args[i].startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) diff --git a/src/qt/qvalidatedlineedit.h b/src/qt/qvalidatedlineedit.h index 66e26be9a3..ec74633c02 100644 --- a/src/qt/qvalidatedlineedit.h +++ b/src/qt/qvalidatedlineedit.h @@ -9,6 +9,7 @@ class QValidatedLineEdit : public QLineEdit { Q_OBJECT + public: explicit QValidatedLineEdit(QWidget *parent = 0); void clear(); diff --git a/src/qt/qvaluecombobox.h b/src/qt/qvaluecombobox.h index 1a47bb6565..64a7da9df5 100644 --- a/src/qt/qvaluecombobox.h +++ b/src/qt/qvaluecombobox.h @@ -8,7 +8,9 @@ class QValueComboBox : public QComboBox { Q_OBJECT + Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged USER true) + public: explicit QValueComboBox(QWidget *parent = 0); @@ -21,8 +23,6 @@ public: signals: void valueChanged(); -public slots: - private: int role; diff --git a/src/qt/res/bitcoin-qt.rc b/src/qt/res/bitcoin-qt.rc index 834001c0c6..5449ff8359 100644 --- a/src/qt/res/bitcoin-qt.rc +++ b/src/qt/res/bitcoin-qt.rc @@ -22,7 +22,7 @@ BEGIN VALUE "FileDescription", "Bitcoin-Qt (OSS GUI client for Bitcoin)" VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "bitcoin-qt" - VALUE "LegalCopyright", "2009-2012 The Bitcoin developers" + VALUE "LegalCopyright", "2009-2013 The Bitcoin developers" VALUE "LegalTrademarks1", "Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." VALUE "OriginalFilename", "bitcoin-qt.exe" VALUE "ProductName", "Bitcoin-Qt" diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 7cf2d41962..c9ce374346 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -6,9 +6,7 @@ #include "guiutil.h" #include <QTime> -#include <QTimer> #include <QThread> -#include <QTextEdit> #include <QKeyEvent> #include <QUrl> #include <QScrollBar> @@ -35,12 +33,14 @@ const struct { /* Object for executing console RPC commands in a separate thread. */ -class RPCExecutor: public QObject +class RPCExecutor : public QObject { Q_OBJECT + public slots: void start(); void request(const QString &command); + signals: void reply(int category, const QString &command); }; diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 0c1547bd8e..2133a5e729 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -1,5 +1,6 @@ #include "sendcoinsdialog.h" #include "ui_sendcoinsdialog.h" + #include "walletmodel.h" #include "bitcoinunits.h" #include "addressbookpage.h" @@ -10,7 +11,6 @@ #include "base58.h" #include <QMessageBox> -#include <QLocale> #include <QTextDocument> #include <QScrollBar> @@ -245,6 +245,26 @@ QWidget *SendCoinsDialog::setupTabChain(QWidget *prev) return ui->sendButton; } +void SendCoinsDialog::setAddress(const QString &address) +{ + SendCoinsEntry *entry = 0; + // Replace the first entry if it is still unused + if(ui->entries->count() == 1) + { + SendCoinsEntry *first = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(0)->widget()); + if(first->isClear()) + { + entry = first; + } + } + if(!entry) + { + entry = addEntry(); + } + + entry->setAddress(address); +} + void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv) { if(!fNewRecipientAllowed) diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 8a6e050c11..043dfdcb40 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -29,6 +29,7 @@ public: */ QWidget *setupTabChain(QWidget *prev); + void setAddress(const QString &address); void pasteEntry(const SendCoinsRecipient &rv); bool handleURI(const QString &uri); diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index c4d84c388c..876b7f808b 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -1,5 +1,6 @@ #include "sendcoinsentry.h" #include "ui_sendcoinsentry.h" + #include "guiutil.h" #include "bitcoinunits.h" #include "addressbookpage.h" @@ -152,6 +153,12 @@ void SendCoinsEntry::setValue(const SendCoinsRecipient &value) ui->payAmount->setValue(value.amount); } +void SendCoinsEntry::setAddress(const QString &address) +{ + ui->payTo->setText(address); + ui->payAmount->setFocus(); +} + bool SendCoinsEntry::isClear() { return ui->payTo->text().isEmpty(); diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h index 0ac14c1472..ec5f3410c1 100644 --- a/src/qt/sendcoinsentry.h +++ b/src/qt/sendcoinsentry.h @@ -26,6 +26,7 @@ public: bool isClear(); void setValue(const SendCoinsRecipient &value); + void setAddress(const QString &address); /** Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907). */ diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 371b5ba535..7c43e5839e 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -10,11 +10,11 @@ #include "walletmodel.h" #include "wallet.h" +#include <QClipboard> + #include <string> #include <vector> -#include <QClipboard> - SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) : QDialog(parent), ui(new Ui::SignVerifyMessageDialog), diff --git a/src/qt/signverifymessagedialog.h b/src/qt/signverifymessagedialog.h index 2c2677cc0c..558f24e232 100644 --- a/src/qt/signverifymessagedialog.h +++ b/src/qt/signverifymessagedialog.h @@ -8,9 +8,6 @@ namespace Ui { } class WalletModel; -QT_BEGIN_NAMESPACE -QT_END_NAMESPACE - class SignVerifyMessageDialog : public QDialog { Q_OBJECT diff --git a/src/qt/test/uritests.cpp b/src/qt/test/uritests.cpp index 4662f5ed31..802d74719e 100644 --- a/src/qt/test/uritests.cpp +++ b/src/qt/test/uritests.cpp @@ -4,15 +4,6 @@ #include <QUrl> -/* -struct SendCoinsRecipient -{ - QString address; - QString label; - qint64 amount; -}; -*/ - void URITests::uriTests() { SendCoinsRecipient rv; diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index d5b08448dd..e4dbf9c0d9 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -2,13 +2,14 @@ #include "guiutil.h" #include "bitcoinunits.h" - #include "main.h" #include "wallet.h" #include "db.h" #include "ui_interface.h" #include "base58.h" +#include <string> + QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx) { if (!wtx.IsFinal()) diff --git a/src/qt/transactiondesc.h b/src/qt/transactiondesc.h index 2523f9aa69..cb0dda5b58 100644 --- a/src/qt/transactiondesc.h +++ b/src/qt/transactiondesc.h @@ -3,7 +3,6 @@ #include <QString> #include <QObject> -#include <string> class CWallet; class CWalletTx; @@ -13,8 +12,10 @@ class CWalletTx; class TransactionDesc: public QObject { Q_OBJECT + public: static QString toHTML(CWallet *wallet, CWalletTx &wtx); + private: TransactionDesc() {} diff --git a/src/qt/transactiondescdialog.h b/src/qt/transactiondescdialog.h index e86fb58a64..f7ceacb63d 100644 --- a/src/qt/transactiondescdialog.h +++ b/src/qt/transactiondescdialog.h @@ -6,6 +6,7 @@ namespace Ui { class TransactionDescDialog; } + QT_BEGIN_NAMESPACE class QModelIndex; QT_END_NAMESPACE diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp index 16fb4dab92..068e5550d2 100644 --- a/src/qt/transactionfilterproxy.cpp +++ b/src/qt/transactionfilterproxy.cpp @@ -1,4 +1,5 @@ #include "transactionfilterproxy.h" + #include "transactiontablemodel.h" #include <QDateTime> diff --git a/src/qt/transactionfilterproxy.h b/src/qt/transactionfilterproxy.h index 30b98588f0..1aea85a005 100644 --- a/src/qt/transactionfilterproxy.h +++ b/src/qt/transactionfilterproxy.h @@ -8,6 +8,7 @@ class TransactionFilterProxy : public QSortFilterProxyModel { Q_OBJECT + public: explicit TransactionFilterProxy(QObject *parent = 0); @@ -32,6 +33,7 @@ public: void setLimit(int limit); int rowCount(const QModelIndex &parent = QModelIndex()) const; + protected: bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const; @@ -42,11 +44,6 @@ private: quint32 typeFilter; qint64 minAmount; int limitRows; - -signals: - -public slots: - }; #endif // TRANSACTIONFILTERPROXY_H diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index f6570803de..d760d47c89 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -14,8 +14,8 @@ class TransactionStatus { public: TransactionStatus(): - confirmed(false), sortKey(""), maturity(Mature), - matures_in(0), status(Offline), depth(0), open_for(0), cur_num_blocks(-1) + confirmed(false), sortKey(""), maturity(Mature), + matures_in(0), status(Offline), depth(0), open_for(0), cur_num_blocks(-1) { } enum Maturity diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index aef0e409bd..baf1e16483 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -1,4 +1,5 @@ #include "transactiontablemodel.h" + #include "guiutil.h" #include "transactionrecord.h" #include "guiconstants.h" @@ -11,13 +12,11 @@ #include "wallet.h" #include "ui_interface.h" -#include <QLocale> #include <QList> #include <QColor> #include <QTimer> #include <QIcon> #include <QDateTime> -#include <QtAlgorithms> // Amount column is right-aligned it contains numbers static int column_alignments[] = { diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index b0687d5399..6b2961c285 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -14,6 +14,7 @@ class WalletModel; class TransactionTableModel : public QAbstractTableModel { Q_OBJECT + public: explicit TransactionTableModel(CWallet* wallet, WalletModel *parent = 0); ~TransactionTableModel(); @@ -55,6 +56,7 @@ public: QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const; + private: CWallet* wallet; WalletModel *walletModel; diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 7acf5deaa3..9240b71c71 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -20,12 +20,9 @@ #include <QLineEdit> #include <QTableView> #include <QHeaderView> -#include <QPushButton> #include <QMessageBox> #include <QPoint> #include <QMenu> -#include <QApplication> -#include <QClipboard> #include <QLabel> #include <QDateTimeEdit> @@ -126,6 +123,7 @@ TransactionView::TransactionView(QWidget *parent) : QAction *copyAddressAction = new QAction(tr("Copy address"), this); QAction *copyLabelAction = new QAction(tr("Copy label"), this); QAction *copyAmountAction = new QAction(tr("Copy amount"), this); + QAction *copyTxIDAction = new QAction(tr("Copy transaction ID"), this); QAction *editLabelAction = new QAction(tr("Edit label"), this); QAction *showDetailsAction = new QAction(tr("Show transaction details"), this); @@ -133,6 +131,7 @@ TransactionView::TransactionView(QWidget *parent) : contextMenu->addAction(copyAddressAction); contextMenu->addAction(copyLabelAction); contextMenu->addAction(copyAmountAction); + contextMenu->addAction(copyTxIDAction); contextMenu->addAction(editLabelAction); contextMenu->addAction(showDetailsAction); @@ -148,6 +147,7 @@ TransactionView::TransactionView(QWidget *parent) : connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress())); connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel())); connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount())); + connect(copyTxIDAction, SIGNAL(triggered()), this, SLOT(copyTxID())); connect(editLabelAction, SIGNAL(triggered()), this, SLOT(editLabel())); connect(showDetailsAction, SIGNAL(triggered()), this, SLOT(showDetails())); } @@ -173,16 +173,11 @@ void TransactionView::setModel(WalletModel *model) transactionView->sortByColumn(TransactionTableModel::Status, Qt::DescendingOrder); transactionView->verticalHeader()->hide(); - transactionView->horizontalHeader()->resizeSection( - TransactionTableModel::Status, 23); - transactionView->horizontalHeader()->resizeSection( - TransactionTableModel::Date, 120); - transactionView->horizontalHeader()->resizeSection( - TransactionTableModel::Type, 120); - transactionView->horizontalHeader()->setResizeMode( - TransactionTableModel::ToAddress, QHeaderView::Stretch); - transactionView->horizontalHeader()->resizeSection( - TransactionTableModel::Amount, 100); + transactionView->horizontalHeader()->resizeSection(TransactionTableModel::Status, 23); + transactionView->horizontalHeader()->resizeSection(TransactionTableModel::Date, 120); + transactionView->horizontalHeader()->resizeSection(TransactionTableModel::Type, 120); + transactionView->horizontalHeader()->setResizeMode(TransactionTableModel::ToAddress, QHeaderView::Stretch); + transactionView->horizontalHeader()->resizeSection(TransactionTableModel::Amount, 100); } } @@ -317,6 +312,11 @@ void TransactionView::copyAmount() GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::FormattedAmountRole); } +void TransactionView::copyTxID() +{ + GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxIDRole); +} + void TransactionView::editLabel() { if(!transactionView->selectionModel() ||!model) diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index 4ade3ecd5f..bb41a83e32 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -22,6 +22,7 @@ QT_END_NAMESPACE class TransactionView : public QWidget { Q_OBJECT + public: explicit TransactionView(QWidget *parent = 0); @@ -65,6 +66,7 @@ private slots: void editLabel(); void copyLabel(); void copyAmount(); + void copyTxID(); signals: void doubleClicked(const QModelIndex&); diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index fd5c8c4d4f..f14b09effe 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -26,6 +26,7 @@ public: class WalletModel : public QObject { Q_OBJECT + public: explicit WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0); ~WalletModel(); @@ -161,5 +162,4 @@ public slots: void pollBalanceChanged(); }; - #endif // WALLETMODEL_H diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp new file mode 100644 index 0000000000..3cfb6dbfa4 --- /dev/null +++ b/src/test/checkblock_tests.cpp @@ -0,0 +1,66 @@ +// +// Unit tests for block.CheckBlock() +// +#include <algorithm> + +#include <boost/assign/list_of.hpp> // for 'map_list_of()' +#include <boost/date_time/posix_time/posix_time_types.hpp> +#include <boost/test/unit_test.hpp> +#include <boost/foreach.hpp> + +#include "main.h" +#include "wallet.h" +#include "net.h" +#include "util.h" + +BOOST_AUTO_TEST_SUITE(CheckBlock_tests) + +bool +read_block(const std::string& filename, CBlock& block) +{ + namespace fs = boost::filesystem; + fs::path testFile = fs::current_path() / "test" / "data" / filename; +#ifdef TEST_DATA_DIR + if (!fs::exists(testFile)) + { + testFile = fs::path(BOOST_PP_STRINGIZE(TEST_DATA_DIR)) / filename; + } +#endif + FILE* fp = fopen(testFile.string().c_str(), "rb"); + if (!fp) return false; + + fseek(fp, 8, SEEK_SET); // skip msgheader/size + + CAutoFile filein = CAutoFile(fp, SER_DISK, CLIENT_VERSION); + if (!filein) return false; + + filein >> block; + + return true; +} + +BOOST_AUTO_TEST_CASE(May15) +{ + // Putting a 1MB binary file in the git repository is not a great + // idea, so this test is only run if you manually download + // test/data/Mar12Fork.dat from + // http://sourceforge.net/projects/bitcoin/files/Bitcoin/blockchain/Mar12Fork.dat/download + unsigned int tMay15 = 1368576000; + SetMockTime(tMay15); // Test as if it was right at May 15 + + CBlock forkingBlock; + if (read_block("Mar12Fork.dat", forkingBlock)) + { + CValidationState state; + forkingBlock.nTime = tMay15-1; // Invalidates PoW + BOOST_CHECK(!forkingBlock.CheckBlock(state, false, false)); + + // After May 15'th, big blocks are OK: + forkingBlock.nTime = tMay15; // Invalidates PoW + BOOST_CHECK(forkingBlock.CheckBlock(state, false, false)); + } + + SetMockTime(0); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index d413eaee8d..95664226c5 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -39,6 +39,9 @@ ["1", "RETURN"], ["1", "DUP IF RETURN ENDIF"], +["1", "RETURN 'data'", "canonical prunable txout format"], +["0 IF", "RETURN ENDIF 1", "still prunable because IF/ENDIF can't span scriptSig/scriptPubKey"], + ["0", "VERIFY 1"], ["1", "VERIFY"], ["1", "VERIFY 0"], @@ -128,13 +131,79 @@ ["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL"], ["0x50","1", "opcode 0x50 is reserved"], -["1", "IF 0xba ELSE 1 ENDIF", "opcodes above NOP10 invalid"], +["1", "IF 0xba ELSE 1 ENDIF", "opcodes above NOP10 invalid if executed"], +["1", "IF 0xbb ELSE 1 ENDIF"], +["1", "IF 0xbc ELSE 1 ENDIF"], +["1", "IF 0xbd ELSE 1 ENDIF"], +["1", "IF 0xbe ELSE 1 ENDIF"], +["1", "IF 0xbf ELSE 1 ENDIF"], ["1", "IF 0xc0 ELSE 1 ENDIF"], +["1", "IF 0xc1 ELSE 1 ENDIF"], +["1", "IF 0xc2 ELSE 1 ENDIF"], +["1", "IF 0xc3 ELSE 1 ENDIF"], +["1", "IF 0xc4 ELSE 1 ENDIF"], +["1", "IF 0xc5 ELSE 1 ENDIF"], +["1", "IF 0xc6 ELSE 1 ENDIF"], +["1", "IF 0xc7 ELSE 1 ENDIF"], +["1", "IF 0xc8 ELSE 1 ENDIF"], +["1", "IF 0xc9 ELSE 1 ENDIF"], +["1", "IF 0xca ELSE 1 ENDIF"], +["1", "IF 0xcb ELSE 1 ENDIF"], +["1", "IF 0xcc ELSE 1 ENDIF"], +["1", "IF 0xcd ELSE 1 ENDIF"], +["1", "IF 0xce ELSE 1 ENDIF"], +["1", "IF 0xcf ELSE 1 ENDIF"], +["1", "IF 0xd0 ELSE 1 ENDIF"], ["1", "IF 0xd1 ELSE 1 ENDIF"], +["1", "IF 0xd2 ELSE 1 ENDIF"], +["1", "IF 0xd3 ELSE 1 ENDIF"], +["1", "IF 0xd4 ELSE 1 ENDIF"], +["1", "IF 0xd5 ELSE 1 ENDIF"], +["1", "IF 0xd6 ELSE 1 ENDIF"], +["1", "IF 0xd7 ELSE 1 ENDIF"], +["1", "IF 0xd8 ELSE 1 ENDIF"], +["1", "IF 0xd9 ELSE 1 ENDIF"], +["1", "IF 0xda ELSE 1 ENDIF"], +["1", "IF 0xdb ELSE 1 ENDIF"], +["1", "IF 0xdc ELSE 1 ENDIF"], +["1", "IF 0xdd ELSE 1 ENDIF"], +["1", "IF 0xde ELSE 1 ENDIF"], +["1", "IF 0xdf ELSE 1 ENDIF"], +["1", "IF 0xe0 ELSE 1 ENDIF"], +["1", "IF 0xe1 ELSE 1 ENDIF"], +["1", "IF 0xe2 ELSE 1 ENDIF"], +["1", "IF 0xe3 ELSE 1 ENDIF"], +["1", "IF 0xe4 ELSE 1 ENDIF"], +["1", "IF 0xe5 ELSE 1 ENDIF"], +["1", "IF 0xe6 ELSE 1 ENDIF"], +["1", "IF 0xe7 ELSE 1 ENDIF"], +["1", "IF 0xe8 ELSE 1 ENDIF"], +["1", "IF 0xe9 ELSE 1 ENDIF"], +["1", "IF 0xea ELSE 1 ENDIF"], +["1", "IF 0xeb ELSE 1 ENDIF"], +["1", "IF 0xec ELSE 1 ENDIF"], +["1", "IF 0xed ELSE 1 ENDIF"], ["1", "IF 0xee ELSE 1 ENDIF"], +["1", "IF 0xef ELSE 1 ENDIF"], +["1", "IF 0xf0 ELSE 1 ENDIF"], +["1", "IF 0xf1 ELSE 1 ENDIF"], +["1", "IF 0xf2 ELSE 1 ENDIF"], +["1", "IF 0xf3 ELSE 1 ENDIF"], +["1", "IF 0xf4 ELSE 1 ENDIF"], +["1", "IF 0xf5 ELSE 1 ENDIF"], +["1", "IF 0xf6 ELSE 1 ENDIF"], +["1", "IF 0xf7 ELSE 1 ENDIF"], +["1", "IF 0xf8 ELSE 1 ENDIF"], +["1", "IF 0xf9 ELSE 1 ENDIF"], +["1", "IF 0xfa ELSE 1 ENDIF"], +["1", "IF 0xfb ELSE 1 ENDIF"], +["1", "IF 0xfc ELSE 1 ENDIF"], ["1", "IF 0xfd ELSE 1 ENDIF"], +["1", "IF 0xfe ELSE 1 ENDIF"], ["1", "IF 0xff ELSE 1 ENDIF"], +["1 IF 1 ELSE", "0xff ENDIF", "invalid because scriptSig and scriptPubKey are processed separately"], + ["NOP", "RIPEMD160"], ["NOP", "SHA1"], ["NOP", "SHA256"], diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index c33a3c7c66..58682d3875 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -34,6 +34,8 @@ ["1 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], ["0 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], +["0", "IF RETURN ENDIF 1", "RETURN only works if executed"], + ["1 1", "VERIFY"], ["10 0 11 TOALTSTACK DROP FROMALTSTACK", "ADD 21 EQUAL"], @@ -188,10 +190,74 @@ ["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL"], ["0", "IF 0xba ELSE 1 ENDIF", "opcodes above NOP10 invalid if executed"], +["0", "IF 0xbb ELSE 1 ENDIF"], +["0", "IF 0xbc ELSE 1 ENDIF"], +["0", "IF 0xbd ELSE 1 ENDIF"], +["0", "IF 0xbe ELSE 1 ENDIF"], +["0", "IF 0xbf ELSE 1 ENDIF"], ["0", "IF 0xc0 ELSE 1 ENDIF"], +["0", "IF 0xc1 ELSE 1 ENDIF"], +["0", "IF 0xc2 ELSE 1 ENDIF"], +["0", "IF 0xc3 ELSE 1 ENDIF"], +["0", "IF 0xc4 ELSE 1 ENDIF"], +["0", "IF 0xc5 ELSE 1 ENDIF"], +["0", "IF 0xc6 ELSE 1 ENDIF"], +["0", "IF 0xc7 ELSE 1 ENDIF"], +["0", "IF 0xc8 ELSE 1 ENDIF"], +["0", "IF 0xc9 ELSE 1 ENDIF"], +["0", "IF 0xca ELSE 1 ENDIF"], +["0", "IF 0xcb ELSE 1 ENDIF"], +["0", "IF 0xcc ELSE 1 ENDIF"], +["0", "IF 0xcd ELSE 1 ENDIF"], +["0", "IF 0xce ELSE 1 ENDIF"], +["0", "IF 0xcf ELSE 1 ENDIF"], +["0", "IF 0xd0 ELSE 1 ENDIF"], ["0", "IF 0xd1 ELSE 1 ENDIF"], +["0", "IF 0xd2 ELSE 1 ENDIF"], +["0", "IF 0xd3 ELSE 1 ENDIF"], +["0", "IF 0xd4 ELSE 1 ENDIF"], +["0", "IF 0xd5 ELSE 1 ENDIF"], +["0", "IF 0xd6 ELSE 1 ENDIF"], +["0", "IF 0xd7 ELSE 1 ENDIF"], +["0", "IF 0xd8 ELSE 1 ENDIF"], +["0", "IF 0xd9 ELSE 1 ENDIF"], +["0", "IF 0xda ELSE 1 ENDIF"], +["0", "IF 0xdb ELSE 1 ENDIF"], +["0", "IF 0xdc ELSE 1 ENDIF"], +["0", "IF 0xdd ELSE 1 ENDIF"], +["0", "IF 0xde ELSE 1 ENDIF"], +["0", "IF 0xdf ELSE 1 ENDIF"], +["0", "IF 0xe0 ELSE 1 ENDIF"], +["0", "IF 0xe1 ELSE 1 ENDIF"], +["0", "IF 0xe2 ELSE 1 ENDIF"], +["0", "IF 0xe3 ELSE 1 ENDIF"], +["0", "IF 0xe4 ELSE 1 ENDIF"], +["0", "IF 0xe5 ELSE 1 ENDIF"], +["0", "IF 0xe6 ELSE 1 ENDIF"], +["0", "IF 0xe7 ELSE 1 ENDIF"], +["0", "IF 0xe8 ELSE 1 ENDIF"], +["0", "IF 0xe9 ELSE 1 ENDIF"], +["0", "IF 0xea ELSE 1 ENDIF"], +["0", "IF 0xeb ELSE 1 ENDIF"], +["0", "IF 0xec ELSE 1 ENDIF"], +["0", "IF 0xed ELSE 1 ENDIF"], ["0", "IF 0xee ELSE 1 ENDIF"], +["0", "IF 0xef ELSE 1 ENDIF"], +["0", "IF 0xf0 ELSE 1 ENDIF"], +["0", "IF 0xf1 ELSE 1 ENDIF"], +["0", "IF 0xf2 ELSE 1 ENDIF"], +["0", "IF 0xf3 ELSE 1 ENDIF"], +["0", "IF 0xf4 ELSE 1 ENDIF"], +["0", "IF 0xf5 ELSE 1 ENDIF"], +["0", "IF 0xf6 ELSE 1 ENDIF"], +["0", "IF 0xf7 ELSE 1 ENDIF"], +["0", "IF 0xf8 ELSE 1 ENDIF"], +["0", "IF 0xf9 ELSE 1 ENDIF"], +["0", "IF 0xfa ELSE 1 ENDIF"], +["0", "IF 0xfb ELSE 1 ENDIF"], +["0", "IF 0xfc ELSE 1 ENDIF"], ["0", "IF 0xfd ELSE 1 ENDIF"], +["0", "IF 0xfe ELSE 1 ENDIF"], ["0", "IF 0xff ELSE 1 ENDIF"], ["NOP", |