aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build-aux/m4/bitcoin_qt.m454
-rw-r--r--configure.ac23
-rw-r--r--doc/release-notes.md8
-rwxr-xr-xqa/rpc-tests/p2p-acceptblock.py87
-rw-r--r--src/Makefile.qt.include4
-rw-r--r--src/bitcoin-tx.cpp7
-rw-r--r--src/chainparams.cpp20
-rw-r--r--src/init.cpp30
-rw-r--r--src/main.cpp45
-rw-r--r--src/mruset.h60
-rw-r--r--src/policy/fees.cpp5
-rw-r--r--src/qt/addressbookpage.cpp26
-rw-r--r--src/qt/addressbookpage.h3
-rw-r--r--src/qt/bitcoin.cpp26
-rw-r--r--src/qt/bitcoingui.cpp69
-rw-r--r--src/qt/bitcoingui.h7
-rw-r--r--src/qt/coincontroldialog.cpp11
-rw-r--r--src/qt/coincontroldialog.h5
-rw-r--r--src/qt/intro.cpp3
-rw-r--r--src/qt/networkstyle.cpp1
-rw-r--r--src/qt/overviewpage.cpp15
-rw-r--r--src/qt/overviewpage.h3
-rw-r--r--src/qt/platformstyle.cpp147
-rw-r--r--src/qt/platformstyle.h55
-rw-r--r--src/qt/receivecoinsdialog.cpp31
-rw-r--r--src/qt/receivecoinsdialog.h5
-rw-r--r--src/qt/rpcconsole.cpp17
-rw-r--r--src/qt/rpcconsole.h4
-rw-r--r--src/qt/scicon.cpp98
-rw-r--r--src/qt/scicon.h24
-rw-r--r--src/qt/sendcoinsdialog.cpp29
-rw-r--r--src/qt/sendcoinsdialog.h4
-rw-r--r--src/qt/sendcoinsentry.cpp24
-rw-r--r--src/qt/sendcoinsentry.h4
-rw-r--r--src/qt/signverifymessagedialog.cpp35
-rw-r--r--src/qt/signverifymessagedialog.h4
-rw-r--r--src/qt/transactiontablemodel.cpp9
-rw-r--r--src/qt/transactiontablemodel.h4
-rw-r--r--src/qt/transactionview.cpp63
-rw-r--r--src/qt/transactionview.h3
-rw-r--r--src/qt/walletframe.cpp7
-rw-r--r--src/qt/walletframe.h5
-rw-r--r--src/qt/walletmodel.cpp4
-rw-r--r--src/qt/walletmodel.h3
-rw-r--r--src/qt/walletview.cpp29
-rw-r--r--src/qt/walletview.h4
-rw-r--r--src/rpcserver.cpp4
-rw-r--r--src/test/getarg_tests.cpp22
-rw-r--r--src/test/mruset_tests.cpp64
-rw-r--r--src/txmempool.cpp4
-rw-r--r--src/util.cpp47
-rw-r--r--src/wallet/crypter.cpp2
-rw-r--r--src/wallet/wallet.cpp2
53 files changed, 685 insertions, 584 deletions
diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4
index 100b8653a8..121e10bd37 100644
--- a/build-aux/m4/bitcoin_qt.m4
+++ b/build-aux/m4/bitcoin_qt.m4
@@ -110,13 +110,8 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
if test x$bitcoin_qt_got_major_vers = x5; then
_BITCOIN_QT_IS_STATIC
if test x$bitcoin_cv_static_qt = xyes; then
+ _BITCOIN_QT_FIND_STATIC_PLUGINS
AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static])
- if test x$qt_plugin_path != x; then
- QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms"
- fi
- if test x$use_pkgconfig = xyes; then
- PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"])
- fi
AC_CACHE_CHECK(for Qt < 5.4, bitcoin_cv_need_acc_widget,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[#include <QtCore>]],[[
#if QT_VERSION >= 0x050400
@@ -127,25 +122,15 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
[bitcoin_cv_need_acc_widget=no])
])
if test "x$bitcoin_cv_need_acc_widget" = "xyes"; then
- if test x$qt_plugin_path != x; then
- QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible"
- fi
_BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(AccessibleFactory)], [-lqtaccessiblewidgets])
fi
if test x$TARGET_OS = xwindows; then
_BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)],[-lqwindows])
AC_DEFINE(QT_QPA_PLATFORM_WINDOWS, 1, [Define this symbol if the qt platform is windows])
elif test x$TARGET_OS = xlinux; then
- PKG_CHECK_MODULES([X11XCB], [x11-xcb], [QT_LIBS="$X11XCB_LIBS $QT_LIBS"])
- if ${PKG_CONFIG} --exists "Qt5Core >= 5.5" 2>/dev/null; then
- PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"])
- fi
_BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)],[-lqxcb -lxcb-static])
AC_DEFINE(QT_QPA_PLATFORM_XCB, 1, [Define this symbol if the qt platform is xcb])
elif test x$TARGET_OS = xdarwin; then
- if test x$use_pkgconfig = xyes; then
- PKG_CHECK_MODULES([QTPRINT], [Qt5PrintSupport], [QT_LIBS="$QTPRINT_LIBS $QT_LIBS"])
- fi
AX_CHECK_LINK_FLAG([[-framework IOKit]],[QT_LIBS="$QT_LIBS -framework IOKit"],[AC_MSG_ERROR(could not iokit framework)])
_BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)],[-lqcocoa])
AC_DEFINE(QT_QPA_PLATFORM_COCOA, 1, [Define this symbol if the qt platform is cocoa])
@@ -154,10 +139,6 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
else
if test x$TARGET_OS = xwindows; then
AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static])
- if test x$qt_plugin_path != x; then
- QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible"
- QT_LIBS="$QT_LIBS -L$qt_plugin_path/codecs"
- fi
_BITCOIN_QT_CHECK_STATIC_PLUGINS([
Q_IMPORT_PLUGIN(qcncodecs)
Q_IMPORT_PLUGIN(qjpcodecs)
@@ -297,6 +278,39 @@ AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGINS],[
LIBS="$CHECK_STATIC_PLUGINS_TEMP_LIBS"
])
+dnl Internal. Find paths necessary for linking qt static plugins
+dnl Inputs: bitcoin_qt_got_major_vers. 4 or 5.
+dnl Inputs: qt_plugin_path. optional.
+dnl Outputs: QT_LIBS is appended
+AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[
+ if test x$bitcoin_qt_got_major_vers = x5; then
+ if test x$qt_plugin_path != x; then
+ QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms"
+ if test -d "$qt_plugin_path/accessible"; then
+ QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible"
+ fi
+ fi
+ m4_ifdef([PKG_CHECK_MODULES],[
+ if test x$use_pkgconfig = xyes; then
+ PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"])
+ if test x$TARGET_OS = xlinux; then
+ PKG_CHECK_MODULES([X11XCB], [x11-xcb], [QT_LIBS="$X11XCB_LIBS $QT_LIBS"])
+ if ${PKG_CONFIG} --exists "Qt5Core >= 5.5" 2>/dev/null; then
+ PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"])
+ fi
+ elif test x$TARGET_OS = xdarwin; then
+ PKG_CHECK_MODULES([QTPRINT], [Qt5PrintSupport], [QT_LIBS="$QTPRINT_LIBS $QT_LIBS"])
+ fi
+ fi
+ ])
+ else
+ if test x$qt_plugin_path != x; then
+ QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible"
+ QT_LIBS="$QT_LIBS -L$qt_plugin_path/codecs"
+ fi
+ fi
+])
+
dnl Internal. Find Qt libraries using pkg-config.
dnl Inputs: bitcoin_qt_want_version (from --with-gui=). The version to check
dnl first.
diff --git a/configure.ac b/configure.ac
index 7f90b5f395..a524bded6f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -680,19 +680,26 @@ else
fi
fi
-AC_CHECK_LIB([crypto],[RAND_egd],[],[
- AC_ARG_WITH([libressl],
- [AS_HELP_STRING([--with-libressl],[Build with system LibreSSL (default is no; DANGEROUS; NOT SUPPORTED)])],
- [AC_MSG_WARN([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])],
- [AC_MSG_ERROR([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])]
- )
-])
-
CFLAGS_TEMP="$CFLAGS"
LIBS_TEMP="$LIBS"
CFLAGS="$CFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS"
LIBS="$LIBS $SSL_LIBS $CRYPTO_LIBS"
AC_CHECK_HEADER([openssl/ec.h],, AC_MSG_ERROR(OpenSSL ec header missing),)
+
+AC_MSG_CHECKING(for a supported OpenSSL version)
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+ #include <openssl/rand.h>
+ ]],
+ [[RAND_egd(NULL);]])],
+ [AC_MSG_RESULT(yes)],
+ [
+ AC_ARG_WITH([libressl],
+ [AS_HELP_STRING([--with-libressl],[Build with system LibreSSL (default is no; DANGEROUS; NOT SUPPORTED)])],
+ [AC_MSG_WARN([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])],
+ [AC_MSG_ERROR([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])]
+ )]
+)
+
CFLAGS="$CFLAGS_TEMP"
LIBS="$LIBS_TEMP"
diff --git a/doc/release-notes.md b/doc/release-notes.md
index 7480a7cd21..db6c28972d 100644
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -27,6 +27,14 @@ Low-level RPC API changes
advantage if a JSON library insists on using a lossy floating point type for
numbers, which would be dangerous for monetary amounts.
+Option parsing behavior
+-----------------------
+
+Command line options are now parsed strictly in the order in which they are
+specified. It used to be the case that `-X -noX` ends up, unintuitively, with X
+set, as `-X` had precedence over `-noX`. This is no longer the case. Like for
+other software, the last specified value for an option will hold.
+
0.12.0 Change log
=================
diff --git a/qa/rpc-tests/p2p-acceptblock.py b/qa/rpc-tests/p2p-acceptblock.py
index fcdd1e1b99..83c03eeb78 100755
--- a/qa/rpc-tests/p2p-acceptblock.py
+++ b/qa/rpc-tests/p2p-acceptblock.py
@@ -40,6 +40,11 @@ The test:
it's missing an intermediate block.
Node1 should reorg to this longer chain.
+4b.Send 288 more blocks on the longer chain.
+ Node0 should process all but the last block (too far ahead in height).
+ Send all headers to Node1, and then send the last block in that chain.
+ Node1 should accept the block because it's coming from a whitelisted peer.
+
5. Send a duplicate of the block in #3 to Node0.
Node0 should not process the block because it is unrequested, and stay on
the shorter chain.
@@ -59,6 +64,8 @@ class TestNode(NodeConnCB):
NodeConnCB.__init__(self)
self.create_callback_map()
self.connection = None
+ self.ping_counter = 1
+ self.last_pong = msg_pong()
def add_connection(self, conn):
self.connection = conn
@@ -82,6 +89,24 @@ class TestNode(NodeConnCB):
def send_message(self, message):
self.connection.send_message(message)
+ def on_pong(self, conn, message):
+ self.last_pong = message
+
+ # Sync up with the node after delivery of a block
+ def sync_with_ping(self, timeout=30):
+ self.connection.send_message(msg_ping(nonce=self.ping_counter))
+ received_pong = False
+ sleep_time = 0.05
+ while not received_pong and timeout > 0:
+ time.sleep(sleep_time)
+ timeout -= sleep_time
+ with mininode_lock:
+ if self.last_pong.nonce == self.ping_counter:
+ received_pong = True
+ self.ping_counter += 1
+ return received_pong
+
+
class AcceptBlockTest(BitcoinTestFramework):
def add_options(self, parser):
parser.add_option("--testbinary", dest="testbinary",
@@ -126,13 +151,15 @@ class AcceptBlockTest(BitcoinTestFramework):
# 2. Send one block that builds on each tip.
# This should be accepted.
blocks_h2 = [] # the height 2 blocks on each node's chain
+ block_time = time.time() + 1
for i in xrange(2):
- blocks_h2.append(create_block(tips[i], create_coinbase(), time.time()+1))
+ blocks_h2.append(create_block(tips[i], create_coinbase(), block_time))
blocks_h2[i].solve()
+ block_time += 1
test_node.send_message(msg_block(blocks_h2[0]))
white_node.send_message(msg_block(blocks_h2[1]))
- time.sleep(1)
+ [ x.sync_with_ping() for x in [test_node, white_node] ]
assert_equal(self.nodes[0].getblockcount(), 2)
assert_equal(self.nodes[1].getblockcount(), 2)
print "First height 2 block accepted by both nodes"
@@ -145,7 +172,7 @@ class AcceptBlockTest(BitcoinTestFramework):
test_node.send_message(msg_block(blocks_h2f[0]))
white_node.send_message(msg_block(blocks_h2f[1]))
- time.sleep(1) # Give time to process the block
+ [ x.sync_with_ping() for x in [test_node, white_node] ]
for x in self.nodes[0].getchaintips():
if x['hash'] == blocks_h2f[0].hash:
assert_equal(x['status'], "headers-only")
@@ -164,7 +191,7 @@ class AcceptBlockTest(BitcoinTestFramework):
test_node.send_message(msg_block(blocks_h3[0]))
white_node.send_message(msg_block(blocks_h3[1]))
- time.sleep(1)
+ [ x.sync_with_ping() for x in [test_node, white_node] ]
# Since the earlier block was not processed by node0, the new block
# can't be fully validated.
for x in self.nodes[0].getchaintips():
@@ -182,6 +209,45 @@ class AcceptBlockTest(BitcoinTestFramework):
assert_equal(self.nodes[1].getblockcount(), 3)
print "Successfully reorged to length 3 chain from whitelisted peer"
+ # 4b. Now mine 288 more blocks and deliver; all should be processed but
+ # the last (height-too-high) on node0. Node1 should process the tip if
+ # we give it the headers chain leading to the tip.
+ tips = blocks_h3
+ headers_message = msg_headers()
+ all_blocks = [] # node0's blocks
+ for j in xrange(2):
+ for i in xrange(288):
+ next_block = create_block(tips[j].sha256, create_coinbase(), tips[j].nTime+1)
+ next_block.solve()
+ if j==0:
+ test_node.send_message(msg_block(next_block))
+ all_blocks.append(next_block)
+ else:
+ headers_message.headers.append(CBlockHeader(next_block))
+ tips[j] = next_block
+
+ time.sleep(2)
+ for x in all_blocks:
+ try:
+ self.nodes[0].getblock(x.hash)
+ if x == all_blocks[287]:
+ raise AssertionError("Unrequested block too far-ahead should have been ignored")
+ except:
+ if x == all_blocks[287]:
+ print "Unrequested block too far-ahead not processed"
+ else:
+ raise AssertionError("Unrequested block with more work should have been accepted")
+
+ headers_message.headers.pop() # Ensure the last block is unrequested
+ white_node.send_message(headers_message) # Send headers leading to tip
+ white_node.send_message(msg_block(tips[1])) # Now deliver the tip
+ try:
+ white_node.sync_with_ping()
+ self.nodes[1].getblock(tips[1].hash)
+ print "Unrequested block far ahead of tip accepted from whitelisted peer"
+ except:
+ raise AssertionError("Unrequested block from whitelisted peer not accepted")
+
# 5. Test handling of unrequested block on the node that didn't process
# Should still not be processed (even though it has a child that has more
# work).
@@ -192,7 +258,7 @@ class AcceptBlockTest(BitcoinTestFramework):
# the node processes it and incorrectly advances the tip).
# But this would be caught later on, when we verify that an inv triggers
# a getdata request for this block.
- time.sleep(1)
+ test_node.sync_with_ping()
assert_equal(self.nodes[0].getblockcount(), 2)
print "Unrequested block that would complete more-work chain was ignored"
@@ -204,21 +270,20 @@ class AcceptBlockTest(BitcoinTestFramework):
test_node.last_getdata = None
test_node.send_message(msg_inv([CInv(2, blocks_h3[0].sha256)]))
- time.sleep(1)
+ test_node.sync_with_ping()
with mininode_lock:
getdata = test_node.last_getdata
- # Check that the getdata is for the right block
- assert_equal(len(getdata.inv), 1)
+ # Check that the getdata includes the right block
assert_equal(getdata.inv[0].hash, blocks_h2f[0].sha256)
print "Inv at tip triggered getdata for unprocessed block"
# 7. Send the missing block for the third time (now it is requested)
test_node.send_message(msg_block(blocks_h2f[0]))
- time.sleep(1)
- assert_equal(self.nodes[0].getblockcount(), 3)
- print "Successfully reorged to length 3 chain from non-whitelisted peer"
+ test_node.sync_with_ping()
+ assert_equal(self.nodes[0].getblockcount(), 290)
+ print "Successfully reorged to longer chain from non-whitelisted peer"
[ c.disconnect_node() for c in connections ]
diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index 2ec3468e06..748f2b14d5 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -185,13 +185,13 @@ BITCOIN_QT_H = \
qt/paymentrequestplus.h \
qt/paymentserver.h \
qt/peertablemodel.h \
+ qt/platformstyle.h \
qt/qvalidatedlineedit.h \
qt/qvaluecombobox.h \
qt/receivecoinsdialog.h \
qt/receiverequestdialog.h \
qt/recentrequeststablemodel.h \
qt/rpcconsole.h \
- qt/scicon.h \
qt/sendcoinsdialog.h \
qt/sendcoinsentry.h \
qt/signverifymessagedialog.h \
@@ -273,10 +273,10 @@ BITCOIN_QT_CPP = \
qt/optionsdialog.cpp \
qt/optionsmodel.cpp \
qt/peertablemodel.cpp \
+ qt/platformstyle.cpp \
qt/qvalidatedlineedit.cpp \
qt/qvaluecombobox.cpp \
qt/rpcconsole.cpp \
- qt/scicon.cpp \
qt/splashscreen.cpp \
qt/trafficgraphwidget.cpp \
qt/utilitydialog.cpp
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index 9ad57d5c6f..e389d51a73 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -143,13 +143,14 @@ static void RegisterLoad(const string& strInput)
valStr.insert(valStr.size(), buf, bread);
}
- if (ferror(f)) {
+ int error = ferror(f);
+ fclose(f);
+
+ if (error) {
string strErr = "Error reading file " + filename;
throw runtime_error(strErr);
}
- fclose(f);
-
// evaluate as JSON buffer register
RegisterSetJson(key, valStr);
}
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 95e20bf61b..623104690a 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -16,7 +16,7 @@ using namespace std;
#include "chainparamsseeds.h"
-static CBlock CreateGenesisBlock(const char* pszTimestamp, CScript genesisOutputScript, uint32_t nTime=1231006505, uint32_t nNonce=2083236893, uint32_t nBits=0x1d00ffff, int32_t nVersion=1, const CAmount& genesisReward=50 * COIN)
+static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
CMutableTransaction txNew;
txNew.nVersion = 1;
@@ -48,10 +48,10 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, CScript genesisOutput
* CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
* vMerkleTree: 4a5e1e
*/
-static CBlock CreateGenesisBlock(uint32_t nTime=1231006505, uint32_t nNonce=2083236893, uint32_t nBits=0x1d00ffff, int32_t nVersion=1, const CAmount& genesisReward=50 * COIN)
+static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
- CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
+ const CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}
@@ -91,7 +91,7 @@ public:
nDefaultPort = 8333;
nPruneAfterHeight = 100000;
- genesis = CreateGenesisBlock();
+ genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
@@ -164,9 +164,10 @@ public:
nDefaultPort = 18333;
nPruneAfterHeight = 1000;
- genesis = CreateGenesisBlock(1296688602, 414098458);
+ genesis = CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
assert(consensus.hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"));
+ assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
vFixedSeeds.clear();
vSeeds.clear();
@@ -216,16 +217,19 @@ public:
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 10 * 60;
consensus.fPowAllowMinDifficultyBlocks = true;
+
pchMessageStart[0] = 0xfa;
pchMessageStart[1] = 0xbf;
pchMessageStart[2] = 0xb5;
pchMessageStart[3] = 0xda;
- genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff);
- consensus.hashGenesisBlock = genesis.GetHash();
nDefaultPort = 18444;
- assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
nPruneAfterHeight = 1000;
+ genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN);
+ consensus.hashGenesisBlock = genesis.GetHash();
+ assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
+ assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
+
vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds.
vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds.
diff --git a/src/init.cpp b/src/init.cpp
index 365bd30714..6bea42a20e 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -441,6 +441,9 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-min", _("Start minimized"));
strUsage += HelpMessageOpt("-rootcertificates=<file>", _("Set SSL root certificates for payment request (default: -system-)"));
strUsage += HelpMessageOpt("-splash", _("Show splash screen on startup (default: 1)"));
+ if (showDebug) {
+ strUsage += HelpMessageOpt("-uiplatform", "Select platform to customize UI for (one of windows, macosx, other; default: platform compiled on)");
+ }
}
return strUsage;
@@ -1275,15 +1278,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
mempool.ReadFeeEstimates(est_filein);
fFeeEstimatesInitialized = true;
- // if prune mode, unset NODE_NETWORK and prune block files
- if (fPruneMode) {
- LogPrintf("Unsetting NODE_NETWORK on prune mode\n");
- nLocalServices &= ~NODE_NETWORK;
- if (!fReindex) {
- PruneAndFlush();
- }
- }
-
// ********************************************************* Step 8: load wallet
#ifdef ENABLE_WALLET
if (fDisableWallet) {
@@ -1437,7 +1431,21 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
#else // ENABLE_WALLET
LogPrintf("No wallet support compiled in!\n");
#endif // !ENABLE_WALLET
- // ********************************************************* Step 9: import blocks
+
+ // ********************************************************* Step 9: data directory maintenance
+
+ // if pruning, unset the service bit and perform the initial blockstore prune
+ // after any wallet rescanning has taken place.
+ if (fPruneMode) {
+ uiInterface.InitMessage(_("Pruning blockstore..."));
+ LogPrintf("Unsetting NODE_NETWORK on prune mode\n");
+ nLocalServices &= ~NODE_NETWORK;
+ if (!fReindex) {
+ PruneAndFlush();
+ }
+ }
+
+ // ********************************************************* Step 10: import blocks
if (mapArgs.count("-blocknotify"))
uiInterface.NotifyBlockTip.connect(BlockNotifyCallback);
@@ -1461,7 +1469,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
MilliSleep(10);
}
- // ********************************************************* Step 10: start node
+ // ********************************************************* Step 11: start node
if (!CheckDiskSpace())
return false;
diff --git a/src/main.cpp b/src/main.cpp
index 0ad41af955..14f36762c9 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1300,9 +1300,6 @@ int GetSpendHeight(const CCoinsViewCache& inputs)
return pindexPrev->nHeight + 1;
}
-static mrumap<uint256, unsigned int> cacheCheck(2 * MAX_BLOCK_SIZE / CTransaction().GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION));
-static boost::mutex cs_cacheCheck;
-
namespace Consensus {
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight)
{
@@ -1357,17 +1354,6 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
{
if (!tx.IsCoinBase())
{
- if (fScriptChecks) {
- boost::unique_lock<boost::mutex> lock(cs_cacheCheck);
- mrumap<uint256, unsigned int>::const_iterator iter = cacheCheck.find(tx.GetHash());
- if (iter != cacheCheck.end()) {
- // The following test relies on the fact that all script validation flags are softforks (i.e. an extra bit set cannot cause a false result to become true).
- if ((iter->second & flags) == flags) {
- return true;
- }
- }
- }
-
if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs)))
return false;
@@ -1418,11 +1404,6 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
}
}
- if (cacheStore && fScriptChecks && pvChecks == NULL) {
- boost::unique_lock<boost::mutex> lock(cs_cacheCheck);
- cacheCheck.insert(tx.GetHash(), flags);
- }
-
return true;
}
@@ -2143,13 +2124,6 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
SyncWithWallets(tx, pblock);
}
- // Erase block's transactions from the validation cache
- {
- boost::unique_lock<boost::mutex> lock(cs_cacheCheck);
- BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
- cacheCheck.erase(tx.GetHash());
- }
- }
int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
@@ -2783,9 +2757,15 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
// Try to process all requested blocks that we don't have, but only
// process an unrequested block if it's new and has enough work to
- // advance our tip.
+ // advance our tip, and isn't too many blocks ahead.
bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA;
bool fHasMoreWork = (chainActive.Tip() ? pindex->nChainWork > chainActive.Tip()->nChainWork : true);
+ // Blocks that are too out-of-order needlessly limit the effectiveness of
+ // pruning, because pruning will not delete block files that contain any
+ // blocks which are too close in height to the tip. Apply this test
+ // regardless of whether pruning is enabled; it should generally be safe to
+ // not process unrequested blocks.
+ bool fTooFarAhead = (pindex->nHeight > int(chainActive.Height() + MIN_BLOCKS_TO_KEEP));
// TODO: deal better with return value and error conditions for duplicate
// and unrequested blocks.
@@ -2793,6 +2773,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
if (!fRequested) { // If we didn't ask for it:
if (pindex->nTx != 0) return true; // This is a previously-processed block that was pruned
if (!fHasMoreWork) return true; // Don't process less-work chains
+ if (fTooFarAhead) return true; // Block height is too high
}
if ((!CheckBlock(block, state)) || !ContextualCheckBlock(block, state, pindex->pprev)) {
@@ -3445,7 +3426,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
}
}
} catch (const std::exception& e) {
- LogPrintf("%s: Deserialize or I/O error - %s", __func__, e.what());
+ LogPrintf("%s: Deserialize or I/O error - %s\n", __func__, e.what());
}
}
} catch (const std::runtime_error& e) {
@@ -4448,8 +4429,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
pfrom->AddInventoryKnown(inv);
CValidationState state;
- // Process all blocks from whitelisted peers, even if not requested.
- ProcessNewBlock(state, pfrom, &block, pfrom->fWhitelisted, NULL);
+ // Process all blocks from whitelisted peers, even if not requested,
+ // unless we're still syncing with the network.
+ // Such an unrequested block may still be processed, subject to the
+ // conditions in AcceptBlock().
+ bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
+ ProcessNewBlock(state, pfrom, &block, forceProcessing, NULL);
int nDoS;
if (state.IsInvalid(nDoS)) {
pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
diff --git a/src/mruset.h b/src/mruset.h
index 9dff5694ba..398aa173bf 100644
--- a/src/mruset.h
+++ b/src/mruset.h
@@ -9,10 +9,6 @@
#include <vector>
#include <utility>
-#include <boost/multi_index_container.hpp>
-#include <boost/multi_index/ordered_index.hpp>
-#include <boost/multi_index/sequenced_index.hpp>
-
/** STL-like set container that only keeps the most recent N elements. */
template <typename T>
class mruset
@@ -66,60 +62,4 @@ public:
size_type max_size() const { return nMaxSize; }
};
-/** STL-like map container that only keeps the most recent N elements. */
-template <typename K, typename V>
-class mrumap
-{
-private:
- struct key_extractor {
- typedef K result_type;
- const result_type& operator()(const std::pair<K, V>& e) const { return e.first; }
- result_type& operator()(std::pair<K, V>* e) const { return e->first; }
- };
-
- typedef boost::multi_index_container<
- std::pair<K, V>,
- boost::multi_index::indexed_by<
- boost::multi_index::sequenced<>,
- boost::multi_index::ordered_unique<key_extractor>
- >
- > map_type;
-
-public:
- typedef K key_type;
- typedef std::pair<K, V> value_type;
- typedef typename map_type::iterator iterator;
- typedef typename map_type::const_iterator const_iterator;
- typedef typename map_type::size_type size_type;
-
-protected:
- map_type m_;
- size_type max_size_;
-
-public:
- mrumap(size_type max_size_in = 1) { clear(max_size_in); }
- iterator begin() { return m_.begin(); }
- iterator end() { return m_.end(); }
- const_iterator begin() const { return m_.begin(); }
- const_iterator end() const { return m_.end(); }
- size_type size() const { return m_.size(); }
- bool empty() const { return m_.empty(); }
- iterator find(const key_type& key) { return m_.template project<0>(boost::get<1>(m_).find(key)); }
- const_iterator find(const key_type& key) const { return m_.template project<0>(boost::get<1>(m_).find(key)); }
- size_type count(const key_type& key) const { return boost::get<1>(m_).count(key); }
- void clear(size_type max_size_in) { m_.clear(); max_size_ = max_size_in; }
- std::pair<iterator, bool> insert(const K& key, const V& value)
- {
- std::pair<K, V> elem(key, value);
- std::pair<iterator, bool> p = m_.push_front(elem);
- if (p.second && m_.size() > max_size_) {
- m_.pop_back();
- }
- return p;
- }
- void erase(iterator it) { m_.erase(it); }
- void erase(const key_type& k) { boost::get<1>(m_).erase(k); }
- size_type max_size() const { return max_size_; }
-};
-
#endif // BITCOIN_MRUSET_H
diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp
index b1491cec01..cdee541d2f 100644
--- a/src/policy/fees.cpp
+++ b/src/policy/fees.cpp
@@ -249,7 +249,7 @@ unsigned int TxConfirmStats::NewTx(unsigned int nBlockHeight, double val)
unsigned int bucketindex = bucketMap.lower_bound(val)->second;
unsigned int blockIndex = nBlockHeight % unconfTxs.size();
unconfTxs[blockIndex][bucketindex]++;
- LogPrint("estimatefee", "adding to %s\n", dataTypeString);
+ LogPrint("estimatefee", "adding to %s", dataTypeString);
return bucketindex;
}
@@ -390,8 +390,9 @@ void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, boo
mapMemPoolTxs[hash].bucketIndex = feeStats.NewTx(txHeight, (double)feeRate.GetFeePerK());
}
else {
- LogPrint("estimatefee", "not adding\n");
+ LogPrint("estimatefee", "not adding");
}
+ LogPrint("estimatefee", "\n");
}
void CBlockPolicyEstimator::processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry& entry)
diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp
index af6801919c..8bd1586446 100644
--- a/src/qt/addressbookpage.cpp
+++ b/src/qt/addressbookpage.cpp
@@ -14,14 +14,14 @@
#include "csvmodelwriter.h"
#include "editaddressdialog.h"
#include "guiutil.h"
-#include "scicon.h"
+#include "platformstyle.h"
#include <QIcon>
#include <QMenu>
#include <QMessageBox>
#include <QSortFilterProxyModel>
-AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
+AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode mode, Tabs tab, QWidget *parent) :
QDialog(parent),
ui(new Ui::AddressBookPage),
model(0),
@@ -30,17 +30,17 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
{
ui->setupUi(this);
-#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
- ui->newAddress->setIcon(QIcon());
- ui->copyAddress->setIcon(QIcon());
- ui->deleteAddress->setIcon(QIcon());
- ui->exportButton->setIcon(QIcon());
-#else
- ui->newAddress->setIcon(SingleColorIcon(":/icons/add"));
- ui->copyAddress->setIcon(SingleColorIcon(":/icons/editcopy"));
- ui->deleteAddress->setIcon(SingleColorIcon(":/icons/remove"));
- ui->exportButton->setIcon(SingleColorIcon(":/icons/export"));
-#endif
+ if (!platformStyle->getImagesOnButtons()) {
+ ui->newAddress->setIcon(QIcon());
+ ui->copyAddress->setIcon(QIcon());
+ ui->deleteAddress->setIcon(QIcon());
+ ui->exportButton->setIcon(QIcon());
+ } else {
+ ui->newAddress->setIcon(platformStyle->SingleColorIcon(":/icons/add"));
+ ui->copyAddress->setIcon(platformStyle->SingleColorIcon(":/icons/editcopy"));
+ ui->deleteAddress->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
+ ui->exportButton->setIcon(platformStyle->SingleColorIcon(":/icons/export"));
+ }
switch(mode)
{
diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h
index 09634ce336..92e6cab9ac 100644
--- a/src/qt/addressbookpage.h
+++ b/src/qt/addressbookpage.h
@@ -9,6 +9,7 @@
class AddressTableModel;
class OptionsModel;
+class PlatformStyle;
namespace Ui {
class AddressBookPage;
@@ -39,7 +40,7 @@ public:
ForEditing /**< Open address book for editing */
};
- explicit AddressBookPage(Mode mode, Tabs tab, QWidget *parent);
+ explicit AddressBookPage(const PlatformStyle *platformStyle, Mode mode, Tabs tab, QWidget *parent);
~AddressBookPage();
void setModel(AddressTableModel *model);
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index b8aec0c268..1da2d3e344 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -15,6 +15,7 @@
#include "intro.h"
#include "networkstyle.h"
#include "optionsmodel.h"
+#include "platformstyle.h"
#include "splashscreen.h"
#include "utilitydialog.h"
#include "winshutdownmonitor.h"
@@ -241,6 +242,7 @@ private:
WalletModel *walletModel;
#endif
int returnValue;
+ const PlatformStyle *platformStyle;
void startThread();
};
@@ -310,6 +312,22 @@ BitcoinApplication::BitcoinApplication(int &argc, char **argv):
returnValue(0)
{
setQuitOnLastWindowClosed(false);
+
+ // UI per-platform customization
+ // This must be done inside the BitcoinApplication constructor, or after it, because
+ // PlatformStyle::instantiate requires a QApplication
+#if defined(Q_OS_MAC)
+ std::string platformName = "macosx";
+#elif defined(Q_OS_WIN)
+ std::string platformName = "windows";
+#else
+ std::string platformName = "other";
+#endif
+ platformName = GetArg("-uiplatform", platformName);
+ platformStyle = PlatformStyle::instantiate(QString::fromStdString(platformName));
+ if (!platformStyle) // Fall back to "other" if specified name not found
+ platformStyle = PlatformStyle::instantiate("other");
+ assert(platformStyle);
}
BitcoinApplication::~BitcoinApplication()
@@ -330,6 +348,8 @@ BitcoinApplication::~BitcoinApplication()
#endif
delete optionsModel;
optionsModel = 0;
+ delete platformStyle;
+ platformStyle = 0;
}
#ifdef ENABLE_WALLET
@@ -346,7 +366,7 @@ void BitcoinApplication::createOptionsModel()
void BitcoinApplication::createWindow(const NetworkStyle *networkStyle)
{
- window = new BitcoinGUI(networkStyle, 0);
+ window = new BitcoinGUI(platformStyle, networkStyle, 0);
pollShutdownTimer = new QTimer(window);
connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown()));
@@ -421,6 +441,8 @@ void BitcoinApplication::initializeResult(int retval)
returnValue = retval ? 0 : 1;
if(retval)
{
+ // Log this only after AppInit2 finishes, as then logging setup is guaranteed complete
+ qWarning() << "Platform customization:" << platformStyle->getName();
#ifdef ENABLE_WALLET
PaymentServer::LoadRootCAs();
paymentServer->setOptionsModel(optionsModel);
@@ -432,7 +454,7 @@ void BitcoinApplication::initializeResult(int retval)
#ifdef ENABLE_WALLET
if(pwalletMain)
{
- walletModel = new WalletModel(pwalletMain, optionsModel);
+ walletModel = new WalletModel(platformStyle, pwalletMain, optionsModel);
window->addWallet(BitcoinGUI::DEFAULT_WALLET, walletModel);
window->setCurrentWallet(BitcoinGUI::DEFAULT_WALLET);
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 396435f12b..1d3f7762ab 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -13,8 +13,8 @@
#include "openuridialog.h"
#include "optionsdialog.h"
#include "optionsmodel.h"
+#include "platformstyle.h"
#include "rpcconsole.h"
-#include "scicon.h"
#include "utilitydialog.h"
#ifdef ENABLE_WALLET
@@ -60,7 +60,7 @@
const QString BitcoinGUI::DEFAULT_WALLET = "~Default";
-BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
+BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent) :
QMainWindow(parent),
clientModel(0),
walletFrame(0),
@@ -98,7 +98,8 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
notificator(0),
rpcConsole(0),
prevBlocks(0),
- spinnerFrame(0)
+ spinnerFrame(0),
+ platformStyle(platformStyle)
{
GUIUtil::restoreWindowGeometry("nWindow", QSize(850, 550), this);
@@ -130,12 +131,12 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
setUnifiedTitleAndToolBarOnMac(true);
#endif
- rpcConsole = new RPCConsole(0);
+ rpcConsole = new RPCConsole(platformStyle, 0);
#ifdef ENABLE_WALLET
if(enableWallet)
{
/** Create wallet frame and make it the central widget */
- walletFrame = new WalletFrame(this);
+ walletFrame = new WalletFrame(platformStyle, this);
setCentralWidget(walletFrame);
} else
#endif // ENABLE_WALLET
@@ -175,7 +176,7 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks);
frameBlocksLayout->setContentsMargins(3,0,3,0);
frameBlocksLayout->setSpacing(3);
- unitDisplayControl = new UnitDisplayStatusBarControl();
+ unitDisplayControl = new UnitDisplayStatusBarControl(platformStyle);
labelEncryptionIcon = new QLabel();
labelConnectionsIcon = new QLabel();
labelBlocksIcon = new QLabel();
@@ -247,36 +248,36 @@ void BitcoinGUI::createActions()
{
QActionGroup *tabGroup = new QActionGroup(this);
- overviewAction = new QAction(SingleColorIcon(":/icons/overview"), tr("&Overview"), this);
+ overviewAction = new QAction(platformStyle->SingleColorIcon(":/icons/overview"), tr("&Overview"), this);
overviewAction->setStatusTip(tr("Show general overview of wallet"));
overviewAction->setToolTip(overviewAction->statusTip());
overviewAction->setCheckable(true);
overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1));
tabGroup->addAction(overviewAction);
- sendCoinsAction = new QAction(SingleColorIcon(":/icons/send"), tr("&Send"), this);
+ sendCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/send"), tr("&Send"), this);
sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address"));
sendCoinsAction->setToolTip(sendCoinsAction->statusTip());
sendCoinsAction->setCheckable(true);
sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
tabGroup->addAction(sendCoinsAction);
- sendCoinsMenuAction = new QAction(TextColorIcon(":/icons/send"), sendCoinsAction->text(), this);
+ sendCoinsMenuAction = new QAction(platformStyle->TextColorIcon(":/icons/send"), sendCoinsAction->text(), this);
sendCoinsMenuAction->setStatusTip(sendCoinsAction->statusTip());
sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip());
- receiveCoinsAction = new QAction(SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this);
+ receiveCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this);
receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)"));
receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
receiveCoinsAction->setCheckable(true);
receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3));
tabGroup->addAction(receiveCoinsAction);
- receiveCoinsMenuAction = new QAction(TextColorIcon(":/icons/receiving_addresses"), receiveCoinsAction->text(), this);
+ receiveCoinsMenuAction = new QAction(platformStyle->TextColorIcon(":/icons/receiving_addresses"), receiveCoinsAction->text(), this);
receiveCoinsMenuAction->setStatusTip(receiveCoinsAction->statusTip());
receiveCoinsMenuAction->setToolTip(receiveCoinsMenuAction->statusTip());
- historyAction = new QAction(SingleColorIcon(":/icons/history"), tr("&Transactions"), this);
+ historyAction = new QAction(platformStyle->SingleColorIcon(":/icons/history"), tr("&Transactions"), this);
historyAction->setStatusTip(tr("Browse transaction history"));
historyAction->setToolTip(historyAction->statusTip());
historyAction->setCheckable(true);
@@ -300,46 +301,46 @@ void BitcoinGUI::createActions()
connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
#endif // ENABLE_WALLET
- quitAction = new QAction(TextColorIcon(":/icons/quit"), tr("E&xit"), this);
+ quitAction = new QAction(platformStyle->TextColorIcon(":/icons/quit"), tr("E&xit"), this);
quitAction->setStatusTip(tr("Quit application"));
quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
quitAction->setMenuRole(QAction::QuitRole);
- aboutAction = new QAction(TextColorIcon(":/icons/about"), tr("&About Bitcoin Core"), this);
+ aboutAction = new QAction(platformStyle->TextColorIcon(":/icons/about"), tr("&About Bitcoin Core"), this);
aboutAction->setStatusTip(tr("Show information about Bitcoin Core"));
aboutAction->setMenuRole(QAction::AboutRole);
- aboutQtAction = new QAction(TextColorIcon(":/icons/about_qt"), tr("About &Qt"), this);
+ aboutQtAction = new QAction(platformStyle->TextColorIcon(":/icons/about_qt"), tr("About &Qt"), this);
aboutQtAction->setStatusTip(tr("Show information about Qt"));
aboutQtAction->setMenuRole(QAction::AboutQtRole);
- optionsAction = new QAction(TextColorIcon(":/icons/options"), tr("&Options..."), this);
+ optionsAction = new QAction(platformStyle->TextColorIcon(":/icons/options"), tr("&Options..."), this);
optionsAction->setStatusTip(tr("Modify configuration options for Bitcoin Core"));
optionsAction->setMenuRole(QAction::PreferencesRole);
- toggleHideAction = new QAction(TextColorIcon(":/icons/about"), tr("&Show / Hide"), this);
+ toggleHideAction = new QAction(platformStyle->TextColorIcon(":/icons/about"), tr("&Show / Hide"), this);
toggleHideAction->setStatusTip(tr("Show or hide the main Window"));
- encryptWalletAction = new QAction(TextColorIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this);
+ encryptWalletAction = new QAction(platformStyle->TextColorIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this);
encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet"));
encryptWalletAction->setCheckable(true);
- backupWalletAction = new QAction(TextColorIcon(":/icons/filesave"), tr("&Backup Wallet..."), this);
+ backupWalletAction = new QAction(platformStyle->TextColorIcon(":/icons/filesave"), tr("&Backup Wallet..."), this);
backupWalletAction->setStatusTip(tr("Backup wallet to another location"));
- changePassphraseAction = new QAction(TextColorIcon(":/icons/key"), tr("&Change Passphrase..."), this);
+ changePassphraseAction = new QAction(platformStyle->TextColorIcon(":/icons/key"), tr("&Change Passphrase..."), this);
changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption"));
- signMessageAction = new QAction(TextColorIcon(":/icons/edit"), tr("Sign &message..."), this);
+ signMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/edit"), tr("Sign &message..."), this);
signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them"));
- verifyMessageAction = new QAction(TextColorIcon(":/icons/verify"), tr("&Verify message..."), this);
+ verifyMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/verify"), tr("&Verify message..."), this);
verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses"));
- openRPCConsoleAction = new QAction(TextColorIcon(":/icons/debugwindow"), tr("&Debug window"), this);
+ openRPCConsoleAction = new QAction(platformStyle->TextColorIcon(":/icons/debugwindow"), tr("&Debug window"), this);
openRPCConsoleAction->setStatusTip(tr("Open debugging and diagnostic console"));
- usedSendingAddressesAction = new QAction(TextColorIcon(":/icons/address-book"), tr("&Sending addresses..."), this);
+ usedSendingAddressesAction = new QAction(platformStyle->TextColorIcon(":/icons/address-book"), tr("&Sending addresses..."), this);
usedSendingAddressesAction->setStatusTip(tr("Show the list of used sending addresses and labels"));
- usedReceivingAddressesAction = new QAction(TextColorIcon(":/icons/address-book"), tr("&Receiving addresses..."), this);
+ usedReceivingAddressesAction = new QAction(platformStyle->TextColorIcon(":/icons/address-book"), tr("&Receiving addresses..."), this);
usedReceivingAddressesAction->setStatusTip(tr("Show the list of used receiving addresses and labels"));
- openAction = new QAction(TextColorIcon(":/icons/open"), tr("Open &URI..."), this);
+ openAction = new QAction(platformStyle->TextColorIcon(":/icons/open"), tr("Open &URI..."), this);
openAction->setStatusTip(tr("Open a bitcoin: URI or payment request"));
- showHelpMessageAction = new QAction(TextColorIcon(":/icons/info"), tr("&Command-line options"), this);
+ showHelpMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/info"), tr("&Command-line options"), this);
showHelpMessageAction->setMenuRole(QAction::NoRole);
showHelpMessageAction->setStatusTip(tr("Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options"));
@@ -650,7 +651,7 @@ void BitcoinGUI::setNumConnections(int count)
case 7: case 8: case 9: icon = ":/icons/connect_3"; break;
default: icon = ":/icons/connect_4"; break;
}
- labelConnectionsIcon->setPixmap(SingleColorIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+ labelConnectionsIcon->setPixmap(platformStyle->SingleColorIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count));
}
@@ -691,7 +692,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate)
if(secs < 90*60)
{
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
- labelBlocksIcon->setPixmap(SingleColorIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
+ labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
#ifdef ENABLE_WALLET
if(walletFrame)
@@ -737,7 +738,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate)
tooltip = tr("Catching up...") + QString("<br>") + tooltip;
if(count != prevBlocks)
{
- labelBlocksIcon->setPixmap(SingleColorIcon(QString(
+ labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(QString(
":/movies/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0')))
.pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
spinnerFrame = (spinnerFrame + 1) % SPINNER_FRAMES;
@@ -931,7 +932,7 @@ void BitcoinGUI::setEncryptionStatus(int status)
break;
case WalletModel::Unlocked:
labelEncryptionIcon->show();
- labelEncryptionIcon->setPixmap(SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+ labelEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
encryptWalletAction->setChecked(true);
changePassphraseAction->setEnabled(true);
@@ -939,7 +940,7 @@ void BitcoinGUI::setEncryptionStatus(int status)
break;
case WalletModel::Locked:
labelEncryptionIcon->show();
- labelEncryptionIcon->setPixmap(SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+ labelEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
encryptWalletAction->setChecked(true);
changePassphraseAction->setEnabled(true);
@@ -1041,7 +1042,7 @@ void BitcoinGUI::unsubscribeFromCoreSignals()
uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
}
-UnitDisplayStatusBarControl::UnitDisplayStatusBarControl() :
+UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(const PlatformStyle *platformStyle) :
optionsModel(0),
menu(0)
{
@@ -1056,7 +1057,7 @@ UnitDisplayStatusBarControl::UnitDisplayStatusBarControl() :
}
setMinimumSize(max_width, 0);
setAlignment(Qt::AlignRight | Qt::AlignVCenter);
- setStyleSheet(QString("QLabel { color : %1 }").arg(SingleColor().name()));
+ setStyleSheet(QString("QLabel { color : %1 }").arg(platformStyle->SingleColor().name()));
}
/** So that it responds to button clicks */
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index 4e50b1712a..dd0d4bb0e2 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -22,6 +22,7 @@ class ClientModel;
class NetworkStyle;
class Notificator;
class OptionsModel;
+class PlatformStyle;
class RPCConsole;
class SendCoinsRecipient;
class UnitDisplayStatusBarControl;
@@ -47,7 +48,7 @@ class BitcoinGUI : public QMainWindow
public:
static const QString DEFAULT_WALLET;
- explicit BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent = 0);
+ explicit BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent = 0);
~BitcoinGUI();
/** Set the client model.
@@ -117,6 +118,8 @@ private:
int prevBlocks;
int spinnerFrame;
+ const PlatformStyle *platformStyle;
+
/** Create the main UI actions. */
void createActions();
/** Create the menu bar and sub-menus. */
@@ -215,7 +218,7 @@ class UnitDisplayStatusBarControl : public QLabel
Q_OBJECT
public:
- explicit UnitDisplayStatusBarControl();
+ explicit UnitDisplayStatusBarControl(const PlatformStyle *platformStyle);
/** Lets the control know about the Options Model (and its signals) */
void setOptionsModel(OptionsModel *optionsModel);
diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
index 934d62d5f7..51008ad2de 100644
--- a/src/qt/coincontroldialog.cpp
+++ b/src/qt/coincontroldialog.cpp
@@ -9,7 +9,7 @@
#include "bitcoinunits.h"
#include "guiutil.h"
#include "optionsmodel.h"
-#include "scicon.h"
+#include "platformstyle.h"
#include "txmempool.h"
#include "walletmodel.h"
@@ -35,10 +35,11 @@ QList<CAmount> CoinControlDialog::payAmounts;
CCoinControl* CoinControlDialog::coinControl = new CCoinControl();
bool CoinControlDialog::fSubtractFeeFromAmount = false;
-CoinControlDialog::CoinControlDialog(QWidget *parent) :
+CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent) :
QDialog(parent),
ui(new Ui::CoinControlDialog),
- model(0)
+ model(0),
+ platformStyle(platformStyle)
{
ui->setupUi(this);
@@ -280,7 +281,7 @@ void CoinControlDialog::lockCoin()
COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
model->lockCoin(outpt);
contextMenuItem->setDisabled(true);
- contextMenuItem->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed"));
+ contextMenuItem->setIcon(COLUMN_CHECKBOX, platformStyle->SingleColorIcon(":/icons/lock_closed"));
updateLabelLocked();
}
@@ -791,7 +792,7 @@ void CoinControlDialog::updateView()
COutPoint outpt(txhash, out.i);
coinControl->UnSelect(outpt); // just to be sure
itemOutput->setDisabled(true);
- itemOutput->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed"));
+ itemOutput->setIcon(COLUMN_CHECKBOX, platformStyle->SingleColorIcon(":/icons/lock_closed"));
}
// set checkbox
diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h
index 0566b02c96..8ff1eac709 100644
--- a/src/qt/coincontroldialog.h
+++ b/src/qt/coincontroldialog.h
@@ -16,6 +16,7 @@
#include <QString>
#include <QTreeWidgetItem>
+class PlatformStyle;
class WalletModel;
class CCoinControl;
@@ -32,7 +33,7 @@ class CoinControlDialog : public QDialog
Q_OBJECT
public:
- explicit CoinControlDialog(QWidget *parent = 0);
+ explicit CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent = 0);
~CoinControlDialog();
void setModel(WalletModel *model);
@@ -57,6 +58,8 @@ private:
QAction *lockAction;
QAction *unlockAction;
+ const PlatformStyle *platformStyle;
+
QString strPad(QString, int, QString);
void sortView(int, Qt::SortOrder);
void updateView();
diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp
index 117969758c..4ab87e0f32 100644
--- a/src/qt/intro.cpp
+++ b/src/qt/intro.cpp
@@ -6,7 +6,6 @@
#include "ui_intro.h"
#include "guiutil.h"
-#include "scicon.h"
#include "util.h"
@@ -168,7 +167,7 @@ void Intro::pickDataDirectory()
/* If current default data directory does not exist, let the user choose one */
Intro intro;
intro.setDataDirectory(dataDir);
- intro.setWindowIcon(SingleColorIcon(":icons/bitcoin"));
+ intro.setWindowIcon(QIcon(":icons/bitcoin"));
while(true)
{
diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp
index e28f903b2e..4541c75886 100644
--- a/src/qt/networkstyle.cpp
+++ b/src/qt/networkstyle.cpp
@@ -5,7 +5,6 @@
#include "networkstyle.h"
#include "guiconstants.h"
-#include "scicon.h"
#include <QApplication>
diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp
index bbd95ef478..a56c80ac63 100644
--- a/src/qt/overviewpage.cpp
+++ b/src/qt/overviewpage.cpp
@@ -10,7 +10,7 @@
#include "guiconstants.h"
#include "guiutil.h"
#include "optionsmodel.h"
-#include "scicon.h"
+#include "platformstyle.h"
#include "transactionfilterproxy.h"
#include "transactiontablemodel.h"
#include "walletmodel.h"
@@ -25,7 +25,9 @@ class TxViewDelegate : public QAbstractItemDelegate
{
Q_OBJECT
public:
- TxViewDelegate(): QAbstractItemDelegate(), unit(BitcoinUnits::BTC)
+ TxViewDelegate(const PlatformStyle *platformStyle):
+ QAbstractItemDelegate(), unit(BitcoinUnits::BTC),
+ platformStyle(platformStyle)
{
}
@@ -43,7 +45,7 @@ public:
int halfheight = (mainRect.height() - 2*ypad)/2;
QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight);
QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight);
- icon = SingleColorIcon(icon, SingleColor());
+ icon = platformStyle->SingleColorIcon(icon);
icon.paint(painter, decorationRect);
QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime();
@@ -101,11 +103,12 @@ public:
}
int unit;
+ const PlatformStyle *platformStyle;
};
#include "overviewpage.moc"
-OverviewPage::OverviewPage(QWidget *parent) :
+OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) :
QWidget(parent),
ui(new Ui::OverviewPage),
clientModel(0),
@@ -116,13 +119,13 @@ OverviewPage::OverviewPage(QWidget *parent) :
currentWatchOnlyBalance(-1),
currentWatchUnconfBalance(-1),
currentWatchImmatureBalance(-1),
- txdelegate(new TxViewDelegate()),
+ txdelegate(new TxViewDelegate(platformStyle)),
filter(0)
{
ui->setupUi(this);
// use a SingleColorIcon for the "out of sync warning" icon
- QIcon icon = SingleColorIcon(":/icons/warning");
+ QIcon icon = platformStyle->SingleColorIcon(":/icons/warning");
icon.addPixmap(icon.pixmap(QSize(64,64), QIcon::Normal), QIcon::Disabled); // also set the disabled icon because we are using a disabled QPushButton to work around missing HiDPI support of QLabel (https://bugreports.qt.io/browse/QTBUG-42503)
ui->labelTransactionsStatus->setIcon(icon);
ui->labelWalletStatus->setIcon(icon);
diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h
index de5ac345da..4139eb35d3 100644
--- a/src/qt/overviewpage.h
+++ b/src/qt/overviewpage.h
@@ -12,6 +12,7 @@
class ClientModel;
class TransactionFilterProxy;
class TxViewDelegate;
+class PlatformStyle;
class WalletModel;
namespace Ui {
@@ -28,7 +29,7 @@ class OverviewPage : public QWidget
Q_OBJECT
public:
- explicit OverviewPage(QWidget *parent = 0);
+ explicit OverviewPage(const PlatformStyle *platformStyle, QWidget *parent = 0);
~OverviewPage();
void setClientModel(ClientModel *clientModel);
diff --git a/src/qt/platformstyle.cpp b/src/qt/platformstyle.cpp
new file mode 100644
index 0000000000..11cbc7a47c
--- /dev/null
+++ b/src/qt/platformstyle.cpp
@@ -0,0 +1,147 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "platformstyle.h"
+
+#include "guiconstants.h"
+
+#include <QApplication>
+#include <QColor>
+#include <QIcon>
+#include <QImage>
+#include <QPalette>
+#include <QPixmap>
+
+static const struct {
+ const char *platformId;
+ /** Show images on push buttons */
+ const bool imagesOnButtons;
+ /** Colorize single-color icons */
+ const bool colorizeIcons;
+ /** Extra padding/spacing in transactionview */
+ const bool useExtraSpacing;
+} platform_styles[] = {
+ {"macosx", false, false, true},
+ {"windows", true, false, false},
+ /* Other: linux, unix, ... */
+ {"other", true, true, false}
+};
+static const unsigned platform_styles_count = sizeof(platform_styles)/sizeof(*platform_styles);
+
+namespace {
+/* Local functions for colorizing single-color images */
+
+void MakeSingleColorImage(QImage& img, const QColor& colorbase)
+{
+ img = img.convertToFormat(QImage::Format_ARGB32);
+ for (int x = img.width(); x--; )
+ {
+ for (int y = img.height(); y--; )
+ {
+ const QRgb rgb = img.pixel(x, y);
+ img.setPixel(x, y, qRgba(colorbase.red(), colorbase.green(), colorbase.blue(), qAlpha(rgb)));
+ }
+ }
+}
+
+QIcon ColorizeIcon(const QIcon& ico, const QColor& colorbase)
+{
+ QIcon new_ico;
+ QSize sz;
+ Q_FOREACH(sz, ico.availableSizes())
+ {
+ QImage img(ico.pixmap(sz).toImage());
+ MakeSingleColorImage(img, colorbase);
+ new_ico.addPixmap(QPixmap::fromImage(img));
+ }
+ return new_ico;
+}
+
+QImage ColorizeImage(const QString& filename, const QColor& colorbase)
+{
+ QImage img(filename);
+ MakeSingleColorImage(img, colorbase);
+ return img;
+}
+
+QIcon ColorizeIcon(const QString& filename, const QColor& colorbase)
+{
+ return QIcon(QPixmap::fromImage(ColorizeImage(filename, colorbase)));
+}
+
+}
+
+
+PlatformStyle::PlatformStyle(const QString &name, bool imagesOnButtons, bool colorizeIcons, bool useExtraSpacing):
+ name(name),
+ imagesOnButtons(imagesOnButtons),
+ colorizeIcons(colorizeIcons),
+ useExtraSpacing(useExtraSpacing),
+ singleColor(0,0,0),
+ textColor(0,0,0)
+{
+ // Determine icon highlighting color
+ if (colorizeIcons) {
+ const QColor colorHighlightBg(QApplication::palette().color(QPalette::Highlight));
+ const QColor colorHighlightFg(QApplication::palette().color(QPalette::HighlightedText));
+ const QColor colorText(QApplication::palette().color(QPalette::WindowText));
+ const int colorTextLightness = colorText.lightness();
+ QColor colorbase;
+ if (abs(colorHighlightBg.lightness() - colorTextLightness) < abs(colorHighlightFg.lightness() - colorTextLightness))
+ colorbase = colorHighlightBg;
+ else
+ colorbase = colorHighlightFg;
+ singleColor = colorbase;
+ }
+ // Determine text color
+ textColor = QColor(QApplication::palette().color(QPalette::WindowText));
+}
+
+QImage PlatformStyle::SingleColorImage(const QString& filename) const
+{
+ if (!colorizeIcons)
+ return QImage(filename);
+ return ColorizeImage(filename, SingleColor());
+}
+
+QIcon PlatformStyle::SingleColorIcon(const QString& filename) const
+{
+ if (!colorizeIcons)
+ return QIcon(filename);
+ return ColorizeIcon(filename, SingleColor());
+}
+
+QIcon PlatformStyle::SingleColorIcon(const QIcon& icon) const
+{
+ if (!colorizeIcons)
+ return icon;
+ return ColorizeIcon(icon, SingleColor());
+}
+
+QIcon PlatformStyle::TextColorIcon(const QString& filename) const
+{
+ return ColorizeIcon(filename, TextColor());
+}
+
+QIcon PlatformStyle::TextColorIcon(const QIcon& icon) const
+{
+ return ColorizeIcon(icon, TextColor());
+}
+
+const PlatformStyle *PlatformStyle::instantiate(const QString &platformId)
+{
+ for (unsigned x=0; x<platform_styles_count; ++x)
+ {
+ if (platformId == platform_styles[x].platformId)
+ {
+ return new PlatformStyle(
+ platform_styles[x].platformId,
+ platform_styles[x].imagesOnButtons,
+ platform_styles[x].colorizeIcons,
+ platform_styles[x].useExtraSpacing);
+ }
+ }
+ return 0;
+}
+
diff --git a/src/qt/platformstyle.h b/src/qt/platformstyle.h
new file mode 100644
index 0000000000..4e763e760e
--- /dev/null
+++ b/src/qt/platformstyle.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_PLATFORMSTYLE_H
+#define BITCOIN_QT_PLATFORMSTYLE_H
+
+#include <QIcon>
+#include <QPixmap>
+#include <QString>
+
+/* Coin network-specific GUI style information */
+class PlatformStyle
+{
+public:
+ /** Get style associated with provided platform name, or 0 if not known */
+ static const PlatformStyle *instantiate(const QString &platformId);
+
+ const QString &getName() const { return name; }
+
+ bool getImagesOnButtons() const { return imagesOnButtons; }
+ bool getUseExtraSpacing() const { return useExtraSpacing; }
+
+ QColor TextColor() const { return textColor; }
+ QColor SingleColor() const { return singleColor; }
+
+ /** Colorize an image (given filename) with the icon color */
+ QImage SingleColorImage(const QString& filename) const;
+
+ /** Colorize an icon (given filename) with the icon color */
+ QIcon SingleColorIcon(const QString& filename) const;
+
+ /** Colorize an icon (given object) with the icon color */
+ QIcon SingleColorIcon(const QIcon& icon) const;
+
+ /** Colorize an icon (given filename) with the text color */
+ QIcon TextColorIcon(const QString& filename) const;
+
+ /** Colorize an icon (given object) with the text color */
+ QIcon TextColorIcon(const QIcon& icon) const;
+
+private:
+ PlatformStyle(const QString &name, bool imagesOnButtons, bool colorizeIcons, bool useExtraSpacing);
+
+ QString name;
+ bool imagesOnButtons;
+ bool colorizeIcons;
+ bool useExtraSpacing;
+ QColor singleColor;
+ QColor textColor;
+ /* ... more to come later */
+};
+
+#endif // BITCOIN_QT_PLATFORMSTYLE_H
+
diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp
index 43b46c63b5..7fb68cc32a 100644
--- a/src/qt/receivecoinsdialog.cpp
+++ b/src/qt/receivecoinsdialog.cpp
@@ -10,9 +10,9 @@
#include "bitcoinunits.h"
#include "guiutil.h"
#include "optionsmodel.h"
+#include "platformstyle.h"
#include "receiverequestdialog.h"
#include "recentrequeststablemodel.h"
-#include "scicon.h"
#include "walletmodel.h"
#include <QAction>
@@ -22,24 +22,25 @@
#include <QScrollBar>
#include <QTextDocument>
-ReceiveCoinsDialog::ReceiveCoinsDialog(QWidget *parent) :
+ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) :
QDialog(parent),
ui(new Ui::ReceiveCoinsDialog),
- model(0)
+ model(0),
+ platformStyle(platformStyle)
{
ui->setupUi(this);
-#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
- ui->clearButton->setIcon(QIcon());
- ui->receiveButton->setIcon(QIcon());
- ui->showRequestButton->setIcon(QIcon());
- ui->removeRequestButton->setIcon(QIcon());
-#else
- ui->clearButton->setIcon(SingleColorIcon(":/icons/remove"));
- ui->receiveButton->setIcon(SingleColorIcon(":/icons/receiving_addresses"));
- ui->showRequestButton->setIcon(SingleColorIcon(":/icons/edit"));
- ui->removeRequestButton->setIcon(SingleColorIcon(":/icons/remove"));
-#endif
+ if (!platformStyle->getImagesOnButtons()) {
+ ui->clearButton->setIcon(QIcon());
+ ui->receiveButton->setIcon(QIcon());
+ ui->showRequestButton->setIcon(QIcon());
+ ui->removeRequestButton->setIcon(QIcon());
+ } else {
+ ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
+ ui->receiveButton->setIcon(platformStyle->SingleColorIcon(":/icons/receiving_addresses"));
+ ui->showRequestButton->setIcon(platformStyle->SingleColorIcon(":/icons/edit"));
+ ui->removeRequestButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
+ }
// context menu actions
QAction *copyLabelAction = new QAction(tr("Copy label"), this);
@@ -132,7 +133,7 @@ void ReceiveCoinsDialog::on_receiveButton_clicked()
if(ui->reuseAddress->isChecked())
{
/* Choose existing receiving address */
- AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this);
+ AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this);
dlg.setModel(model->getAddressTableModel());
if(dlg.exec())
{
diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h
index 6bb159482b..eaaf129a91 100644
--- a/src/qt/receivecoinsdialog.h
+++ b/src/qt/receivecoinsdialog.h
@@ -16,6 +16,7 @@
#include <QVariant>
class OptionsModel;
+class PlatformStyle;
class WalletModel;
namespace Ui {
@@ -39,7 +40,7 @@ public:
MINIMUM_COLUMN_WIDTH = 130
};
- explicit ReceiveCoinsDialog(QWidget *parent = 0);
+ explicit ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent = 0);
~ReceiveCoinsDialog();
void setModel(WalletModel *model);
@@ -57,6 +58,8 @@ private:
GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer;
WalletModel *model;
QMenu *contextMenu;
+ const PlatformStyle *platformStyle;
+
void copyColumnToClipboard(int column);
virtual void resizeEvent(QResizeEvent *event);
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index b2717558ca..3231b392f2 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -8,7 +8,7 @@
#include "clientmodel.h"
#include "guiutil.h"
#include "peertablemodel.h"
-#include "scicon.h"
+#include "platformstyle.h"
#include "chainparams.h"
#include "rpcserver.h"
@@ -200,21 +200,22 @@ void RPCExecutor::request(const QString &command)
}
}
-RPCConsole::RPCConsole(QWidget *parent) :
+RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) :
QWidget(parent),
ui(new Ui::RPCConsole),
clientModel(0),
historyPtr(0),
cachedNodeid(-1),
- contextMenu(0)
+ contextMenu(0),
+ platformStyle(platformStyle)
{
ui->setupUi(this);
GUIUtil::restoreWindowGeometry("nRPCConsoleWindow", this->size(), this);
-#ifndef Q_OS_MAC
- ui->openDebugLogfileButton->setIcon(SingleColorIcon(":/icons/export"));
-#endif
- ui->clearButton->setIcon(SingleColorIcon(":/icons/remove"));
+ if (platformStyle->getImagesOnButtons()) {
+ ui->openDebugLogfileButton->setIcon(platformStyle->SingleColorIcon(":/icons/export"));
+ }
+ ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
// Install event filter for up and down arrow
ui->lineEdit->installEventFilter(this);
@@ -363,7 +364,7 @@ void RPCConsole::clear()
ui->messagesWidget->document()->addResource(
QTextDocument::ImageResource,
QUrl(ICON_MAPPING[i].url),
- SingleColorImage(ICON_MAPPING[i].source, SingleColor()).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+ platformStyle->SingleColorImage(ICON_MAPPING[i].source).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
}
// Set default style sheet
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index 6f42aa08b7..b94efee84a 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -13,6 +13,7 @@
#include <QWidget>
class ClientModel;
+class PlatformStyle;
namespace Ui {
class RPCConsole;
@@ -29,7 +30,7 @@ class RPCConsole: public QWidget
Q_OBJECT
public:
- explicit RPCConsole(QWidget *parent);
+ explicit RPCConsole(const PlatformStyle *platformStyle, QWidget *parent);
~RPCConsole();
void setClientModel(ClientModel *model);
@@ -106,6 +107,7 @@ private:
int historyPtr;
NodeId cachedNodeid;
QMenu *contextMenu;
+ const PlatformStyle *platformStyle;
};
#endif // BITCOIN_QT_RPCCONSOLE_H
diff --git a/src/qt/scicon.cpp b/src/qt/scicon.cpp
deleted file mode 100644
index c493b5569e..0000000000
--- a/src/qt/scicon.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2014 The Bitcoin developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#include "scicon.h"
-
-#include <QApplication>
-#include <QColor>
-#include <QIcon>
-#include <QImage>
-#include <QPalette>
-#include <QPixmap>
-
-namespace {
-
-void MakeSingleColorImage(QImage& img, const QColor& colorbase)
-{
- img = img.convertToFormat(QImage::Format_ARGB32);
- for (int x = img.width(); x--; )
- {
- for (int y = img.height(); y--; )
- {
- const QRgb rgb = img.pixel(x, y);
- img.setPixel(x, y, qRgba(colorbase.red(), colorbase.green(), colorbase.blue(), qAlpha(rgb)));
- }
- }
-}
-
-}
-
-QImage SingleColorImage(const QString& filename, const QColor& colorbase)
-{
- QImage img(filename);
-#if !defined(WIN32) && !defined(MAC_OSX)
- MakeSingleColorImage(img, colorbase);
-#endif
- return img;
-}
-
-QIcon SingleColorIcon(const QIcon& ico, const QColor& colorbase)
-{
-#if defined(WIN32) || defined(MAC_OSX)
- return ico;
-#else
- QIcon new_ico;
- QSize sz;
- Q_FOREACH(sz, ico.availableSizes())
- {
- QImage img(ico.pixmap(sz).toImage());
- MakeSingleColorImage(img, colorbase);
- new_ico.addPixmap(QPixmap::fromImage(img));
- }
- return new_ico;
-#endif
-}
-
-QIcon SingleColorIcon(const QString& filename, const QColor& colorbase)
-{
- return QIcon(QPixmap::fromImage(SingleColorImage(filename, colorbase)));
-}
-
-QColor SingleColor()
-{
-#if defined(WIN32) || defined(MAC_OSX)
- return QColor(0,0,0);
-#else
- const QColor colorHighlightBg(QApplication::palette().color(QPalette::Highlight));
- const QColor colorHighlightFg(QApplication::palette().color(QPalette::HighlightedText));
- const QColor colorText(QApplication::palette().color(QPalette::WindowText));
- const int colorTextLightness = colorText.lightness();
- QColor colorbase;
- if (abs(colorHighlightBg.lightness() - colorTextLightness) < abs(colorHighlightFg.lightness() - colorTextLightness))
- colorbase = colorHighlightBg;
- else
- colorbase = colorHighlightFg;
- return colorbase;
-#endif
-}
-
-QIcon SingleColorIcon(const QString& filename)
-{
- return SingleColorIcon(filename, SingleColor());
-}
-
-static QColor TextColor()
-{
- return QColor(QApplication::palette().color(QPalette::WindowText));
-}
-
-QIcon TextColorIcon(const QString& filename)
-{
- return SingleColorIcon(filename, TextColor());
-}
-
-QIcon TextColorIcon(const QIcon& ico)
-{
- return SingleColorIcon(ico, TextColor());
-}
diff --git a/src/qt/scicon.h b/src/qt/scicon.h
deleted file mode 100644
index 1388069ddb..0000000000
--- a/src/qt/scicon.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2014 The Bitcoin developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#ifndef BITCOIN_QT_SCICON_H
-#define BITCOIN_QT_SCICON_H
-
-#include <QtCore>
-
-QT_BEGIN_NAMESPACE
-class QColor;
-class QIcon;
-class QString;
-QT_END_NAMESPACE
-
-QImage SingleColorImage(const QString& filename, const QColor&);
-QIcon SingleColorIcon(const QIcon&, const QColor&);
-QIcon SingleColorIcon(const QString& filename, const QColor&);
-QColor SingleColor();
-QIcon SingleColorIcon(const QString& filename);
-QIcon TextColorIcon(const QIcon&);
-QIcon TextColorIcon(const QString& filename);
-
-#endif // BITCOIN_QT_SCICON_H
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 2407fcbc4a..449a7bc5e8 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -11,7 +11,7 @@
#include "coincontroldialog.h"
#include "guiutil.h"
#include "optionsmodel.h"
-#include "scicon.h"
+#include "platformstyle.h"
#include "sendcoinsentry.h"
#include "walletmodel.h"
@@ -27,25 +27,26 @@
#include <QSettings>
#include <QTextDocument>
-SendCoinsDialog::SendCoinsDialog(QWidget *parent) :
+SendCoinsDialog::SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) :
QDialog(parent),
ui(new Ui::SendCoinsDialog),
clientModel(0),
model(0),
fNewRecipientAllowed(true),
- fFeeMinimized(true)
+ fFeeMinimized(true),
+ platformStyle(platformStyle)
{
ui->setupUi(this);
-#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
- ui->addButton->setIcon(QIcon());
- ui->clearButton->setIcon(QIcon());
- ui->sendButton->setIcon(QIcon());
-#else
- ui->addButton->setIcon(SingleColorIcon(":/icons/add"));
- ui->clearButton->setIcon(SingleColorIcon(":/icons/remove"));
- ui->sendButton->setIcon(SingleColorIcon(":/icons/send"));
-#endif
+ if (!platformStyle->getImagesOnButtons()) {
+ ui->addButton->setIcon(QIcon());
+ ui->clearButton->setIcon(QIcon());
+ ui->sendButton->setIcon(QIcon());
+ } else {
+ ui->addButton->setIcon(platformStyle->SingleColorIcon(":/icons/add"));
+ ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
+ ui->sendButton->setIcon(platformStyle->SingleColorIcon(":/icons/send"));
+ }
GUIUtil::setupAddressWidget(ui->lineEditCoinControlChange, this);
@@ -364,7 +365,7 @@ void SendCoinsDialog::accept()
SendCoinsEntry *SendCoinsDialog::addEntry()
{
- SendCoinsEntry *entry = new SendCoinsEntry(this);
+ SendCoinsEntry *entry = new SendCoinsEntry(platformStyle, this);
entry->setModel(model);
ui->entries->addWidget(entry);
connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*)));
@@ -711,7 +712,7 @@ void SendCoinsDialog::coinControlFeatureChanged(bool checked)
// Coin Control: button inputs -> show actual coin control dialog
void SendCoinsDialog::coinControlButtonClicked()
{
- CoinControlDialog dlg;
+ CoinControlDialog dlg(platformStyle);
dlg.setModel(model);
dlg.exec();
coinControlUpdateLabels();
diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h
index c833da84b2..391905ffcd 100644
--- a/src/qt/sendcoinsdialog.h
+++ b/src/qt/sendcoinsdialog.h
@@ -12,6 +12,7 @@
class ClientModel;
class OptionsModel;
+class PlatformStyle;
class SendCoinsEntry;
class SendCoinsRecipient;
@@ -31,7 +32,7 @@ class SendCoinsDialog : public QDialog
Q_OBJECT
public:
- explicit SendCoinsDialog(QWidget *parent = 0);
+ explicit SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent = 0);
~SendCoinsDialog();
void setClientModel(ClientModel *clientModel);
@@ -60,6 +61,7 @@ private:
WalletModel *model;
bool fNewRecipientAllowed;
bool fFeeMinimized;
+ const PlatformStyle *platformStyle;
// Process WalletModel::SendCoinsReturn and generate a pair consisting
// of a message and message flags for use in Q_EMIT message().
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index 90a8cbdc4e..44aa8ad1af 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -9,30 +9,30 @@
#include "addresstablemodel.h"
#include "guiutil.h"
#include "optionsmodel.h"
-#include "scicon.h"
+#include "platformstyle.h"
#include "walletmodel.h"
#include <QApplication>
#include <QClipboard>
-SendCoinsEntry::SendCoinsEntry(QWidget *parent) :
+SendCoinsEntry::SendCoinsEntry(const PlatformStyle *platformStyle, QWidget *parent) :
QStackedWidget(parent),
ui(new Ui::SendCoinsEntry),
- model(0)
+ model(0),
+ platformStyle(platformStyle)
{
ui->setupUi(this);
- ui->addressBookButton->setIcon(SingleColorIcon(":/icons/address-book"));
- ui->pasteButton->setIcon(SingleColorIcon(":/icons/editpaste"));
- ui->deleteButton->setIcon(SingleColorIcon(":/icons/remove"));
- ui->deleteButton_is->setIcon(SingleColorIcon(":/icons/remove"));
- ui->deleteButton_s->setIcon(SingleColorIcon(":/icons/remove"));
+ ui->addressBookButton->setIcon(platformStyle->SingleColorIcon(":/icons/address-book"));
+ ui->pasteButton->setIcon(platformStyle->SingleColorIcon(":/icons/editpaste"));
+ ui->deleteButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
+ ui->deleteButton_is->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
+ ui->deleteButton_s->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
setCurrentWidget(ui->SendCoins);
-#ifdef Q_OS_MAC
- ui->payToLayout->setSpacing(4);
-#endif
+ if (platformStyle->getUseExtraSpacing())
+ ui->payToLayout->setSpacing(4);
#if QT_VERSION >= 0x040700
ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book"));
#endif
@@ -65,7 +65,7 @@ void SendCoinsEntry::on_addressBookButton_clicked()
{
if(!model)
return;
- AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::SendingTab, this);
+ AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::SendingTab, this);
dlg.setModel(model->getAddressTableModel());
if(dlg.exec())
{
diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h
index d7e655fdc3..107ab70158 100644
--- a/src/qt/sendcoinsentry.h
+++ b/src/qt/sendcoinsentry.h
@@ -10,6 +10,7 @@
#include <QStackedWidget>
class WalletModel;
+class PlatformStyle;
namespace Ui {
class SendCoinsEntry;
@@ -25,7 +26,7 @@ class SendCoinsEntry : public QStackedWidget
Q_OBJECT
public:
- explicit SendCoinsEntry(QWidget *parent = 0);
+ explicit SendCoinsEntry(const PlatformStyle *platformStyle, QWidget *parent = 0);
~SendCoinsEntry();
void setModel(WalletModel *model);
@@ -64,6 +65,7 @@ private:
SendCoinsRecipient recipient;
Ui::SendCoinsEntry *ui;
WalletModel *model;
+ const PlatformStyle *platformStyle;
bool updateLabel(const QString &address);
};
diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp
index ce166f3672..60e8e36ebe 100644
--- a/src/qt/signverifymessagedialog.cpp
+++ b/src/qt/signverifymessagedialog.cpp
@@ -7,7 +7,7 @@
#include "addressbookpage.h"
#include "guiutil.h"
-#include "scicon.h"
+#include "platformstyle.h"
#include "walletmodel.h"
#include "base58.h"
@@ -20,21 +20,22 @@
#include <QClipboard>
-SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) :
+SignVerifyMessageDialog::SignVerifyMessageDialog(const PlatformStyle *platformStyle, QWidget *parent) :
QDialog(parent),
ui(new Ui::SignVerifyMessageDialog),
- model(0)
+ model(0),
+ platformStyle(platformStyle)
{
ui->setupUi(this);
- ui->addressBookButton_SM->setIcon(SingleColorIcon(":/icons/address-book"));
- ui->pasteButton_SM->setIcon(SingleColorIcon(":/icons/editpaste"));
- ui->copySignatureButton_SM->setIcon(SingleColorIcon(":/icons/editcopy"));
- ui->signMessageButton_SM->setIcon(SingleColorIcon(":/icons/edit"));
- ui->clearButton_SM->setIcon(SingleColorIcon(":/icons/remove"));
- ui->addressBookButton_VM->setIcon(SingleColorIcon(":/icons/address-book"));
- ui->verifyMessageButton_VM->setIcon(SingleColorIcon(":/icons/transaction_0"));
- ui->clearButton_VM->setIcon(SingleColorIcon(":/icons/remove"));
+ ui->addressBookButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/address-book"));
+ ui->pasteButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/editpaste"));
+ ui->copySignatureButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/editcopy"));
+ ui->signMessageButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/edit"));
+ ui->clearButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
+ ui->addressBookButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/address-book"));
+ ui->verifyMessageButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/transaction_0"));
+ ui->clearButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
#if QT_VERSION >= 0x040700
ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature"));
@@ -94,7 +95,7 @@ void SignVerifyMessageDialog::on_addressBookButton_SM_clicked()
{
if (model && model->getAddressTableModel())
{
- AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this);
+ AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this);
dlg.setModel(model->getAddressTableModel());
if (dlg.exec())
{
@@ -148,12 +149,12 @@ void SignVerifyMessageDialog::on_signMessageButton_SM_clicked()
return;
}
- CDataStream ss(SER_GETHASH, 0);
+ CHashWriter ss(SER_GETHASH, 0);
ss << strMessageMagic;
ss << ui->messageIn_SM->document()->toPlainText().toStdString();
std::vector<unsigned char> vchSig;
- if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig))
+ if (!key.SignCompact(ss.GetHash(), vchSig))
{
ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signing failed.") + QString("</nobr>"));
@@ -185,7 +186,7 @@ void SignVerifyMessageDialog::on_addressBookButton_VM_clicked()
{
if (model && model->getAddressTableModel())
{
- AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::SendingTab, this);
+ AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::SendingTab, this);
dlg.setModel(model->getAddressTableModel());
if (dlg.exec())
{
@@ -223,12 +224,12 @@ void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked()
return;
}
- CDataStream ss(SER_GETHASH, 0);
+ CHashWriter ss(SER_GETHASH, 0);
ss << strMessageMagic;
ss << ui->messageIn_VM->document()->toPlainText().toStdString();
CPubKey pubkey;
- if (!pubkey.RecoverCompact(Hash(ss.begin(), ss.end()), vchSig))
+ if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
{
ui->signatureIn_VM->setValid(false);
ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
diff --git a/src/qt/signverifymessagedialog.h b/src/qt/signverifymessagedialog.h
index bf841e4f8b..d651d5049b 100644
--- a/src/qt/signverifymessagedialog.h
+++ b/src/qt/signverifymessagedialog.h
@@ -7,6 +7,7 @@
#include <QDialog>
+class PlatformStyle;
class WalletModel;
namespace Ui {
@@ -18,7 +19,7 @@ class SignVerifyMessageDialog : public QDialog
Q_OBJECT
public:
- explicit SignVerifyMessageDialog(QWidget *parent);
+ explicit SignVerifyMessageDialog(const PlatformStyle *platformStyle, QWidget *parent);
~SignVerifyMessageDialog();
void setModel(WalletModel *model);
@@ -34,6 +35,7 @@ protected:
private:
Ui::SignVerifyMessageDialog *ui;
WalletModel *model;
+ const PlatformStyle *platformStyle;
private Q_SLOTS:
/* sign message */
diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
index f384562a50..98ad1a44b6 100644
--- a/src/qt/transactiontablemodel.cpp
+++ b/src/qt/transactiontablemodel.cpp
@@ -8,7 +8,7 @@
#include "guiconstants.h"
#include "guiutil.h"
#include "optionsmodel.h"
-#include "scicon.h"
+#include "platformstyle.h"
#include "transactiondesc.h"
#include "transactionrecord.h"
#include "walletmodel.h"
@@ -222,12 +222,13 @@ public:
}
};
-TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *parent):
+TransactionTableModel::TransactionTableModel(const PlatformStyle *platformStyle, CWallet* wallet, WalletModel *parent):
QAbstractTableModel(parent),
wallet(wallet),
walletModel(parent),
priv(new TransactionTablePriv(wallet, this)),
- fProcessingQueuedTransactions(false)
+ fProcessingQueuedTransactions(false),
+ platformStyle(platformStyle)
{
columns << QString() << QString() << tr("Date") << tr("Type") << tr("Label") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit());
priv->refreshWallet();
@@ -521,7 +522,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
case Qt::DecorationRole:
{
QIcon icon = qvariant_cast<QIcon>(index.data(RawDecorationRole));
- return TextColorIcon(icon);
+ return platformStyle->TextColorIcon(icon);
}
case Qt::DisplayRole:
switch(index.column())
diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h
index 25c82c764b..2089f703a6 100644
--- a/src/qt/transactiontablemodel.h
+++ b/src/qt/transactiontablemodel.h
@@ -10,6 +10,7 @@
#include <QAbstractTableModel>
#include <QStringList>
+class PlatformStyle;
class TransactionRecord;
class TransactionTablePriv;
class WalletModel;
@@ -23,7 +24,7 @@ class TransactionTableModel : public QAbstractTableModel
Q_OBJECT
public:
- explicit TransactionTableModel(CWallet* wallet, WalletModel *parent = 0);
+ explicit TransactionTableModel(const PlatformStyle *platformStyle, CWallet* wallet, WalletModel *parent = 0);
~TransactionTableModel();
enum ColumnIndex {
@@ -82,6 +83,7 @@ private:
QStringList columns;
TransactionTablePriv *priv;
bool fProcessingQueuedTransactions;
+ const PlatformStyle *platformStyle;
void subscribeToCoreSignals();
void unsubscribeFromCoreSignals();
diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp
index 998789b3ae..54e5a82720 100644
--- a/src/qt/transactionview.cpp
+++ b/src/qt/transactionview.cpp
@@ -10,7 +10,7 @@
#include "editaddressdialog.h"
#include "guiutil.h"
#include "optionsmodel.h"
-#include "scicon.h"
+#include "platformstyle.h"
#include "transactiondescdialog.h"
#include "transactionfilterproxy.h"
#include "transactionrecord.h"
@@ -35,7 +35,7 @@
#include <QUrl>
#include <QVBoxLayout>
-TransactionView::TransactionView(QWidget *parent) :
+TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *parent) :
QWidget(parent), model(0), transactionProxyModel(0),
transactionView(0)
{
@@ -44,27 +44,28 @@ TransactionView::TransactionView(QWidget *parent) :
QHBoxLayout *hlayout = new QHBoxLayout();
hlayout->setContentsMargins(0,0,0,0);
-#ifdef Q_OS_MAC
- hlayout->setSpacing(5);
- hlayout->addSpacing(26);
-#else
- hlayout->setSpacing(0);
- hlayout->addSpacing(23);
-#endif
+
+ if (platformStyle->getUseExtraSpacing()) {
+ hlayout->setSpacing(5);
+ hlayout->addSpacing(26);
+ } else {
+ hlayout->setSpacing(0);
+ hlayout->addSpacing(23);
+ }
watchOnlyWidget = new QComboBox(this);
watchOnlyWidget->setFixedWidth(24);
watchOnlyWidget->addItem("", TransactionFilterProxy::WatchOnlyFilter_All);
- watchOnlyWidget->addItem(SingleColorIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes);
- watchOnlyWidget->addItem(SingleColorIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No);
+ watchOnlyWidget->addItem(platformStyle->SingleColorIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes);
+ watchOnlyWidget->addItem(platformStyle->SingleColorIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No);
hlayout->addWidget(watchOnlyWidget);
dateWidget = new QComboBox(this);
-#ifdef Q_OS_MAC
- dateWidget->setFixedWidth(121);
-#else
- dateWidget->setFixedWidth(120);
-#endif
+ if (platformStyle->getUseExtraSpacing()) {
+ dateWidget->setFixedWidth(121);
+ } else {
+ dateWidget->setFixedWidth(120);
+ }
dateWidget->addItem(tr("All"), All);
dateWidget->addItem(tr("Today"), Today);
dateWidget->addItem(tr("This week"), ThisWeek);
@@ -75,11 +76,11 @@ TransactionView::TransactionView(QWidget *parent) :
hlayout->addWidget(dateWidget);
typeWidget = new QComboBox(this);
-#ifdef Q_OS_MAC
- typeWidget->setFixedWidth(121);
-#else
- typeWidget->setFixedWidth(120);
-#endif
+ if (platformStyle->getUseExtraSpacing()) {
+ typeWidget->setFixedWidth(121);
+ } else {
+ typeWidget->setFixedWidth(120);
+ }
typeWidget->addItem(tr("All"), TransactionFilterProxy::ALL_TYPES);
typeWidget->addItem(tr("Received with"), TransactionFilterProxy::TYPE(TransactionRecord::RecvWithAddress) |
@@ -102,11 +103,11 @@ TransactionView::TransactionView(QWidget *parent) :
#if QT_VERSION >= 0x040700
amountWidget->setPlaceholderText(tr("Min amount"));
#endif
-#ifdef Q_OS_MAC
- amountWidget->setFixedWidth(97);
-#else
- amountWidget->setFixedWidth(100);
-#endif
+ if (platformStyle->getUseExtraSpacing()) {
+ amountWidget->setFixedWidth(97);
+ } else {
+ amountWidget->setFixedWidth(100);
+ }
amountWidget->setValidator(new QDoubleValidator(0, 1e20, 8, this));
hlayout->addWidget(amountWidget);
@@ -121,11 +122,11 @@ TransactionView::TransactionView(QWidget *parent) :
vlayout->setSpacing(0);
int width = view->verticalScrollBar()->sizeHint().width();
// Cover scroll bar width with spacing
-#ifdef Q_OS_MAC
- hlayout->addSpacing(width+2);
-#else
- hlayout->addSpacing(width);
-#endif
+ if (platformStyle->getUseExtraSpacing()) {
+ hlayout->addSpacing(width+2);
+ } else {
+ hlayout->addSpacing(width);
+ }
// Always show scroll bar
view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
view->setTabKeyNavigation(false);
diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h
index 6c35362be4..ac157fb98d 100644
--- a/src/qt/transactionview.h
+++ b/src/qt/transactionview.h
@@ -10,6 +10,7 @@
#include <QWidget>
#include <QKeyEvent>
+class PlatformStyle;
class TransactionFilterProxy;
class WalletModel;
@@ -32,7 +33,7 @@ class TransactionView : public QWidget
Q_OBJECT
public:
- explicit TransactionView(QWidget *parent = 0);
+ explicit TransactionView(const PlatformStyle *platformStyle, QWidget *parent = 0);
void setModel(WalletModel *model);
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
index 892947bf3a..ba8c28464d 100644
--- a/src/qt/walletframe.cpp
+++ b/src/qt/walletframe.cpp
@@ -12,9 +12,10 @@
#include <QHBoxLayout>
#include <QLabel>
-WalletFrame::WalletFrame(BitcoinGUI *_gui) :
+WalletFrame::WalletFrame(const PlatformStyle *platformStyle, BitcoinGUI *_gui) :
QFrame(_gui),
- gui(_gui)
+ gui(_gui),
+ platformStyle(platformStyle)
{
// Leave HBox hook for adding a list view later
QHBoxLayout *walletFrameLayout = new QHBoxLayout(this);
@@ -42,7 +43,7 @@ bool WalletFrame::addWallet(const QString& name, WalletModel *walletModel)
if (!gui || !clientModel || !walletModel || mapWalletViews.count(name) > 0)
return false;
- WalletView *walletView = new WalletView(this);
+ WalletView *walletView = new WalletView(platformStyle, this);
walletView->setBitcoinGUI(gui);
walletView->setClientModel(clientModel);
walletView->setWalletModel(walletModel);
diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h
index 5a5e2ab944..9a56e97f9c 100644
--- a/src/qt/walletframe.h
+++ b/src/qt/walletframe.h
@@ -10,6 +10,7 @@
class BitcoinGUI;
class ClientModel;
+class PlatformStyle;
class SendCoinsRecipient;
class WalletModel;
class WalletView;
@@ -23,7 +24,7 @@ class WalletFrame : public QFrame
Q_OBJECT
public:
- explicit WalletFrame(BitcoinGUI *_gui = 0);
+ explicit WalletFrame(const PlatformStyle *platformStyle, BitcoinGUI *_gui = 0);
~WalletFrame();
void setClientModel(ClientModel *clientModel);
@@ -45,6 +46,8 @@ private:
bool bOutOfSync;
+ const PlatformStyle *platformStyle;
+
WalletView *currentWalletView();
public Q_SLOTS:
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 7820047b6b..f580853732 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -27,7 +27,7 @@
#include <boost/foreach.hpp>
-WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) :
+WalletModel::WalletModel(const PlatformStyle *platformStyle, CWallet *wallet, OptionsModel *optionsModel, QObject *parent) :
QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0),
transactionTableModel(0),
recentRequestsTableModel(0),
@@ -39,7 +39,7 @@ WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *p
fForceCheckBalanceChanged = false;
addressTableModel = new AddressTableModel(wallet, this);
- transactionTableModel = new TransactionTableModel(wallet, this);
+ transactionTableModel = new TransactionTableModel(platformStyle, wallet, this);
recentRequestsTableModel = new RecentRequestsTableModel(wallet, this);
// This timer will be fired repeatedly to update the balance
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index 40bc623543..c29682e4f6 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -17,6 +17,7 @@
class AddressTableModel;
class OptionsModel;
+class PlatformStyle;
class RecentRequestsTableModel;
class TransactionTableModel;
class WalletModelTransaction;
@@ -100,7 +101,7 @@ class WalletModel : public QObject
Q_OBJECT
public:
- explicit WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0);
+ explicit WalletModel(const PlatformStyle *platformStyle, CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0);
~WalletModel();
enum StatusCode // Returned by sendCoins
diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp
index c5f556b444..fa96f62e03 100644
--- a/src/qt/walletview.cpp
+++ b/src/qt/walletview.cpp
@@ -11,8 +11,8 @@
#include "guiutil.h"
#include "optionsmodel.h"
#include "overviewpage.h"
+#include "platformstyle.h"
#include "receivecoinsdialog.h"
-#include "scicon.h"
#include "sendcoinsdialog.h"
#include "signverifymessagedialog.h"
#include "transactiontablemodel.h"
@@ -29,31 +29,32 @@
#include <QPushButton>
#include <QVBoxLayout>
-WalletView::WalletView(QWidget *parent):
+WalletView::WalletView(const PlatformStyle *platformStyle, QWidget *parent):
QStackedWidget(parent),
clientModel(0),
- walletModel(0)
+ walletModel(0),
+ platformStyle(platformStyle)
{
// Create tabs
- overviewPage = new OverviewPage();
+ overviewPage = new OverviewPage(platformStyle);
transactionsPage = new QWidget(this);
QVBoxLayout *vbox = new QVBoxLayout();
QHBoxLayout *hbox_buttons = new QHBoxLayout();
- transactionView = new TransactionView(this);
+ transactionView = new TransactionView(platformStyle, this);
vbox->addWidget(transactionView);
QPushButton *exportButton = new QPushButton(tr("&Export"), this);
exportButton->setToolTip(tr("Export the data in the current tab to a file"));
-#ifndef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
- exportButton->setIcon(SingleColorIcon(":/icons/export"));
-#endif
+ if (platformStyle->getImagesOnButtons()) {
+ exportButton->setIcon(platformStyle->SingleColorIcon(":/icons/export"));
+ }
hbox_buttons->addStretch();
hbox_buttons->addWidget(exportButton);
vbox->addLayout(hbox_buttons);
transactionsPage->setLayout(vbox);
- receiveCoinsPage = new ReceiveCoinsDialog();
- sendCoinsPage = new SendCoinsDialog();
+ receiveCoinsPage = new ReceiveCoinsDialog(platformStyle);
+ sendCoinsPage = new SendCoinsDialog(platformStyle);
addWidget(overviewPage);
addWidget(transactionsPage);
@@ -182,7 +183,7 @@ void WalletView::gotoSendCoinsPage(QString addr)
void WalletView::gotoSignMessageTab(QString addr)
{
// calls show() in showTab_SM()
- SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(this);
+ SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(platformStyle, this);
signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose);
signVerifyMessageDialog->setModel(walletModel);
signVerifyMessageDialog->showTab_SM(true);
@@ -194,7 +195,7 @@ void WalletView::gotoSignMessageTab(QString addr)
void WalletView::gotoVerifyMessageTab(QString addr)
{
// calls show() in showTab_VM()
- SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(this);
+ SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(platformStyle, this);
signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose);
signVerifyMessageDialog->setModel(walletModel);
signVerifyMessageDialog->showTab_VM(true);
@@ -272,7 +273,7 @@ void WalletView::usedSendingAddresses()
{
if(!walletModel)
return;
- AddressBookPage *dlg = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab, this);
+ AddressBookPage *dlg = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::SendingTab, this);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->setModel(walletModel->getAddressTableModel());
dlg->show();
@@ -282,7 +283,7 @@ void WalletView::usedReceivingAddresses()
{
if(!walletModel)
return;
- AddressBookPage *dlg = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab, this);
+ AddressBookPage *dlg = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::ReceivingTab, this);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->setModel(walletModel->getAddressTableModel());
dlg->show();
diff --git a/src/qt/walletview.h b/src/qt/walletview.h
index 87c5d7bfbf..f97cf1ee80 100644
--- a/src/qt/walletview.h
+++ b/src/qt/walletview.h
@@ -12,6 +12,7 @@
class BitcoinGUI;
class ClientModel;
class OverviewPage;
+class PlatformStyle;
class ReceiveCoinsDialog;
class SendCoinsDialog;
class SendCoinsRecipient;
@@ -34,7 +35,7 @@ class WalletView : public QStackedWidget
Q_OBJECT
public:
- explicit WalletView(QWidget *parent);
+ explicit WalletView(const PlatformStyle *platformStyle, QWidget *parent);
~WalletView();
void setBitcoinGUI(BitcoinGUI *gui);
@@ -64,6 +65,7 @@ private:
TransactionView *transactionView;
QProgressDialog *progressDialog;
+ const PlatformStyle *platformStyle;
public Q_SLOTS:
/** Switch to overview (home) page */
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index 03c123a361..68091010f7 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -752,14 +752,14 @@ void StopRPCThreads()
{
acceptor->cancel(ec);
if (ec)
- LogPrintf("%s: Warning: %s when cancelling acceptor", __func__, ec.message());
+ LogPrintf("%s: Warning: %s when cancelling acceptor\n", __func__, ec.message());
}
rpc_acceptors.clear();
BOOST_FOREACH(const PAIRTYPE(std::string, boost::shared_ptr<deadline_timer>) &timer, deadlineTimers)
{
timer.second->cancel(ec);
if (ec)
- LogPrintf("%s: Warning: %s when cancelling timer", __func__, ec.message());
+ LogPrintf("%s: Warning: %s when cancelling timer\n", __func__, ec.message());
}
deadlineTimers.clear();
diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp
index a0c5592a95..eb61a2884d 100644
--- a/src/test/getarg_tests.cpp
+++ b/src/test/getarg_tests.cpp
@@ -60,18 +60,18 @@ BOOST_AUTO_TEST_CASE(boolarg)
BOOST_CHECK(!GetBoolArg("-foo", false));
BOOST_CHECK(!GetBoolArg("-foo", true));
- ResetArgs("-foo -nofoo"); // -foo should win
- BOOST_CHECK(GetBoolArg("-foo", false));
- BOOST_CHECK(GetBoolArg("-foo", true));
-
- ResetArgs("-foo=1 -nofoo=1"); // -foo should win
- BOOST_CHECK(GetBoolArg("-foo", false));
- BOOST_CHECK(GetBoolArg("-foo", true));
+ ResetArgs("-foo -nofoo"); // -nofoo should win
+ BOOST_CHECK(!GetBoolArg("-foo", false));
+ BOOST_CHECK(!GetBoolArg("-foo", true));
- ResetArgs("-foo=0 -nofoo=0"); // -foo should win
+ ResetArgs("-foo=1 -nofoo=1"); // -nofoo should win
BOOST_CHECK(!GetBoolArg("-foo", false));
BOOST_CHECK(!GetBoolArg("-foo", true));
+ ResetArgs("-foo=0 -nofoo=0"); // -nofoo=0 should win
+ BOOST_CHECK(GetBoolArg("-foo", false));
+ BOOST_CHECK(GetBoolArg("-foo", true));
+
// New 0.6 feature: treat -- same as -:
ResetArgs("--foo=1");
BOOST_CHECK(GetBoolArg("-foo", false));
@@ -150,9 +150,9 @@ BOOST_AUTO_TEST_CASE(boolargno)
BOOST_CHECK(GetBoolArg("-foo", true));
BOOST_CHECK(GetBoolArg("-foo", false));
- ResetArgs("-foo --nofoo");
- BOOST_CHECK(GetBoolArg("-foo", true));
- BOOST_CHECK(GetBoolArg("-foo", false));
+ ResetArgs("-foo --nofoo"); // --nofoo should win
+ BOOST_CHECK(!GetBoolArg("-foo", true));
+ BOOST_CHECK(!GetBoolArg("-foo", false));
ResetArgs("-nofoo -foo"); // foo always wins:
BOOST_CHECK(GetBoolArg("-foo", true));
diff --git a/src/test/mruset_tests.cpp b/src/test/mruset_tests.cpp
index 3c06689168..2b68f8899e 100644
--- a/src/test/mruset_tests.cpp
+++ b/src/test/mruset_tests.cpp
@@ -78,68 +78,4 @@ BOOST_AUTO_TEST_CASE(mruset_test)
}
}
-BOOST_AUTO_TEST_CASE(mrumap_test)
-{
- // The mrumap being tested.
- mrumap<int, char> mru(5000);
-
- // Run the test 10 times.
- for (int test = 0; test < 10; test++) {
- // Reset mru.
- mru.clear(5000);
-
- // A deque + set to simulate the mruset.
- std::deque<int> rep;
- std::map<int, char> all;
-
- // Insert 10000 random integers below 15000.
- for (int j=0; j<10000; j++) {
- int add = GetRandInt(15000);
- char val = (char)GetRandInt(256);
- mru.insert(add, val);
-
- // Add the number to rep/all as well.
- if (all.count(add) == 0) {
- all.insert(std::make_pair<int, char>(add, val));
- rep.push_back(add);
- if (all.size() == 5001) {
- all.erase(rep.front());
- rep.pop_front();
- }
- }
-
- if (GetRandInt(5) == 0) {
- // With 20% chance: remove an item
- int pos = GetRandInt(rep.size());
- std::deque<int>::iterator it = rep.begin();
- while (pos--) { it++; }
- int delval = *it;
- mru.erase(delval);
- all.erase(delval);
- rep.erase(it);
- }
-
- // Do a full comparison between mru and the simulated mru every 1000 and every 5001 elements.
- if (j % 1000 == 0 || j % 5001 == 0) {
- // Check that all elements that should be in there, are in there.
- BOOST_FOREACH(int x, rep) {
- BOOST_CHECK(mru.count(x));
- BOOST_CHECK(mru.find(x)->second == all[x]);
- }
-
- // Check that all elements that are in there, should be in there.
- for (mrumap<int, char>::iterator it = mru.begin(); it != mru.end(); it++) {
- BOOST_CHECK(all.count(it->first));
- BOOST_CHECK(all[it->first] == it->second);
- }
-
- for (int t = 0; t < 10; t++) {
- int r = GetRandInt(15000);
- BOOST_CHECK(all.count(r) == mru.count(r));
- }
- }
- }
- }
-}
-
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 5bc06e5056..c921dae45d 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -348,7 +348,7 @@ CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const
minerPolicyEstimator->Write(fileout);
}
catch (const std::exception&) {
- LogPrintf("CTxMemPool::WriteFeeEstimates(): unable to write policy estimator data (non-fatal)");
+ LogPrintf("CTxMemPool::WriteFeeEstimates(): unable to write policy estimator data (non-fatal)\n");
return false;
}
return true;
@@ -367,7 +367,7 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein)
minerPolicyEstimator->Read(filein);
}
catch (const std::exception&) {
- LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)");
+ LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)\n");
return false;
}
return true;
diff --git a/src/util.cpp b/src/util.cpp
index 37d52037c0..a7ec740de8 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -315,18 +315,21 @@ int LogPrintStr(const std::string &str)
return ret;
}
-static void InterpretNegativeSetting(string name, map<string, string>& mapSettingsRet)
+/** Interpret string as boolean, for argument parsing */
+static bool InterpretBool(const std::string& strValue)
{
- // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
- if (name.find("-no") == 0)
+ if (strValue.empty())
+ return true;
+ return (atoi(strValue) != 0);
+}
+
+/** Turn -noX into -X=0 */
+static void InterpretNegativeSetting(std::string& strKey, std::string& strValue)
+{
+ if (strKey.length()>3 && strKey[0]=='-' && strKey[1]=='n' && strKey[2]=='o')
{
- std::string positive("-");
- positive.append(name.begin()+3, name.end());
- if (mapSettingsRet.count(positive) == 0)
- {
- bool value = !GetBoolArg(name, false);
- mapSettingsRet[positive] = (value ? "1" : "0");
- }
+ strKey = "-" + strKey.substr(3);
+ strValue = InterpretBool(strValue) ? "0" : "1";
}
}
@@ -358,17 +361,11 @@ void ParseParameters(int argc, const char* const argv[])
// If both --foo and -foo are set, the last takes effect.
if (str.length() > 1 && str[1] == '-')
str = str.substr(1);
+ InterpretNegativeSetting(str, strValue);
mapArgs[str] = strValue;
mapMultiArgs[str].push_back(strValue);
}
-
- // New 0.6 features:
- BOOST_FOREACH(const PAIRTYPE(string,string)& entry, mapArgs)
- {
- // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
- InterpretNegativeSetting(entry.first, mapArgs);
- }
}
std::string GetArg(const std::string& strArg, const std::string& strDefault)
@@ -388,11 +385,7 @@ int64_t GetArg(const std::string& strArg, int64_t nDefault)
bool GetBoolArg(const std::string& strArg, bool fDefault)
{
if (mapArgs.count(strArg))
- {
- if (mapArgs[strArg].empty())
- return true;
- return (atoi(mapArgs[strArg]) != 0);
- }
+ return InterpretBool(mapArgs[strArg]);
return fDefault;
}
@@ -543,13 +536,11 @@ void ReadConfigFile(map<string, string>& mapSettingsRet,
{
// Don't overwrite existing settings so command line settings override bitcoin.conf
string strKey = string("-") + it->string_key;
+ string strValue = it->value[0];
+ InterpretNegativeSetting(strKey, strValue);
if (mapSettingsRet.count(strKey) == 0)
- {
- mapSettingsRet[strKey] = it->value[0];
- // interpret nofoo=1 as foo=0 (and nofoo=0 as foo=1) as long as foo not set)
- InterpretNegativeSetting(strKey, mapSettingsRet);
- }
- mapMultiSettingsRet[strKey].push_back(it->value[0]);
+ mapSettingsRet[strKey] = strValue;
+ mapMultiSettingsRet[strKey].push_back(strValue);
}
// If datadir is changed in .conf file:
ClearDatadirCache();
diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp
index c7f7e21679..0b0fb562e0 100644
--- a/src/wallet/crypter.cpp
+++ b/src/wallet/crypter.cpp
@@ -186,7 +186,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
}
if (keyPass && keyFail)
{
- LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.");
+ LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.\n");
assert(false);
}
if (keyFail || !keyPass)
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 58b9ccc078..dcc2983139 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -2109,7 +2109,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
if (!wtxNew.AcceptToMemoryPool(false))
{
// This must not fail. The transaction has already been signed and recorded.
- LogPrintf("CommitTransaction(): Error: Transaction not valid");
+ LogPrintf("CommitTransaction(): Error: Transaction not valid\n");
return false;
}
wtxNew.RelayWalletTransaction();