diff options
-rw-r--r-- | README.md | 13 | ||||
-rw-r--r-- | bitcoin-qt.pro | 87 | ||||
-rw-r--r-- | doc/release-process.txt | 55 | ||||
-rw-r--r-- | src/bitcoinrpc.cpp | 26 | ||||
-rw-r--r-- | src/main.cpp | 20 | ||||
-rw-r--r-- | src/qt/bitcoin.cpp | 2 | ||||
-rw-r--r-- | src/qt/bitcoin.qrc | 5 | ||||
-rw-r--r-- | src/qt/bitcoingui.cpp | 5 | ||||
-rw-r--r-- | src/qt/forms/sendcoinsdialog.ui | 48 | ||||
-rw-r--r-- | src/qt/notificator.cpp | 12 | ||||
-rw-r--r-- | src/qt/notificator.h | 4 | ||||
-rw-r--r-- | src/qt/optionsdialog.cpp | 4 | ||||
-rw-r--r-- | src/qt/overviewpage.cpp | 3 | ||||
-rw-r--r-- | src/qt/sendcoinsdialog.cpp | 11 | ||||
-rw-r--r-- | src/qt/sendcoinsdialog.h | 1 | ||||
-rw-r--r-- | src/qt/transactiondesc.h | 1 | ||||
-rw-r--r-- | src/test/util_tests.cpp | 36 | ||||
-rw-r--r-- | src/util.h | 45 |
18 files changed, 300 insertions, 78 deletions
@@ -27,3 +27,16 @@ help test the Bitcoin core, please contact QA@BitcoinTesting.org. Feature branches are created when there are major new features being worked on by several people. + +From time to time a pull request will become outdated. If this occurs, and +the pull is no longer automatically mergeable; a comment on the pull will +be used to issue a warning of closure. The pull will be closed 15 days +after the warning if action is not taken by the author. Pull requests closed +in this manner will have their corresponding issue labeled 'stagnant'. + +Issues with no commits will be given a similar warning, and closed after +15 days from their last activity. Issues closed in this manner will be +labeled 'stale'. + +Requests to reopen closed pull requests and/or issues can be submitted to +QA@BitcoinTesting.org.
\ No newline at end of file diff --git a/bitcoin-qt.pro b/bitcoin-qt.pro index b9fecb848e..2d9cdc7ef5 100644 --- a/bitcoin-qt.pro +++ b/bitcoin-qt.pro @@ -2,23 +2,21 @@ TEMPLATE = app TARGET = INCLUDEPATH += src src/json src/cryptopp src/qt DEFINES += QT_GUI -# DEFINES += SSL CONFIG += no_include_pwd +# for boost 1.37, add -mt to the boost libraries +# use: qmake BOOST_LIB_SUFFIX=-mt +# or when linking against a specific BerkelyDB version: BDB_LIB_SUFFIX=-4.8 + +# Dependency library locations can be customized with BOOST_INCLUDE_PATH, +# BOOST_LIB_PATH, BDB_INCLUDE_PATH, BDB_LIB_PATH +# OPENSSL_INCLUDE_PATH and OPENSSL_LIB_PATH respectively + OBJECTS_DIR = build MOC_DIR = build UI_DIR = build -# for boost 1.37, add -mt to the boost libraries -LIBS += -lssl -lcrypto -ldb_cxx -unix:!macx:LIBS += -lboost_system -lboost_filesystem -lboost_program_options -lboost_thread -macx:LIBS += -lboost_system-mt -lboost_filesystem-mt -lboost_program_options-mt -lboost_thread-mt -macx:DEFINES += __WXMAC_OSX__ MSG_NOSIGNAL=0 BOOST_FILESYSTEM_VERSION=3 -windows:LIBS += -lboost_system-mgw44-mt-1_43 -lboost_filesystem-mgw44-mt-1_43 -lboost_program_options-mgw44-mt-1_43 -lboost_thread-mgw44-mt-1_43 -lws2_32 -lgdi32 -windows:DEFINES += __WXMSW__ -windows:RC_FILE = src/qt/res/bitcoin-qt.rc - -# use: qmake "USE_UPNP=1" +# use: qmake "USE_UPNP=0" (disable by default) or "USE_UPNP=1" (enable by default) # miniupnpc (http://miniupnp.free.fr/files/) must be installed count(USE_UPNP, 1) { message(Building with UPNP support) @@ -26,12 +24,19 @@ count(USE_UPNP, 1) { LIBS += -lminiupnpc } -count(USE_DBUS, 1) { +# use: qmake "USE_DBUS=1" +contains(USE_DBUS, 1) { message(Building with DBUS (Freedesktop notifications) support) - DEFINES += QT_DBUS + DEFINES += USE_DBUS QT += dbus } +# use: qmake "USE_SSL=1" +contains(USE_DBUS, 1) { + message(Building with SSL support for RPC) + DEFINES += USE_SSL +} + # for extra security against potential buffer overflows QMAKE_CXXFLAGS += -fstack-protector QMAKE_LFLAGS += -fstack-protector @@ -173,17 +178,63 @@ FORMS += \ src/qt/forms/askpassphrasedialog.ui CODECFORTR = UTF-8 + # for lrelease/lupdate TRANSLATIONS = src/qt/locale/bitcoin_nl.ts src/qt/locale/bitcoin_de.ts \ src/qt/locale/bitcoin_ru.ts +isEmpty(QMAKE_LRELEASE) { + win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\lrelease.exe + else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease +} +isEmpty(TS_DIR):TS_DIR = src/qt/locale +# automatically build translations, so they can be included in resource file +TSQM.name = lrelease ${QMAKE_FILE_IN} +TSQM.input = TRANSLATIONS +TSQM.output = $$TS_DIR/${QMAKE_FILE_BASE}.qm +TSQM.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN} +TSQM.CONFIG = no_link +QMAKE_EXTRA_COMPILERS += TSQM +PRE_TARGETDEPS += compiler_TSQM_make_all + +# "Other files" to show in Qt Creator OTHER_FILES += \ - README.rst + doc/*.rst doc/*.txt doc/README README.md + +# platform specific defaults, if not overridden on command line +isEmpty(BOOST_LIB_SUFFIX) { + macx:BOOST_LIB_SUFFIX = -mt + windows:BOOST_LIB_SUFFIX = -mgw44-mt-1_43 +} -# For use with MacPorts -macx:INCLUDEPATH += /opt/local/include /opt/local/include/db48 -macx:LIBS += -L/opt/local/lib -L/opt/local/lib/db48 +isEmpty(BDB_LIB_PATH) { + macx:BDB_LIB_PATH = /opt/local/lib/db48 +} + +isEmpty(BDB_INCLUDE_PATH) { + macx:BDB_INCLUDE_PATH = /opt/local/include/db48 +} + +isEmpty(BOOST_LIB_PATH) { + macx:BOOST_LIB_PATH = /opt/local/lib +} + +isEmpty(BOOST_INCLUDE_PATH) { + macx:BOOST_INCLUDE_PATH = /opt/local/include +} -# Additional Mac options +windows:LIBS += -lws2_32 -lgdi32 +windows:DEFINES += __WXMSW__ +windows:RC_FILE = src/qt/res/bitcoin-qt.rc + +macx:DEFINES += __WXMAC_OSX__ MSG_NOSIGNAL=0 BOOST_FILESYSTEM_VERSION=3 macx:ICON = src/qt/res/icons/bitcoin.icns macx:TARGET = "Bitcoin Qt" + +# Set libraries and includes at end, to use platform-defined defaults if not overridden +INCLUDEPATH += $$BOOST_INCLUDE_PATH $$BDB_INCLUDE_PATH $$OPENSSL_INCLUDE_PATH +LIBS += $$join(BOOST_LIB_PATH,,-L,) $$join(BDB_LIB_PATH,,-L,) $$join(OPENSSL_LIB_PATH,,-L,) +LIBS += -lssl -lcrypto -ldb_cxx$$BDB_LIB_SUFFIX +LIBS += -lboost_system$$BOOST_LIB_SUFFIX -lboost_filesystem$$BOOST_LIB_SUFFIX -lboost_program_options$$BOOST_LIB_SUFFIX -lboost_thread$$BOOST_LIB_SUFFIX + +system($$QMAKE_LRELEASE -silent $$_PRO_FILE_) diff --git a/doc/release-process.txt b/doc/release-process.txt index 2e8b93e11b..ff00b121fc 100644 --- a/doc/release-process.txt +++ b/doc/release-process.txt @@ -23,17 +23,26 @@ * perform gitian builds - * From the bitcoin source dir - $ cd ../gitian-builder - $ ./bin/gbuild --commit bitcoin=v0.3.23 ../bitcoin/contrib/gitian.yml - $ ./bin/gbuild --commit bitcoin=v0.3.23 ../bitcoin/contrib/gitian-win32.yml + * From a directory containing the bitcoin source, gitian-builder and bitcoin-gitian-sigs + $ export VERSION=0.3.23 + $ cd ./gitian-builder + $ ./bin/gbuild --commit bitcoin=v$VERSION ../bitcoin/contrib/gitian-descriptors/gitian.yml + $ ./bin/gsign --signer (your gitian key, ie bluematt, sipa, etc) --release $VERSION --destination ../bitcoin-gitian-sigs/ ../bitcoin/contrib/gitian-descriptors/gitian.yml + $ cd build/out + $ zip bitcoin-$VERSION-linux-gitian.zip * + $ mv bitcoin-$VERSION-linux-gitian.zip ../../ + $ ./bin/gbuild --commit bitcoin=v$VERSION ../bitcoin/contrib/gitian-descriptors/gitian-win32.yml + $ ./bin/gsign --signer (your gitian key, ie bluematt, sipa, etc) --release $VERSION-win32 --destination ../bitcoin-gitian-sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win32.yml + $ cd build/out + $ zip bitcoin-$VERSION-win32-gitian.zip * + $ mv bitcoin-$VERSION-win32-gitian.zip ../../ Build output expected: - 1. linux 32-bit and 64-bit binaries + source - 2. windows 32-bit binary + source - 3. windows installer + 1. linux 32-bit and 64-bit binaries + source (bitcoin-$VERSION-linux-gitian.zip) + 2. windows 32-bit binary, installer + source (bitcoin-$VERSION-win32-gitian.zip) + 3. Gitian signatures (in bitcoin-gitian-sigs/$VERSION[-win32]/(your gitian key)/ -* repackage gitian builds: +* repackage gitian builds for release as stand-alone zip/tar/installer exe * Windows .zip and setup.exe: $ mkdir bitcoin-$VERSION-win32 @@ -66,4 +75,34 @@ * update wiki download links +* release gitian-signed gitian archives + + * Collect enough gitian signatures to meet minimum_weight (see contrib/gitian-downloader/*-download-config) + + * From a directory containing bitcoin source, bitcoin-gitian-sigs and gitian zips + $ export VERSION=0.3.23 + $ mkdir bitcoin-$VERSION-win32-gitian; cd bitcoin-$VERSION-win32-gitian + $ unzip ../bitcoin-$VERSION-win32-gitian.zip + $ mkdir gitian + $ cp ../bitcoin/contrib/gitian-downloader/*.pgp ./gitian/ + $ for file in `ls ../bitcoin-gitian-sigs/$VERSION-win32/`; do + $ cp ../bitcoin-gitian-sigs/$VERSION-win32/$file/bitcoin-build.assert ./gitian/$file-build.assert + $ cp ../bitcoin-gitian-sigs/$VERSION-win32/$file/bitcoin-build.assert.sig ./gitian/$file-build.assert.sig + $ done + $ zip bitcoin-$VERSION-win32-gitian.zip * + $ cp bitcoin-$VERSION-win32-gitian.zip ../ + $ cd .. + $ mkdir bitcoin-$VERSION-linux-gitian; cd bitcoin-$VERSION-linux-gitian + $ unzip ../bitcoin-$VERSION-linux-gitian.zip + $ mkdir gitian + $ cp ../bitcoin/contrib/gitian-downloader/*.pgp ./gitian/ + $ for file in `ls ../bitcoin-gitian-sigs/$VERSION/`; do + $ cp ../bitcoin-gitian-sigs/$VERSION/$file/bitcoin-build.assert ./gitian/$file-build.assert + $ cp ../bitcoin-gitian-sigs/$VERSION/$file/bitcoin-build.assert.sig ./gitian/$file-build.assert.sig + $ done + $ zip bitcoin-$VERSION-linux-gitian.zip * + $ cp bitcoin-$VERSION-linux-gitian.zip ../ + + * Upload gitian zips to SF + diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 8468e56105..1e7ffe6310 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -1003,7 +1003,6 @@ Value ListReceived(const Array& params, bool fByAccounts) Object obj; obj.push_back(Pair("address", address.ToString())); obj.push_back(Pair("account", strAccount)); - obj.push_back(Pair("label", strAccount)); // deprecated obj.push_back(Pair("amount", ValueFromAmount(nAmount))); obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf))); ret.push_back(obj); @@ -1018,7 +1017,6 @@ Value ListReceived(const Array& params, bool fByAccounts) int nConf = (*it).second.nConf; Object obj; obj.push_back(Pair("account", (*it).first)); - obj.push_back(Pair("label", (*it).first)); // deprecated obj.push_back(Pair("amount", ValueFromAmount(nAmount))); obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf))); ret.push_back(obj); @@ -1548,9 +1546,9 @@ Value getwork(const Array& params, bool fHelp) throw runtime_error( "getwork [data]\n" "If [data] is not specified, returns formatted hash data to work on:\n" - " \"midstate\" : precomputed hash state after hashing the first half of the data\n" + " \"midstate\" : precomputed hash state after hashing the first half of the data (DEPRECATED)\n" // deprecated " \"data\" : block data\n" - " \"hash1\" : formatted hash buffer for second hash\n" + " \"hash1\" : formatted hash buffer for second hash (DEPRECATED)\n" // deprecated " \"target\" : little endian hash target\n" "If [data] is specified, tries to solve the block and returns true if it was successful."); @@ -1614,9 +1612,9 @@ Value getwork(const Array& params, bool fHelp) uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); Object result; - result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); + result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata)))); - result.push_back(Pair("hash1", HexStr(BEGIN(phash1), END(phash1)))); + result.push_back(Pair("hash1", HexStr(BEGIN(phash1), END(phash1)))); // deprecated result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget)))); return result; } @@ -1675,20 +1673,13 @@ pair<string, rpcfn_type> pCallTable[] = make_pair("getnewaddress", &getnewaddress), make_pair("getaccountaddress", &getaccountaddress), make_pair("setaccount", &setaccount), - make_pair("setlabel", &setaccount), // deprecated make_pair("getaccount", &getaccount), - make_pair("getlabel", &getaccount), // deprecated make_pair("getaddressesbyaccount", &getaddressesbyaccount), - make_pair("getaddressesbylabel", &getaddressesbyaccount), // deprecated make_pair("sendtoaddress", &sendtoaddress), - make_pair("getamountreceived", &getreceivedbyaddress), // deprecated, renamed to getreceivedbyaddress - make_pair("getallreceived", &listreceivedbyaddress), // deprecated, renamed to listreceivedbyaddress make_pair("getreceivedbyaddress", &getreceivedbyaddress), make_pair("getreceivedbyaccount", &getreceivedbyaccount), - make_pair("getreceivedbylabel", &getreceivedbyaccount), // deprecated make_pair("listreceivedbyaddress", &listreceivedbyaddress), make_pair("listreceivedbyaccount", &listreceivedbyaccount), - make_pair("listreceivedbylabel", &listreceivedbyaccount), // deprecated make_pair("backupwallet", &backupwallet), make_pair("keypoolrefill", &keypoolrefill), make_pair("walletpassphrase", &walletpassphrase), @@ -1724,11 +1715,8 @@ string pAllowInSafeMode[] = "getinfo", "getnewaddress", "getaccountaddress", - "setlabel", // deprecated "getaccount", - "getlabel", // deprecated "getaddressesbyaccount", - "getaddressesbylabel", // deprecated "backupwallet", "keypoolrefill", "walletpassphrase", @@ -2316,18 +2304,12 @@ int CommandLineRPC(int argc, char *argv[]) if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]); if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]); if (strMethod == "settxfee" && n > 0) ConvertTo<double>(params[0]); - if (strMethod == "getamountreceived" && n > 1) ConvertTo<boost::int64_t>(params[1]); // deprecated if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]); if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo<boost::int64_t>(params[1]); - if (strMethod == "getreceivedbylabel" && n > 1) ConvertTo<boost::int64_t>(params[1]); // deprecated - if (strMethod == "getallreceived" && n > 0) ConvertTo<boost::int64_t>(params[0]); // deprecated - if (strMethod == "getallreceived" && n > 1) ConvertTo<bool>(params[1]); // deprecated if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]); if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo<bool>(params[1]); if (strMethod == "listreceivedbyaccount" && n > 0) ConvertTo<boost::int64_t>(params[0]); if (strMethod == "listreceivedbyaccount" && n > 1) ConvertTo<bool>(params[1]); - if (strMethod == "listreceivedbylabel" && n > 0) ConvertTo<boost::int64_t>(params[0]); // deprecated - if (strMethod == "listreceivedbylabel" && n > 1) ConvertTo<bool>(params[1]); // deprecated if (strMethod == "getbalance" && n > 1) ConvertTo<boost::int64_t>(params[1]); if (strMethod == "move" && n > 2) ConvertTo<double>(params[2]); if (strMethod == "move" && n > 3) ConvertTo<boost::int64_t>(params[3]); diff --git a/src/main.cpp b/src/main.cpp index be6fc9c53f..472c80a33a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -32,7 +32,6 @@ uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3 static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32); const int nTotalBlocksEstimate = 140700; // Conservative estimate of total nr of blocks on main chain const int nInitialBlockThreshold = 120; // Regard blocks up until N-threshold as "initial download" -int nMaxBlocksOfPeers = 0; // Amount of blocks that other nodes claim to have CBlockIndex* pindexGenesisBlock = NULL; int nBestHeight = -1; CBigNum bnBestChainWork = 0; @@ -41,6 +40,8 @@ uint256 hashBestChain = 0; CBlockIndex* pindexBest = NULL; int64 nTimeBestReceived = 0; +CMedianFilter<int> cPeerBlockCounts(5, 0); // Amount of blocks that other nodes claim to have + map<uint256, CBlock*> mapOrphanBlocks; multimap<uint256, CBlock*> mapOrphanBlocksByPrev; @@ -65,11 +66,6 @@ int fUseUPnP = false; #endif - - - - - ////////////////////////////////////////////////////////////////////////////// // // dispatching functions @@ -364,7 +360,7 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi // 34 bytes because a TxOut is: // 20-byte address + 8 byte bitcoin amount + 5 bytes of ops + 1 byte script length if (GetSigOpCount() > nSize / 34 || nSize < 100) - return DoS(10, error("AcceptToMemoryPool() : transaction with out-of-bounds SigOpCount")); + return error("AcceptToMemoryPool() : transaction with out-of-bounds SigOpCount"); // Rather not work on nonstandard transactions (unless -testnet) if (!fTestNet && !IsStandard()) @@ -730,7 +726,7 @@ int GetTotalBlocksEstimate() // Return maximum amount of blocks that other nodes claim to have int GetNumBlocksOfPeers() { - return std::max(nMaxBlocksOfPeers, GetTotalBlocksEstimate()); + return std::max(cPeerBlockCounts.median(), GetTotalBlocksEstimate()); } bool IsInitialBlockDownload() @@ -864,7 +860,7 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPoo if (txPrev.IsCoinBase()) for (CBlockIndex* pindex = pindexBlock; pindex && pindexBlock->nHeight - pindex->nHeight < COINBASE_MATURITY; pindex = pindex->pprev) if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile) - return DoS(10, error("ConnectInputs() : tried to spend coinbase at depth %d", pindexBlock->nHeight - pindex->nHeight)); + return error("ConnectInputs() : tried to spend coinbase at depth %d", pindexBlock->nHeight - pindex->nHeight); // Skip ECDSA signature verification when connecting blocks (fBlock=true) during initial download // (before the last blockchain checkpoint). This is safe because block merkle hashes are @@ -1859,10 +1855,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->fSuccessfullyConnected = true; printf("version message: version %d, blocks=%d\n", pfrom->nVersion, pfrom->nStartingHeight); - if(pfrom->nStartingHeight > nMaxBlocksOfPeers) - { - nMaxBlocksOfPeers = pfrom->nStartingHeight; - } + + cPeerBlockCounts.input(pfrom->nStartingHeight); } diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index daba512adc..60a9074204 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -120,7 +120,7 @@ int main(int argc, char *argv[]) // Load language file for system locale QString locale = QLocale::system().name(); QTranslator translator; - translator.load("bitcoin_"+locale); + translator.load(":/translations/"+locale); app.installTranslator(&translator); QSplashScreen splash(QPixmap(":/images/splash"), 0); diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index be0e4dce61..2985bb60ef 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -45,4 +45,9 @@ <qresource prefix="/movies"> <file alias="update_spinner">res/movies/update_spinner.mng</file> </qresource> + <qresource prefix="/translations"> + <file alias="de_DE">locale/bitcoin_de.qm</file> + <file alias="nl_NL">locale/bitcoin_nl.qm</file> + <file alias="ru_RU">locale/bitcoin_ru.qm</file> + </qresource> </RCC> diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 3e6b547006..be10b97c0f 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -522,11 +522,6 @@ void BitcoinGUI::gotoReceiveCoinsPage() void BitcoinGUI::gotoSendCoinsPage() { sendCoinsAction->setChecked(true); - if(centralWidget->currentWidget() != sendCoinsPage) - { - // Clear the current contents if we arrived from another tab - sendCoinsPage->clear(); - } centralWidget->setCurrentWidget(sendCoinsPage); exportAction->setEnabled(false); diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index 5b30d99e56..f9dd02fef5 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -25,7 +25,7 @@ <x>0</x> <y>0</y> <width>666</width> - <height>162</height> + <height>165</height> </rect> </property> <layout class="QVBoxLayout" name="verticalLayout_2"> @@ -59,7 +59,7 @@ <item> <layout class="QHBoxLayout" name="horizontalLayout"> <property name="spacing"> - <number>12</number> + <number>6</number> </property> <item> <widget class="QPushButton" name="addButton"> @@ -76,6 +76,50 @@ </widget> </item> <item> + <widget class="QPushButton" name="clearButton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Clear all</string> + </property> + <property name="icon"> + <iconset resource="../bitcoin.qrc"> + <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset> + </property> + <property name="autoRepeatDelay"> + <number>300</number> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="spacing"> + <number>3</number> + </property> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Balance:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="labelBalance"> + <property name="text"> + <string>123.456 BTC</string> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + </layout> + </item> + <item> <spacer name="horizontalSpacer"> <property name="orientation"> <enum>Qt::Horizontal</enum> diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp index 86ccfc8541..cf0c0a3901 100644 --- a/src/qt/notificator.cpp +++ b/src/qt/notificator.cpp @@ -9,7 +9,7 @@ #include <QSystemTrayIcon> #include <QMessageBox> -#ifdef QT_DBUS +#ifdef USE_DBUS #include <QtDBus/QtDBus> #include <stdint.h> #endif @@ -23,7 +23,7 @@ Notificator::Notificator(const QString &programName, QSystemTrayIcon *trayicon, programName(programName), mode(None), trayIcon(trayicon) -#ifdef QT_DBUS +#ifdef USE_DBUS ,interface(0) #endif { @@ -31,7 +31,7 @@ Notificator::Notificator(const QString &programName, QSystemTrayIcon *trayicon, { mode = QSystemTray; } -#ifdef QT_DBUS +#ifdef USE_DBUS interface = new QDBusInterface("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications"); if(interface->isValid()) @@ -43,12 +43,12 @@ Notificator::Notificator(const QString &programName, QSystemTrayIcon *trayicon, Notificator::~Notificator() { -#ifdef QT_DBUS +#ifdef USE_DBUS delete interface; #endif } -#ifdef QT_DBUS +#ifdef USE_DBUS // Loosely based on http://www.qtcentre.org/archive/index.php/t-25879.html class FreedesktopImage @@ -205,7 +205,7 @@ void Notificator::notify(Class cls, const QString &title, const QString &text, c { switch(mode) { -#ifdef QT_DBUS +#ifdef USE_DBUS case Freedesktop: notifyDBus(cls, title, text, icon, millisTimeout); break; diff --git a/src/qt/notificator.h b/src/qt/notificator.h index 13f6a908da..4217f7e06f 100644 --- a/src/qt/notificator.h +++ b/src/qt/notificator.h @@ -6,7 +6,7 @@ QT_BEGIN_NAMESPACE class QSystemTrayIcon; -#ifdef QT_DBUS +#ifdef USE_DBUS class QDBusInterface; #endif QT_END_NAMESPACE @@ -52,7 +52,7 @@ private: QString programName; Mode mode; QSystemTrayIcon *trayIcon; -#ifdef QT_DBUS +#ifdef USE_DBUS QDBusInterface *interface; void notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout); diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 0eeb6f86a5..7267e3d103 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -23,6 +23,7 @@ /* First page of options */ class MainOptionsPage : public QWidget { + Q_OBJECT public: explicit MainOptionsPage(QWidget *parent=0); @@ -45,6 +46,7 @@ public slots: class DisplayOptionsPage : public QWidget { + Q_OBJECT public: explicit DisplayOptionsPage(QWidget *parent=0); @@ -58,6 +60,8 @@ public slots: }; +#include "optionsdialog.moc" + OptionsDialog::OptionsDialog(QWidget *parent): QDialog(parent), contents_widget(0), pages_widget(0), model(0), main_page(0), display_page(0) diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 7bade9a755..f84a79fe30 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -17,7 +17,7 @@ class TxViewDelegate : public QAbstractItemDelegate { - //Q_OBJECT + Q_OBJECT public: TxViewDelegate(): QAbstractItemDelegate(), unit(BitcoinUnits::BTC) { @@ -87,6 +87,7 @@ public: int unit; }; +#include "overviewpage.moc" OverviewPage::OverviewPage(QWidget *parent) : QWidget(parent), diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 852d789805..58eb5c21f7 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -22,6 +22,7 @@ SendCoinsDialog::SendCoinsDialog(QWidget *parent) : addEntry(); connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addEntry())); + connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear())); } void SendCoinsDialog::setModel(WalletModel *model) @@ -36,6 +37,9 @@ void SendCoinsDialog::setModel(WalletModel *model) entry->setModel(model); } } + + setBalance(model->getBalance(), model->getUnconfirmedBalance()); + connect(model, SIGNAL(balanceChanged(qint64, qint64)), this, SLOT(setBalance(qint64, qint64))); } SendCoinsDialog::~SendCoinsDialog() @@ -241,3 +245,10 @@ void SendCoinsDialog::handleURL(const QUrl *url) } pasteEntry(rv); } + +void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance) +{ + Q_UNUSED(unconfirmedBalance); + int unit = model->getOptionsModel()->getDisplayUnit(); + ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance)); +} diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 9c56e51811..a14f99e8b2 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -37,6 +37,7 @@ public slots: void accept(); SendCoinsEntry *addEntry(); void updateRemoveEnabled(); + void setBalance(qint64 balance, qint64 unconfirmedBalance); private: Ui::SendCoinsDialog *ui; diff --git a/src/qt/transactiondesc.h b/src/qt/transactiondesc.h index 257b2cbb89..484bb1230e 100644 --- a/src/qt/transactiondesc.h +++ b/src/qt/transactiondesc.h @@ -10,6 +10,7 @@ class CWalletTx; class TransactionDesc: public QObject { + Q_OBJECT public: // Provide human-readable extended HTML description of a transaction static QString toHTML(CWallet *wallet, CWalletTx &wtx); diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp new file mode 100644 index 0000000000..337d901277 --- /dev/null +++ b/src/test/util_tests.cpp @@ -0,0 +1,36 @@ +#include <vector> +#include <boost/test/unit_test.hpp> +#include <boost/foreach.hpp> + +#include "../util.h" + +using namespace std; + +BOOST_AUTO_TEST_SUITE(util_tests) + +BOOST_AUTO_TEST_CASE(util_MedianFilter) +{ + CMedianFilter<int> filter(5, 15); + + BOOST_CHECK(filter.median() == 15); + + filter.input(20); // [15 20] + BOOST_CHECK(filter.median() == 17); + + filter.input(30); // [15 20 30] + BOOST_CHECK(filter.median() == 20); + + filter.input(3); // [3 15 20 30] + BOOST_CHECK(filter.median() == 17); + + filter.input(7); // [3 7 15 20 30] + BOOST_CHECK(filter.median() == 15); + + filter.input(18); // [3 7 18 20 30] + BOOST_CHECK(filter.median() == 18); + + filter.input(0); // [0 3 7 18 30] + BOOST_CHECK(filter.median() == 7); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/util.h b/src/util.h index 1fdfdf1197..f0b2f4a71c 100644 --- a/src/util.h +++ b/src/util.h @@ -570,6 +570,51 @@ inline uint160 Hash160(const std::vector<unsigned char>& vch) } +// Median filter over a stream of values +// Returns the median of the last N numbers +template <typename T> class CMedianFilter +{ +private: + std::vector<T> vValues; + std::vector<T> vSorted; + int nSize; +public: + CMedianFilter(int size, T initial_value): + nSize(size) + { + vValues.reserve(size); + vValues.push_back(initial_value); + vSorted = vValues; + } + + void input(T value) + { + if(vValues.size() == nSize) + { + vValues.erase(vValues.begin()); + } + vValues.push_back(value); + + vSorted.resize(vValues.size()); + std::copy(vValues.begin(), vValues.end(), vSorted.begin()); + std::sort(vSorted.begin(), vSorted.end()); + } + + T median() const + { + int size = vSorted.size(); + assert(size>0); + if(size & 1) // Odd number of elements + { + return vSorted[size/2]; + } + else // Even number of elements + { + return (vSorted[size/2-1] + vSorted[size/2]) / 2; + } + } +}; + |