aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac221
-rwxr-xr-xqa/rpc-tests/send.sh14
-rw-r--r--qa/rpc-tests/util.sh5
-rwxr-xr-xqa/rpc-tests/wallet.sh1
-rw-r--r--src/Makefile.am79
-rw-r--r--src/Makefile.include9
-rw-r--r--src/m4/bitcoin_qt.m4380
-rw-r--r--src/net.h4
-rw-r--r--src/qt/Makefile.am253
-rw-r--r--src/qt/bitcoin.cpp503
-rw-r--r--src/qt/bitcoingui.cpp185
-rw-r--r--src/qt/bitcoingui.h31
-rw-r--r--src/qt/notificator.cpp16
-rw-r--r--src/qt/optionsmodel.cpp11
-rw-r--r--src/qt/splashscreen.cpp36
-rw-r--r--src/qt/splashscreen.h11
-rw-r--r--src/qt/test/Makefile.am28
-rw-r--r--src/qt/test/test_main.cpp18
-rw-r--r--src/rpcmisc.cpp3
-rw-r--r--src/rpcrawtransaction.cpp8
-rw-r--r--src/rpcserver.cpp2
-rw-r--r--src/test/Makefile.am54
22 files changed, 1366 insertions, 506 deletions
diff --git a/configure.ac b/configure.ac
index af230c355..82f489a06 100644
--- a/configure.ac
+++ b/configure.ac
@@ -63,38 +63,6 @@ AC_ARG_ENABLE([ipv6],
[use_ipv6=$enableval],
[use_ipv6=yes])
-dnl enable qt support
-AC_ARG_WITH([qt],
- [AS_HELP_STRING([--with-qt],
- [enable qt (default is yes)])],
- [use_qt=$withval],
- [use_qt=auto])
-AC_DEFUN([BITCOIN_QT_FAIL],[
- if test "x$use_qt" = "xauto"; then
- AC_MSG_WARN([$1; bitcoin-qt frontend will not be built])
- use_qt=no
- else
- AC_MSG_ERROR([$1])
- fi
-])
-AC_DEFUN([BITCOIN_QT_CHECK],[
- if test "x$use_qt" != "xno"; then
- true
- $1
- else
- true
- $2
- fi
-])
-AC_DEFUN([BITCOIN_QT_PATH_PROGS],[
- BITCOIN_QT_CHECK([
- AC_PATH_PROGS($1,$2,$3,$4)
- if test "x$$1" = "x"; then
- BITCOIN_QT_FAIL([$1 not found])
- fi
- ])
-])
-
AC_ARG_ENABLE(tests,
AS_HELP_STRING([--enable-tests],[compile tests (default is yes)]),
[use_tests=$enableval],
@@ -116,12 +84,6 @@ AC_ARG_WITH([qrencode],
[use_qr=$withval],
[use_qr=auto])
-AC_ARG_WITH([qtdbus],
- [AS_HELP_STRING([--with-qtdbus],
- [enable DBus support (default is yes if qt is enabled and QtDBus is found)])],
- [use_dbus=$withval],
- [use_dbus=auto])
-
AC_ARG_ENABLE([hardening],
[AS_HELP_STRING([--enable-hardening],
[attempt to harden the resulting executables (default is yes)])],
@@ -140,10 +102,6 @@ AC_ARG_ENABLE([lcov],
[use_lcov=yes],
[use_lcov=no])
-AC_ARG_WITH([qt-incdir],[AS_HELP_STRING([--with-qt-incdir=INC_DIR],[specify qt include path (overridden by pkgconfig)])], [qt_include_path=$withval], [])
-AC_ARG_WITH([qt-libdir],[AS_HELP_STRING([--with-qt-libdir=LIB_DIR],[specify qt lib path (overridden by pkgconfig)])], [qt_lib_path=$withval], [])
-AC_ARG_WITH([qt-bindir],[AS_HELP_STRING([--with-qt-bindir=BIN_DIR],[specify qt bin path])], [qt_bin_path=$withval], [])
-AC_ARG_WITH([qt-plugindir],[AS_HELP_STRING([--with-qt-plugindir=PLUGIN_DIR],[specify qt plugin path (overridden by pkgconfig)])], [qt_plugin_path=$withval], [])
AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[specify protoc bin path])], [protoc_bin_path=$withval], [])
@@ -168,13 +126,7 @@ AC_PATH_PROG(LCOV, lcov)
AC_PATH_PROG(JAVA, java)
AC_PATH_PROG(GENHTML, genhtml)
AC_PATH_PROG([GIT], [git])
-BITCOIN_QT_PATH_PROGS([MOC], [moc-qt4 moc4 moc],, $qt_bin_path:$PATH)
-BITCOIN_QT_PATH_PROGS([UIC], [uic-qt4 uic4 uic],, $qt_bin_path:$PATH)
-BITCOIN_QT_PATH_PROGS([RCC], [rcc-qt4 rcc4 rcc],, $qt_bin_path:$PATH)
-BITCOIN_QT_PATH_PROGS([LRELEASE], [lrelease-qt4 lrelease4 lrelease],, $qt_bin_path:$PATH)
-BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],, $protoc_bin_path:$PATH)
AC_PATH_PROG(CCACHE,ccache)
-AC_PATH_PROGS([LUPDATE], [lupdate-qt4 lupdate4 lupdate],, $qt_bin_path:$PATH)
AC_PATH_PROG(XGETTEXT,xgettext)
AC_PATH_PROG(HEXDUMP,hexdump)
PKG_PROG_PKG_CONFIG
@@ -239,7 +191,7 @@ case $host in
AC_CHECK_PROG([PORT],port, port)
if test x$PORT = xport; then
dnl add default macports paths
- CPPFLAGS="$CPPFLAGS -I/opt/local/include -I/opt/local/include/db48"
+ CPPFLAGS="$CPPFLAGS -isystem /opt/local/include -I/opt/local/include/db48"
LIBS="$LIBS -L/opt/local/lib -L/opt/local/lib/db48"
fi
@@ -254,12 +206,6 @@ case $host in
fi
fi
- BITCOIN_QT_CHECK([
- MOC_DEFS="-DQ_OS_MAC"
- base_frameworks="-framework Foundation -framework ApplicationServices -framework AppKit"
- AX_CHECK_LINK_FLAG([[$base_frameworks]],[LIBS="$LIBS $base_frameworks"],[AC_MSG_ERROR(could not find base frameworks)])
- ])
-
CPPFLAGS="$CPPFLAGS -DMAC_OSX"
TESTDEFS="-DBOOST_TEST_DYN_LINK"
;;
@@ -452,6 +398,8 @@ if test x$boost_sleep != xyes; then
AC_MSG_ERROR(No working boost sleep implementation found)
fi
+BITCOIN_QT_INIT
+
if test x$use_pkgconfig = xyes; then
if test x$PKG_CONFIG == x; then
@@ -464,23 +412,10 @@ if test x$use_pkgconfig = xyes; then
[
PKG_CHECK_MODULES([SSL], [libssl], [INCLUDES="$INCLUDES $SSL_CFLAGS"; LIBS="$LIBS $SSL_LIBS"], [AC_MSG_ERROR(openssl not found.)])
PKG_CHECK_MODULES([CRYPTO], [libcrypto], [INCLUDES="$INCLUDES $CRYPTO_CFLAGS"; LIBS="$LIBS $CRYPTO_LIBS"], [AC_MSG_ERROR(libcrypto not found.)])
-
- BITCOIN_QT_CHECK([
- PKG_CHECK_MODULES([QT], [QtCore QtGui QtNetwork], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes],[
- have_qt=no
- BITCOIN_QT_FAIL([Qt dependencies not found])
- ])
- if test x$use_tests = xyes; then
- PKG_CHECK_MODULES([QT_TEST], [QtTest], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no])
- fi
- if test x$use_dbus != xno; then
- PKG_CHECK_MODULES([QT_DBUS], [QtDBus], [QT_DBUS_INCLUDES="$QT_DBUS_CFLAGS"; have_qt_dbus=yes], [have_qt_dbus=no])
- fi
- if test x$use_qr != xno; then
- PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])
- fi
- PKG_CHECK_MODULES([PROTOBUF], [protobuf], [have_protobuf=yes], [AC_MSG_ERROR(libprotobuf not found.)])
- ])
+ BITCOIN_QT_CHECK([PKG_CHECK_MODULES([PROTOBUF], [protobuf], [have_protobuf=yes], [BITCOIN_QT_FAIL(libprotobuf not found)])])
+ if test x$use_qr != xno; then
+ BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])])
+ fi
]
)
else
@@ -490,81 +425,18 @@ else
AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),)
AC_CHECK_LIB([ssl], [main],, AC_MSG_ERROR(libssl missing))
- BITCOIN_QT_CHECK([
- TEMP_LIBS="$LIBS"
- LIBS=
- if test x$qt_lib_path != x; then
- QT_LIBS="$QT_LIBS -L$qt_lib_path"
- LIBS="$QT_LIBS"
- fi
- if test x$qt_plugin_path != x; then
- QT_LIBS="$QT_LIBS -L$qt_plugin_path/codecs"
- LIBS="$QT_LIBS"
- fi
-
- if test x$TARGET_OS == xwindows; then
- AC_CHECK_LIB([imm32], [main],, BITCOIN_QT_FAIL(libimm32 not found))
- fi
- ])
-
- #TODO: These are only needed when they're linked directly to parent libs. It really has nothing to do with windows.
- #Instead, check for missing functions in parent libs and assume static if they're absent.
- if test x$TARGET_OS == xwindows; then
- BITCOIN_QT_CHECK(AC_CHECK_LIB([qcncodecs],[main],,BITCOIN_QT_FAIL(libqcncodecs not found)))
- BITCOIN_QT_CHECK(AC_CHECK_LIB([qjpcodecs],[main],,BITCOIN_QT_FAIL(libqjpcodecs not found)))
- BITCOIN_QT_CHECK(AC_CHECK_LIB([qkrcodecs],[main],,BITCOIN_QT_FAIL(libqkrcodecs not found)))
- BITCOIN_QT_CHECK(AC_CHECK_LIB([qtwcodecs],[main],,BITCOIN_QT_FAIL(libqtwcodecs not found)))
- fi
+ BITCOIN_QT_CHECK(AC_CHECK_LIB([protobuf] ,[main],,BITCOIN_QT_FAIL(libprotobuf not found)))
+ if test x$use_qr != xno; then
+ BITCOIN_QT_CHECK([AC_CHECK_LIB([qrencode], [main],, [have_qrencode=no])])
+ BITCOIN_QT_CHECK([AC_CHECK_HEADER([qrencode.h],, have_qrencode=no)])
+ fi
+fi
- BITCOIN_QT_CHECK(AC_CHECK_LIB([QtCore] ,[main],,BITCOIN_QT_FAIL(libQtCore not found)))
- BITCOIN_QT_CHECK(AC_CHECK_LIB([QtGui] ,[main],,BITCOIN_QT_FAIL(libQtGui not found)))
- BITCOIN_QT_CHECK(AC_CHECK_LIB([QtNetwork],[main],,BITCOIN_QT_FAIL(libQtNetwork not found)))
- BITCOIN_QT_CHECK(AC_CHECK_LIB([protobuf] ,[main],,BITCOIN_QT_FAIL(libprotobuf not found)))
+BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path)
- BITCOIN_QT_CHECK([
- QT_LIBS="$LIBS"
- LIBS="$TEMP_LIBS"
+dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus
+BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt4])
- TEMP_CPPFLAGS="$CPPFLAGS"
- if test x$qt_include_path != x; then
- QT_INCLUDES="-I$qt_include_path -I$qt_include_path/QtCore -I$qt_include_path/QtGui -I$qt_include_path/QtNetwork -I$qt_include_path/QtTest -I$qt_include_path/QtDBus"
- CPPFLAGS="$CPPFLAGS $QT_INCLUDES"
- fi
- ])
- BITCOIN_QT_CHECK([AC_CHECK_HEADER([QtPlugin],,BITCOIN_QT_FAIL(QtCore headers missing))])
- BITCOIN_QT_CHECK([AC_CHECK_HEADER([QApplication],, BITCOIN_QT_FAIL(QtGui headers missing))])
- BITCOIN_QT_CHECK([AC_CHECK_HEADER([QLocalSocket],, BITCOIN_QT_FAIL(QtNetwork headers missing))])
-
- BITCOIN_QT_CHECK([
- if test x$use_tests = xyes; then
- TEMP_LIBS="$LIBS"
- LIBS=
- if test x$qt_lib_path != x; then
- LIBS="-L$qt_lib_path"
- fi
- AC_CHECK_LIB([QtTest], [main],, have_qt_test=no)
- AC_CHECK_HEADER([QTest],, have_qt_test=no)
- QT_TEST_LIBS="$LIBS"
- LIBS="$TEMP_LIBS"
- fi
- if test x$use_dbus != xno; then
- TEMP_LIBS="$LIBS"
- LIBS=
- if test x$qt_lib_path != x; then
- LIBS="-L$qt_lib_path"
- fi
- AC_CHECK_LIB([QtDBus], [main],, have_qt_dbus=no)
- AC_CHECK_HEADER([QtDBus],, have_qt_dbus=no)
- QT_DBUS_LIBS="$LIBS"
- LIBS="$TEMP_LIBS"
- fi
- CPPFLAGS="$TEMP_CPPFLAGS"
- if test x$use_qr != xno; then
- AC_CHECK_LIB([qrencode], [main],, [have_qrencode=no])
- AC_CHECK_HEADER([qrencode.h],, have_qrencode=no)
- fi
- ])
-fi
if test x$use_ipv6 = xyes; then
dnl Check for ipv6 build requirements
@@ -613,10 +485,6 @@ if test x$enable_wallet != xno; then
else
AC_MSG_RESULT(no)
-
- if test "x$use_qt" != "xno"; then
- AC_MSG_ERROR([Cannot currently build Qt GUI with wallet disabled. Use --without-qt.])
- fi
fi
dnl enable ipv6 support
@@ -662,46 +530,15 @@ else
fi
fi
-dnl enable qt support
-AC_MSG_CHECKING([if qt should be enabled])
-BITCOIN_QT_CHECK([
- use_qt=yes
- BUILD_QT=qt
- if test x$use_tests = xyes; then
- if test x$have_qt_test = xno; then
- AC_MSG_ERROR("libQtTest not found. Use --disable-tests or --without-qt.")
- fi
- fi
- if test x$have_qt_dbus = xno; then
- if test x$use_dbus = xyes; then
- AC_MSG_ERROR("libQtDBus not found. Install libQtDBus or remove --with-qtdbus.")
- fi
- use_dbus=no
- fi
- if test x$XGETTEXT == x; then
- AC_MSG_WARN("xgettext is required to update qt translations")
- fi
- if test x$LUPDATE == x; then
- AC_MSG_WARN("lupdate is required to update qt translations")
- fi
-],[
- use_qt=no
-])
-
-AC_MSG_RESULT($use_qt)
-
dnl these are only used when qt is enabled
-if test x$use_qt = xyes; then
-
+if test x$bitcoin_enable_qt != xno; then
+ BUILD_QT=qt
dnl enable dbus support
AC_MSG_CHECKING([if dbus should be enabled])
- if test x$use_dbus != xno; then
- use_dbus=yes
+ if test x$bitcoin_enable_qt_dbus != xno; then
AC_DEFINE([USE_DBUS],[1],[Define if dbus support should be compiled in])
- else
- use_dbus=no
fi
- AC_MSG_RESULT($use_dbus)
+ AC_MSG_RESULT($bitcoin_enable_qt_dbus)
dnl enable qr support
AC_MSG_CHECKING([if qr should be enabled])
@@ -720,8 +557,15 @@ if test x$use_qt = xyes; then
fi
fi
- if test x$use_tests$have_qt_test = xyesyes; then
+ if test x$XGETTEXT == x; then
+ AC_MSG_WARN("xgettext is required to update qt translations")
+ fi
+
+ if test x$use_tests = xyes; then
BUILD_TEST_QT="test"
+ if test x$bitcoin_enable_qt_test != xyes; then
+ AC_MSG_ERROR("QT Test lib not found. Use --disable-tests or --without-qt.")
+ fi
fi
fi
@@ -756,17 +600,10 @@ AC_SUBST(USE_QRCODE)
AC_SUBST(USE_IPV6)
AC_SUBST(INCLUDES)
AC_SUBST(BOOST_LIBS)
-AC_SUBST(MOC_DEFS)
-AC_SUBST(QT_INCLUDES)
-AC_SUBST(QT_TEST_LIBS)
-AC_SUBST(QT_LIBS)
-AC_SUBST(QT_DBUS_LIBS)
-AC_SUBST(QT_DBUS_INCLUDES)
-AC_SUBST(QT_TEST_INCLUDES)
AC_SUBST(TESTDEFS)
AC_SUBST(LEVELDB_TARGET_FLAGS)
-AC_SUBST(BUILD_QT)
AC_SUBST(BUILD_TEST)
+AC_SUBST(BUILD_QT)
AC_SUBST(BUILD_TEST_QT)
AC_CONFIG_FILES([Makefile src/Makefile src/test/Makefile src/qt/Makefile src/qt/test/Makefile share/setup.nsi share/qt/Info.plist])
AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh])
diff --git a/qa/rpc-tests/send.sh b/qa/rpc-tests/send.sh
new file mode 100755
index 000000000..fdfb1867b
--- /dev/null
+++ b/qa/rpc-tests/send.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+TIMEOUT=10
+SIGNAL=HUP
+if [ $# -eq 0 ]; then
+ echo -e "Usage:\t$0 <cmd>"
+ echo -e "\tRuns <cmd> and wait ${TIMEOUT} seconds or until SIG${SIGNAL} is received."
+ echo -e "\tReturns: 0 if SIG${SIGNAL} is received, 1 otherwise."
+ exit 0
+fi
+trap '[[ ${PID} ]] && kill ${PID}' ${SIGNAL}
+"$@"
+sleep ${TIMEOUT} & PID=$!
+wait ${PID} && exit 1
+exit 0
diff --git a/qa/rpc-tests/util.sh b/qa/rpc-tests/util.sh
index e4e395374..fed7d3256 100644
--- a/qa/rpc-tests/util.sh
+++ b/qa/rpc-tests/util.sh
@@ -23,6 +23,7 @@ function CreateDataDir {
echo "rpcuser=rt" >> $CONF
echo "rpcpassword=rt" >> $CONF
echo "rpcwait=1" >> $CONF
+ echo "walletnotify=killall -HUP `basename ${SENDANDWAIT}`" >> $CONF
shift
while (( "$#" )); do
echo $1 >> $CONF
@@ -59,7 +60,7 @@ function Send {
to=$2
amount=$3
address=$(Address $to)
- txid=$( $CLI $from sendtoaddress $address $amount )
+ txid=$( ${SENDANDWAIT} $CLI $from sendtoaddress $address $amount )
}
# Use: Unspent <datadir> <n'th-last-unspent> <var>
@@ -80,7 +81,7 @@ function CreateTxn1 {
# Use: SendRawTxn <datadir> <hex_txn_data>
function SendRawTxn {
- $CLI $1 sendrawtransaction $2
+ ${SENDANDWAIT} $CLI $1 sendrawtransaction $2
}
# Use: GetBlocks <datadir>
diff --git a/qa/rpc-tests/wallet.sh b/qa/rpc-tests/wallet.sh
index 118809a26..8d5a6cdc7 100755
--- a/qa/rpc-tests/wallet.sh
+++ b/qa/rpc-tests/wallet.sh
@@ -12,6 +12,7 @@ BITCOIND=${1}/bitcoind
CLI=${1}/bitcoin-cli
DIR="${BASH_SOURCE%/*}"
+SENDANDWAIT="${DIR}/send.sh"
if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
. "$DIR/util.sh"
diff --git a/src/Makefile.am b/src/Makefile.am
index 85d7c3c9c..9917be248 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,7 +3,10 @@ include Makefile.include
AM_CPPFLAGS += -I$(top_srcdir)/src/leveldb/helpers/memenv \
-I$(builddir)
-noinst_LIBRARIES = libbitcoin_server.a libbitcoin_common.a libbitcoin_cli.a
+noinst_LIBRARIES = \
+ libbitcoin_server.a \
+ libbitcoin_common.a \
+ libbitcoin_cli.a
if ENABLE_WALLET
noinst_LIBRARIES += libbitcoin_wallet.a
endif
@@ -14,20 +17,60 @@ SUBDIRS = . $(BUILD_QT) $(BUILD_TEST)
DIST_SUBDIRS = . qt test
.PHONY: FORCE
# bitcoin core #
-BITCOIN_CORE_H = addrman.h alert.h allocators.h base58.h bignum.h \
+BITCOIN_CORE_H = \
+ addrman.h \
+ alert.h \
+ allocators.h \
+ base58.h bignum.h \
+ bloom.h \
+ chainparams.h \
+ checkpoints.h \
+ checkqueue.h \
+ clientversion.h \
+ coincontrol.h \
+ coins.h \
+ compat.h \
+ core.h \
+ crypter.h \
+ db.h \
+ hash.h \
+ init.h \
+ key.h \
+ keystore.h \
+ leveldbwrapper.h \
+ limitedmap.h \
+ main.h \
+ miner.h \
+ mruset.h \
+ netbase.h \
+ net.h \
+ noui.h \
+ protocol.h \
rpcclient.h \
rpcprotocol.h \
rpcserver.h \
- bloom.h chainparams.h checkpoints.h checkqueue.h \
- clientversion.h coincontrol.h compat.h core.h coins.h crypter.h db.h hash.h init.h \
- key.h keystore.h leveldbwrapper.h limitedmap.h main.h miner.h mruset.h \
- netbase.h net.h noui.h protocol.h script.h serialize.h sync.h threadsafety.h \
- txdb.h txmempool.h ui_interface.h uint256.h util.h version.h walletdb.h wallet.h
-
-JSON_H = json/json_spirit.h json/json_spirit_error_position.h \
- json/json_spirit_reader.h json/json_spirit_reader_template.h \
- json/json_spirit_stream_reader.h json/json_spirit_utils.h \
- json/json_spirit_value.h json/json_spirit_writer.h \
+ script.h \
+ serialize.h \
+ sync.h \
+ threadsafety.h \
+ txdb.h \
+ txmempool.h \
+ ui_interface.h \
+ uint256.h \
+ util.h \
+ version.h \
+ walletdb.h \
+ wallet.h
+
+JSON_H = \
+ json/json_spirit.h \
+ json/json_spirit_error_position.h \
+ json/json_spirit_reader.h \
+ json/json_spirit_reader_template.h \
+ json/json_spirit_stream_reader.h \
+ json/json_spirit_utils.h \
+ json/json_spirit_value.h \
+ json/json_spirit_writer.h \
json/json_spirit_writer_template.h
obj/build.h: FORCE
@@ -93,7 +136,12 @@ nodist_libbitcoin_common_a_SOURCES = $(top_srcdir)/src/obj/build.h
#
# bitcoind binary #
-bitcoind_LDADD = libbitcoin_server.a libbitcoin_cli.a libbitcoin_common.a leveldb/libleveldb.a leveldb/libmemenv.a
+bitcoind_LDADD = \
+ libbitcoin_server.a \
+ libbitcoin_cli.a \
+ libbitcoin_common.a \
+ leveldb/libleveldb.a \
+ leveldb/libmemenv.a
if ENABLE_WALLET
bitcoind_LDADD += libbitcoin_wallet.a
endif
@@ -108,7 +156,10 @@ AM_CPPFLAGS += $(BDB_CPPFLAGS)
bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS)
# bitcoin-cli binary #
-bitcoin_cli_LDADD = libbitcoin_cli.a libbitcoin_common.a $(BOOST_LIBS)
+bitcoin_cli_LDADD = \
+ libbitcoin_cli.a \
+ libbitcoin_common.a \
+ $(BOOST_LIBS)
bitcoin_cli_SOURCES = bitcoin-cli.cpp
#
diff --git a/src/Makefile.include b/src/Makefile.include
index 13cffd29b..070902c51 100644
--- a/src/Makefile.include
+++ b/src/Makefile.include
@@ -12,6 +12,7 @@ LIBBITCOIN_CLI=$(top_builddir)/src/libbitcoin_cli.a
LIBLEVELDB=$(top_builddir)/src/leveldb/libleveldb.a
LIBMEMENV=$(top_builddir)/src/leveldb/libmemenv.a
LIBBITCOINQT=$(top_builddir)/src/qt/libbitcoinqt.a
+MOC_DEFS=$(DEFS) -I$(top_srcdir)/src
$(LIBBITCOIN):
$(MAKE) -C $(top_builddir)/src $(@F)
@@ -32,23 +33,23 @@ $(LIBBITCOINQT):
ui_%.h: %.ui
@test -d $(abs_builddir)/$(@D) || $(MKDIR_P) $(abs_builddir)/$(@D)
- @test -f $(UIC) && $(UIC) -o $(abs_builddir)/$@ $(abs_srcdir)/$< || echo error: could not build $(abs_builddir)/$@
+ @test -f $(UIC) && QT_SELECT=$(QT_SELECT) $(UIC) -o $(abs_builddir)/$@ $(abs_srcdir)/$< || echo error: could not build $(abs_builddir)/$@
$(SED) -i.bak -e '/^\*\*.*Created:/d' $(abs_builddir)/$@ && rm $(abs_builddir)/[email protected]
$(SED) -i.bak -e '/^\*\*.*by:/d' $(abs_builddir)/$@ && rm $(abs_builddir)/[email protected]
%.moc: %.cpp
- $(MOC) $(QT_INCLUDES) $(MOC_DEFS) -o $@ $<
+ QT_SELECT=$(QT_SELECT) $(MOC) $(QT_INCLUDES) $(MOC_DEFS) -o $@ $<
$(SED) -i.bak -e '/^\*\*.*Created:/d' $@ && rm [email protected]
$(SED) -i.bak -e '/^\*\*.*by:/d' $@ && rm [email protected]
moc_%.cpp: %.h
- $(MOC) $(QT_INCLUDES) $(MOC_DEFS) -o $@ $<
+ QT_SELECT=$(QT_SELECT) $(MOC) $(QT_INCLUDES) $(MOC_DEFS) -o $@ $<
$(SED) -i.bak -e '/^\*\*.*Created:/d' $@ && rm [email protected]
$(SED) -i.bak -e '/^\*\*.*by:/d' $@ && rm [email protected]
%.qm: %.ts
@test -d $(abs_builddir)/$(@D) || $(MKDIR_P) $(abs_builddir)/$(@D)
- @test -f $(LRELEASE) && $(LRELEASE) $(abs_srcdir)/$< -qm $(abs_builddir)/$@ || \
+ @test -f $(LRELEASE) && QT_SELECT=$(QT_SELECT) $(LRELEASE) $(abs_srcdir)/$< -qm $(abs_builddir)/$@ || \
echo error: could not build $(abs_builddir)/$@
%.pb.cc %.pb.h: %.proto
diff --git a/src/m4/bitcoin_qt.m4 b/src/m4/bitcoin_qt.m4
new file mode 100644
index 000000000..91c399eef
--- /dev/null
+++ b/src/m4/bitcoin_qt.m4
@@ -0,0 +1,380 @@
+dnl Helper for cases where a qt dependency is not met.
+dnl Output: If qt version is auto, set bitcoin_enable_qt to false. Else, exit.
+AC_DEFUN([BITCOIN_QT_FAIL],[
+ if test "x$bitcoin_qt_want_version" = "xauto" && test x$bitcoin_qt_force != xyes; then
+ if test x$bitcoin_enable_qt != xno; then
+ AC_MSG_WARN([$1; bitcoin-qt frontend will not be built])
+ fi
+ bitcoin_enable_qt=no
+ else
+ AC_MSG_ERROR([$1])
+ fi
+])
+
+AC_DEFUN([BITCOIN_QT_CHECK],[
+ if test "x$bitcoin_enable_qt" != "xno" && test x$bitcoin_qt_want_version != xno; then
+ true
+ $1
+ else
+ true
+ $2
+ fi
+])
+
+dnl BITCOIN_QT_PATH_PROGS([FOO], [foo foo2], [/path/to/search/first], [continue if missing])
+dnl Helper for finding the path of programs needed for QT.
+dnl Inputs: $1: Variable to be set
+dnl Inputs: $2: List of programs to search for
+dnl Inputs: $3: Look for $2 here before $PATH
+dnl Inputs: $4: If "yes", don't fail if $2 is not found.
+dnl Output: $1 is set to the path of $2 if found. $2 are searched in order.
+AC_DEFUN([BITCOIN_QT_PATH_PROGS],[
+ BITCOIN_QT_CHECK([
+ if test "x$3" != "x"; then
+ AC_PATH_PROGS($1,$2,,$3)
+ else
+ AC_PATH_PROGS($1,$2)
+ fi
+ if test "x$$1" = "x" && test "x$4" != "xyes"; then
+ BITCOIN_QT_FAIL([$1 not found])
+ fi
+ ])
+])
+
+dnl Initialize qt input.
+dnl This must be called before any other BITCOIN_QT* macros to ensure that
+dnl input variables are set correctly.
+dnl CAUTION: Do not use this inside of a conditional.
+AC_DEFUN([BITCOIN_QT_INIT],[
+ dnl enable qt support
+ AC_ARG_WITH([qt],
+ [AS_HELP_STRING([--with-qt],
+ [with qt (no|qt4|qt5|auto. default is auto, qt4 tried first.)])],
+ [
+ bitcoin_qt_want_version=$withval
+ if test x$bitcoin_qt_want_version = xyes; then
+ bitcoin_qt_force=yes
+ bitcoin_qt_want_version=auto
+ fi
+ ],
+ [bitcoin_qt_want_version=auto])
+
+ AC_ARG_WITH([qt-incdir],[AS_HELP_STRING([--with-qt-incdir=INC_DIR],[specify qt include path (overridden by pkgconfig)])], [qt_include_path=$withval], [])
+ AC_ARG_WITH([qt-libdir],[AS_HELP_STRING([--with-qt-libdir=LIB_DIR],[specify qt lib path (overridden by pkgconfig)])], [qt_lib_path=$withval], [])
+ AC_ARG_WITH([qt-plugindir],[AS_HELP_STRING([--with-qt-plugindir=PLUGIN_DIR],[specify qt plugin path (overridden by pkgconfig)])], [qt_plugin_path=$withval], [])
+ AC_ARG_WITH([qt-bindir],[AS_HELP_STRING([--with-qt-bindir=BIN_DIR],[specify qt bin path])], [qt_bin_path=$withval], [])
+
+ AC_ARG_WITH([qtdbus],
+ [AS_HELP_STRING([--with-qtdbus],
+ [enable DBus support (default is yes if qt is enabled and QtDBus is found)])],
+ [use_dbus=$withval],
+ [use_dbus=auto])
+])
+
+dnl Find the appropriate version of Qt libraries and includes.
+dnl Inputs: $1: Whether or not pkg-config should be used. yes|no. Default: yes.
+dnl Inputs: $2: If $1 is "yes" and --with-qt=auto, which qt version should be
+dnl tried first.
+dnl Outputs: See _BITCOIN_QT_FIND_LIBS_*
+dnl Outputs: Sets variables for all qt-related tools.
+dnl Outputs: bitcoin_enable_qt, bitcoin_enable_qt_dbus, bitcoin_enable_qt_test
+AC_DEFUN([BITCOIN_QT_CONFIGURE],[
+ use_pkgconfig=$1
+
+ if test x$use_pkgconfig == x; then
+ use_pkgconfig=yes
+ fi
+
+ if test x$use_pkgconfig = xyes; then
+ if test x$PKG_CONFIG == x; then
+ AC_MSG_ERROR(pkg-config not found.)
+ fi
+ BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG([$2])])
+ else
+ BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG])
+ fi
+
+ BITCOIN_QT_PATH_PROGS([MOC], [moc-qt${bitcoin_qt_got_major_vers} moc${bitcoin_qt_got_major_vers} moc], $qt_bin_path)
+ BITCOIN_QT_PATH_PROGS([UIC], [uic-qt${bitcoin_qt_got_major_vers} uic${bitcoin_qt_got_major_vers} uic], $qt_bin_path)
+ BITCOIN_QT_PATH_PROGS([RCC], [rcc-qt${bitcoin_qt_got_major_vers} rcc${bitcoin_qt_got_major_vers} rcc], $qt_bin_path)
+ BITCOIN_QT_PATH_PROGS([LRELEASE], [lrelease-qt${bitcoin_qt_got_major_vers} lrelease${bitcoin_qt_got_major_vers} lrelease], $qt_bin_path)
+ BITCOIN_QT_PATH_PROGS([LUPDATE], [lupdate-qt${bitcoin_qt_got_major_vers} lupdate${bitcoin_qt_got_major_vers} lupdate],$qt_bin_path, yes)
+
+ case $host in
+ *darwin*)
+ BITCOIN_QT_CHECK([
+ MOC_DEFS="-DQ_OS_MAC"
+ base_frameworks="-framework Foundation -framework ApplicationServices -framework AppKit"
+ AX_CHECK_LINK_FLAG([[$base_frameworks]],[QT_LIBS="$QT_LIBS $base_frameworks"],[AC_MSG_ERROR(could not find base frameworks)])
+ AC_SUBST(MOC_DEFS)
+ ])
+ ;;
+ esac
+
+
+ dnl enable qt support
+ AC_MSG_CHECKING(if QT should be enabled)
+ BITCOIN_QT_CHECK([
+ bitcoin_enable_qt=yes
+ bitcoin_enable_qt_test=yes
+ if test x$have_qt_test = xno; then
+ bitcoin_enable_qt_test=no
+ fi
+ bitcoin_enable_qt_dbus=yes
+ if test x$have_qt_dbus = xno; then
+ bitcoin_enable_qt_dbus=no
+ if test x$use_dbus = xyes; then
+ AC_MSG_ERROR("libQtDBus not found. Install libQtDBus or remove --with-qtdbus.")
+ fi
+ fi
+ if test x$LUPDATE == x; then
+ AC_MSG_WARN("lupdate is required to update qt translations")
+ fi
+ ],[
+ bitcoin_enable_qt=no
+ ])
+ AC_MSG_RESULT([$bitcoin_enable_qt (Qt${bitcoin_qt_got_major_vers})])
+
+ AC_SUBST(QT_INCLUDES)
+ AC_SUBST(QT_LIBS)
+ AC_SUBST(QT_DBUS_INCLUDES)
+ AC_SUBST(QT_DBUS_LIBS)
+ AC_SUBST(QT_TEST_INCLUDES)
+ AC_SUBST(QT_TEST_LIBS)
+ AC_SUBST(QT_SELECT, qt${bitcoin_qt_got_major_vers})
+])
+
+dnl All macros below are internal and should _not_ be used from the main
+dnl configure.ac.
+dnl ----
+
+dnl Internal. Check if the included version of QT is Qt5.
+dnl Requires: INCLUDES must be populated as necessary.
+dnl Output: bitcoin_cv_qt5=yes|no
+AC_DEFUN([_BITCOIN_QT_CHECK_QT5],[
+ AC_CACHE_CHECK(for QT 5, bitcoin_cv_qt5,[
+ AC_TRY_COMPILE(
+ [#include <QtCore>],
+ [
+ #if QT_VERSION < 0x050000
+ choke me
+ #else
+ return 0;
+ #endif
+ ],
+ bitcoin_cv_qt5=yes,
+ bitcoin_cv_qt5=no)
+])])
+
+dnl Internal. Check if the linked version of QT was built as static libs.
+dnl Requires: Qt5. This check cannot determine if Qt4 is static.
+dnl Requires: INCLUDES and LIBS must be populated as necessary.
+dnl Output: bitcoin_cv_static_qt=yes|no
+dnl Output: Defines QT_STATICPLUGIN if plugins are static.
+AC_DEFUN([_BITCOIN_QT_IS_STATIC],[
+ AC_CACHE_CHECK(for static QT, bitcoin_cv_static_qt,[
+ AC_TRY_COMPILE(
+ [#include <QtCore>],
+ [
+ #if defined(QT_STATIC)
+ return 0;
+ #else
+ choke me
+ #endif
+ ],
+ [bitcoin_cv_static_qt=yes],
+ [bitcoin_cv_static_qt=no])
+ ])
+ if test xbitcoin_cv_static_qt = xyes; then
+ AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol for static QT plugins])
+ fi
+])
+
+dnl Internal. Check if the link-requirements for static plugins are met.
+dnl Requires: INCLUDES and LIBS must be populated as necessary.
+dnl Inputs: $1: A series of Q_IMPORT_PLUGIN().
+dnl Inputs: $2: The libraries that resolve $1.
+dnl Output: QT_LIBS is prepended or configure exits.
+AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGINS],[
+ AC_MSG_CHECKING(for static QT plugins: $2)
+ CHECK_STATIC_PLUGINS_TEMP_LIBS="$LIBS"
+ LIBS="$2 $QT_LIBS $LIBS"
+ AC_TRY_LINK([
+ #define QT_STATICPLUGIN
+ #include <QtPlugin>
+ $1],
+ [return 0;],
+ [AC_MSG_RESULT(yes); QT_LIBS="$2 $QT_LIBS"],
+ [AC_MSG_RESULT(no)]; BITCOIN_QT_FAIL(Could not resolve: $2))
+ LIBS="$CHECK_STATIC_PLUGINS_TEMP_LIBS"
+])
+
+dnl Internal. Find Qt libraries using pkg-config.
+dnl Inputs: bitcoin_qt_want_version (from --with-qt=). The version to check
+dnl first.
+dnl Inputs: $1: If bitcoin_qt_want_version is "auto", check for this version
+dnl first.
+dnl Outputs: All necessary QT_* variables are set.
+dnl Outputs: bitcoin_qt_got_major_vers is set to "4" or "5".
+dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no.
+AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG],[
+ m4_ifdef([PKG_CHECK_MODULES],[
+ auto_priority_version=$1
+ if test x$auto_priority_version == x; then
+ auto_priority_version=qt5
+ fi
+ if test x$bitcoin_qt_want_version == xqt5 || ( test x$bitcoin_qt_want_version == xauto && test x$auto_priority_version == xqt5 ); then
+ QT_LIB_PREFIX=Qt5
+ bitcoin_qt_got_major_vers=5
+ else
+ QT_LIB_PREFIX=Qt
+ bitcoin_qt_got_major_vers=4
+ fi
+ qt5_modules="Qt5Core Qt5Gui Qt5Network Qt5Widgets"
+ qt4_modules="QtCore QtGui QtNetwork"
+ BITCOIN_QT_CHECK([
+ if test x$bitcoin_qt_want_version == xqt5 || ( test x$bitcoin_qt_want_version == xauto && test x$auto_priority_version == xqt5 ); then
+ PKG_CHECK_MODULES([QT], [$qt5_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes],[have_qt=no])
+ elif test x$bitcoin_qt_want_version == xqt4 || ( test x$bitcoin_qt_want_version == xauto && test x$auto_priority_version == xqt4 ); then
+ PKG_CHECK_MODULES([QT], [$qt4_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes], [have_qt=no])
+ fi
+
+ dnl qt version is set to 'auto' and the preferred version wasn't found. Now try the other.
+ if test x$have_qt == xno && test x$bitcoin_qt_want_version == xauto; then
+ if test x$auto_priority_version = x$qt5; then
+ PKG_CHECK_MODULES([QT], [$qt4_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt; bitcoin_qt_got_major_vers=4], [have_qt=no])
+ else
+ PKG_CHECK_MODULES([QT], [$qt5_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt5; bitcoin_qt_got_major_vers=5], [have_qt=no])
+ fi
+ fi
+ if test x$have_qt != xyes; then
+ have_qt=no
+ BITCOIN_QT_FAIL([Qt dependencies not found])
+ fi
+ ])
+ BITCOIN_QT_CHECK([
+ PKG_CHECK_MODULES([QT_TEST], [${QT_LIB_PREFIX}Test], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no])
+ if test x$use_dbus != xno; then
+ PKG_CHECK_MODULES([QT_DBUS], [${QT_LIB_PREFIX}DBus], [QT_DBUS_INCLUDES="$QT_DBUS_CFLAGS"; have_qt_dbus=yes], [have_qt_dbus=no])
+ fi
+ ])
+ ])
+ true; dnl
+])
+
+dnl Internal. Find Qt libraries without using pkg-config. Version is deduced
+dnl from the discovered headers.
+dnl Inputs: bitcoin_qt_want_version (from --with-qt=). The version to use.
+dnl If "auto", the version will be discovered by _BITCOIN_QT_CHECK_QT5.
+dnl Outputs: All necessary QT_* variables are set.
+dnl Outputs: bitcoin_qt_got_major_vers is set to "4" or "5".
+dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no.
+AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG],[
+ TEMP_CPPFLAGS="$CPPFLAGS"
+ TEMP_LIBS="$LIBS"
+ BITCOIN_QT_CHECK([
+ if test x$qt_include_path != x; then
+ QT_INCLUDES="-I$qt_include_path -I$qt_include_path/QtCore -I$qt_include_path/QtGui -I$qt_include_path/QtWidgets -I$qt_include_path/QtNetwork -I$qt_include_path/QtTest -I$qt_include_path/QtDBus"
+ CPPFLAGS="$QT_INCLUDES $CPPFLAGS"
+ fi
+ ])
+
+ BITCOIN_QT_CHECK([AC_CHECK_HEADER([QtPlugin],,BITCOIN_QT_FAIL(QtCore headers missing))])
+ BITCOIN_QT_CHECK([AC_CHECK_HEADER([QApplication],, BITCOIN_QT_FAIL(QtGui headers missing))])
+ BITCOIN_QT_CHECK([AC_CHECK_HEADER([QLocalSocket],, BITCOIN_QT_FAIL(QtNetwork headers missing))])
+
+ BITCOIN_QT_CHECK([
+ if test x$bitcoin_qt_want_version = xauto; then
+ _BITCOIN_QT_CHECK_QT5
+ fi
+ if test x$bitcoin_cv_qt5 == xyes || test x$bitcoin_qt_want_version = xqt5; then
+ QT_LIB_PREFIX=Qt5
+ bitcoin_qt_got_major_vers=5
+ else
+ QT_LIB_PREFIX=Qt
+ bitcoin_qt_got_major_vers=4
+ fi
+ ])
+
+ BITCOIN_QT_CHECK([
+ LIBS=
+ if test x$qt_lib_path != x; then
+ LIBS="$LIBS -L$qt_lib_path"
+ fi
+ if test x$qt_plugin_path != x; then
+ LIBS="$LIBS -L$qt_plugin_path/accessible"
+ if test x$bitcoin_qt_got_major_vers == x5; then
+ LIBS="$LIBS -L$qt_plugin_path/platforms"
+ else
+ LIBS="$LIBS -L$qt_plugin_path/codecs"
+ fi
+ fi
+
+ if test x$TARGET_OS == xwindows; then
+ AC_CHECK_LIB([imm32], [main],, BITCOIN_QT_FAIL(libimm32 not found))
+ fi
+ ])
+
+ BITCOIN_QT_CHECK(AC_CHECK_LIB([z] ,[main],,BITCOIN_QT_FAIL(zlib not found)))
+ BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Core] ,[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXCore not found)))
+ BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Gui] ,[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXGui not found)))
+ BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Network],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXNetwork not found)))
+ if test x$bitcoin_qt_got_major_vers == x5; then
+ BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Widgets],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXWidgets not found)))
+ fi
+ QT_LIBS="$LIBS"
+ LIBS="$TEMP_LIBS"
+
+ dnl This is ugly and complicated. Yuck. Works as follows:
+ dnl We can't discern whether Qt4 builds are static or not. For Qt5, we can
+ dnl check a header to find out. When Qt is built statically, some plugins must
+ dnl be linked into the final binary as well. These plugins have changed between
+ dnl Qt4 and Qt5. With Qt5, languages moved into core and the WindowsIntegration
+ dnl plugin was added. Since we can't tell if Qt4 is static or not, it is
+ dnl assumed for all non-pkg-config builds.
+ dnl _BITCOIN_QT_CHECK_STATIC_PLUGINS does a quick link-check and appends the
+ dnl results to QT_LIBS.
+ BITCOIN_QT_CHECK([
+ if test x$bitcoin_qt_got_major_vers == x5; then
+ _BITCOIN_QT_IS_STATIC
+ if test x$bitcoin_cv_static_qt == xyes; then
+ AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static])
+ _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(AccessibleFactory)], [-lqtaccessiblewidgets])
+ if test x$TARGET_OS == xwindows; then
+ _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)],[-lqwindows])
+ fi
+ fi
+ else
+ AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static])
+ _BITCOIN_QT_CHECK_STATIC_PLUGINS([
+ Q_IMPORT_PLUGIN(qcncodecs)
+ Q_IMPORT_PLUGIN(qjpcodecs)
+ Q_IMPORT_PLUGIN(qtwcodecs)
+ Q_IMPORT_PLUGIN(qkrcodecs)
+ Q_IMPORT_PLUGIN(AccessibleFactory)],
+ [-lqcncodecs -lqjpcodecs -lqtwcodecs -lqkrcodecs -lqtaccessiblewidgets])
+ fi
+ ])
+
+ BITCOIN_QT_CHECK([
+ LIBS=
+ if test x$qt_lib_path != x; then
+ LIBS="-L$qt_lib_path"
+ fi
+ AC_CHECK_LIB([${QT_LIB_PREFIX}Test], [main],, have_qt_test=no)
+ AC_CHECK_HEADER([QTest],, have_qt_test=no)
+ QT_TEST_LIBS="$LIBS"
+ if test x$use_dbus != xno; then
+ LIBS=
+ if test x$qt_lib_path != x; then
+ LIBS="-L$qt_lib_path"
+ fi
+ AC_CHECK_LIB([${QT_LIB_PREFIX}DBus], [main],, have_qt_dbus=no)
+ AC_CHECK_HEADER([QtDBus],, have_qt_dbus=no)
+ QT_DBUS_LIBS="$LIBS"
+ fi
+ ])
+ CPPFLAGS="$TEMP_CPPFLAGS"
+ LIBS="$TEMP_LIBS"
+])
+
diff --git a/src/net.h b/src/net.h
index 583500173..a181e275c 100644
--- a/src/net.h
+++ b/src/net.h
@@ -209,7 +209,7 @@ public:
std::string addrName;
CService addrLocal;
int nVersion;
- // strSubVer is whatever byte array we read from the wire. However, this field is intended
+ // strSubVer is whatever byte array we read from the wire. However, this field is intended
// to be printed out, displayed to humans in various forms and so on. So we sanitize it and
// store the sanitized version in cleanSubVer. The original should be used when dealing with
// the network or wire types and the cleaned string used when displayed or logged.
@@ -264,7 +264,7 @@ public:
int64_t nPingUsecStart;
int64_t nPingUsecTime;
bool fPingQueued;
-
+
CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false) : ssSend(SER_NETWORK, INIT_PROTO_VERSION)
{
nServices = 0;
diff --git a/src/qt/Makefile.am b/src/qt/Makefile.am
index 863274e80..ac11625c8 100644
--- a/src/qt/Makefile.am
+++ b/src/qt/Makefile.am
@@ -74,41 +74,72 @@ QT_TS = \
locale/bitcoin_zh_CN.ts \
locale/bitcoin_zh_TW.ts
-QT_FORMS_UI = forms/aboutdialog.ui forms/addressbookpage.ui \
+QT_FORMS_UI = \
+ forms/aboutdialog.ui \
+ forms/addressbookpage.ui \
forms/askpassphrasedialog.ui \
forms/coincontroldialog.ui \
forms/editaddressdialog.ui \
forms/intro.ui \
forms/openuridialog.ui \
- forms/optionsdialog.ui forms/overviewpage.ui forms/receiverequestdialog.ui \
+ forms/optionsdialog.ui \
+ forms/overviewpage.ui \
+ forms/receiverequestdialog.ui \
forms/receivecoinsdialog.ui \
- forms/rpcconsole.ui forms/sendcoinsdialog.ui forms/sendcoinsentry.ui \
- forms/signverifymessagedialog.ui forms/transactiondescdialog.ui
+ forms/rpcconsole.ui \
+ forms/sendcoinsdialog.ui \
+ forms/sendcoinsentry.ui \
+ forms/signverifymessagedialog.ui \
+ forms/transactiondescdialog.ui
-QT_MOC_CPP = moc_aboutdialog.cpp moc_addressbookpage.cpp \
- moc_addresstablemodel.cpp moc_askpassphrasedialog.cpp \
- moc_bitcoinaddressvalidator.cpp moc_bitcoinamountfield.cpp \
- moc_bitcoingui.cpp moc_bitcoinunits.cpp moc_clientmodel.cpp \
+QT_MOC_CPP = \
+ moc_aboutdialog.cpp \
+ moc_addressbookpage.cpp \
+ moc_addresstablemodel.cpp \
+ moc_askpassphrasedialog.cpp \
+ moc_bitcoinaddressvalidator.cpp \
+ moc_bitcoinamountfield.cpp \
+ moc_bitcoingui.cpp \
+ moc_bitcoinunits.cpp \
+ moc_clientmodel.cpp \
moc_coincontroldialog.cpp \
moc_coincontroltreewidget.cpp \
- moc_csvmodelwriter.cpp moc_editaddressdialog.cpp moc_guiutil.cpp \
- moc_intro.cpp moc_macdockiconhandler.cpp moc_macnotificationhandler.cpp \
- moc_monitoreddatamapper.cpp moc_notificator.cpp \
+ moc_csvmodelwriter.cpp \
+ moc_editaddressdialog.cpp \
+ moc_guiutil.cpp \
+ moc_intro.cpp \
+ moc_macdockiconhandler.cpp \
+ moc_macnotificationhandler.cpp \
+ moc_monitoreddatamapper.cpp \
+ moc_notificator.cpp \
moc_openuridialog.cpp \
moc_optionsdialog.cpp \
- moc_optionsmodel.cpp moc_overviewpage.cpp moc_paymentserver.cpp \
- moc_receiverequestdialog.cpp moc_qvalidatedlineedit.cpp moc_qvaluecombobox.cpp \
+ moc_optionsmodel.cpp \
+ moc_overviewpage.cpp \
+ moc_paymentserver.cpp \
+ moc_receiverequestdialog.cpp \
+ moc_qvalidatedlineedit.cpp \
+ moc_qvaluecombobox.cpp \
moc_receivecoinsdialog.cpp \
moc_recentrequeststablemodel.cpp \
- moc_rpcconsole.cpp moc_sendcoinsdialog.cpp moc_sendcoinsentry.cpp \
- moc_signverifymessagedialog.cpp moc_splashscreen.cpp moc_trafficgraphwidget.cpp moc_transactiondesc.cpp \
- moc_transactiondescdialog.cpp moc_transactionfilterproxy.cpp \
- moc_transactiontablemodel.cpp moc_transactionview.cpp moc_walletframe.cpp \
- moc_walletmodel.cpp moc_walletview.cpp
+ moc_rpcconsole.cpp \
+ moc_sendcoinsdialog.cpp \
+ moc_sendcoinsentry.cpp \
+ moc_signverifymessagedialog.cpp \
+ moc_splashscreen.cpp \
+ moc_trafficgraphwidget.cpp \
+ moc_transactiondesc.cpp \
+ moc_transactiondescdialog.cpp \
+ moc_transactionfilterproxy.cpp \
+ moc_transactiontablemodel.cpp \
+ moc_transactionview.cpp \
+ moc_walletframe.cpp \
+ moc_walletmodel.cpp \
+ moc_walletview.cpp
BITCOIN_MM = macdockiconhandler.mm macnotificationhandler.mm
-QT_MOC = intro.moc overviewpage.moc rpcconsole.moc
+QT_MOC = intro.moc overviewpage.moc rpcconsole.moc bitcoin.moc
QT_QRC_CPP = qrc_bitcoin.cpp
QT_QRC = bitcoin.qrc
@@ -117,57 +148,149 @@ PROTOBUF_CC = paymentrequest.pb.cc
PROTOBUF_H = paymentrequest.pb.h
PROTOBUF_PROTO = paymentrequest.proto
-BITCOIN_QT_H = aboutdialog.h addressbookpage.h addresstablemodel.h \
- askpassphrasedialog.h bitcoinaddressvalidator.h bitcoinamountfield.h \
- bitcoingui.h bitcoinunits.h clientmodel.h coincontroldialog.h coincontroltreewidget.h csvmodelwriter.h \
- editaddressdialog.h guiconstants.h guiutil.h intro.h macdockiconhandler.h \
- macnotificationhandler.h monitoreddatamapper.h notificator.h \
+BITCOIN_QT_H = \
+ aboutdialog.h \
+ addressbookpage.h \
+ addresstablemodel.h \
+ askpassphrasedialog.h \
+ bitcoinaddressvalidator.h \
+ bitcoinamountfield.h \
+ bitcoingui.h \
+ bitcoinunits.h \
+ clientmodel.h \
+ coincontroldialog.h \
+ coincontroltreewidget.h \
+ csvmodelwriter.h \
+ editaddressdialog.h \
+ guiconstants.h \
+ guiutil.h \
+ intro.h \
+ macdockiconhandler.h \
+ macnotificationhandler.h \
+ monitoreddatamapper.h \
+ notificator.h \
openuridialog.h \
optionsdialog.h \
- optionsmodel.h overviewpage.h paymentrequestplus.h paymentserver.h \
+ optionsmodel.h \
+ overviewpage.h \
+ paymentrequestplus.h \
+ paymentserver.h \
receivecoinsdialog.h \
recentrequeststablemodel.h \
- receiverequestdialog.h qvalidatedlineedit.h qvaluecombobox.h rpcconsole.h \
- sendcoinsdialog.h sendcoinsentry.h signverifymessagedialog.h splashscreen.h \
- trafficgraphwidget.h transactiondescdialog.h transactiondesc.h transactionfilterproxy.h \
- transactionrecord.h transactiontablemodel.h transactionview.h walletframe.h \
- walletmodel.h walletmodeltransaction.h walletview.h
-
-RES_ICONS = res/icons/bitcoin.png res/icons/address-book.png \
- res/icons/quit.png res/icons/send.png res/icons/toolbar.png \
- res/icons/connect0_16.png res/icons/connect1_16.png \
- res/icons/connect2_16.png res/icons/connect3_16.png \
- res/icons/connect4_16.png res/icons/transaction0.png \
- res/icons/transaction2.png res/icons/clock1.png res/icons/clock2.png \
- res/icons/clock3.png res/icons/clock4.png res/icons/clock5.png \
- res/icons/configure.png res/icons/receive.png res/icons/editpaste.png \
- res/icons/editcopy.png res/icons/add.png res/icons/bitcoin_testnet.png \
- res/icons/toolbar_testnet.png res/icons/edit.png res/icons/history.png \
- res/icons/overview.png res/icons/export.png res/icons/synced.png \
- res/icons/remove.png res/icons/tx_mined.png res/icons/tx_input.png \
- res/icons/tx_output.png res/icons/tx_inout.png res/icons/lock_closed.png \
- res/icons/lock_open.png res/icons/key.png res/icons/filesave.png \
- res/icons/qrcode.png res/icons/debugwindow.png res/icons/bitcoin.ico \
+ receiverequestdialog.h \
+ qvalidatedlineedit.h \
+ qvaluecombobox.h \
+ rpcconsole.h \
+ sendcoinsdialog.h \
+ sendcoinsentry.h \
+ signverifymessagedialog.h \
+ splashscreen.h \
+ trafficgraphwidget.h \
+ transactiondescdialog.h \
+ transactiondesc.h \
+ transactionfilterproxy.h \
+ transactionrecord.h \
+ transactiontablemodel.h \
+ transactionview.h \
+ walletframe.h \
+ walletmodel.h \
+ walletmodeltransaction.h \
+ walletview.h
+
+RES_ICONS = \
+ res/icons/bitcoin.png \
+ res/icons/address-book.png \
+ res/icons/quit.png \
+ res/icons/send.png \
+ res/icons/toolbar.png \
+ res/icons/connect0_16.png \
+ res/icons/connect1_16.png \
+ res/icons/connect2_16.png \
+ res/icons/connect3_16.png \
+ res/icons/connect4_16.png \
+ res/icons/transaction0.png \
+ res/icons/transaction2.png \
+ res/icons/clock1.png \
+ res/icons/clock2.png \
+ res/icons/clock3.png \
+ res/icons/clock4.png \
+ res/icons/clock5.png \
+ res/icons/configure.png \
+ res/icons/receive.png \
+ res/icons/editpaste.png \
+ res/icons/editcopy.png \
+ res/icons/add.png \
+ res/icons/bitcoin_testnet.png \
+ res/icons/toolbar_testnet.png \
+ res/icons/edit.png \
+ res/icons/history.png \
+ res/icons/overview.png \
+ res/icons/export.png \
+ res/icons/synced.png \
+ res/icons/remove.png \
+ res/icons/tx_mined.png \
+ res/icons/tx_input.png \
+ res/icons/tx_output.png \
+ res/icons/tx_inout.png \
+ res/icons/lock_closed.png \
+ res/icons/lock_open.png \
+ res/icons/key.png \
+ res/icons/filesave.png \
+ res/icons/qrcode.png \
+ res/icons/debugwindow.png \
+ res/icons/bitcoin.ico \
res/icons/bitcoin_testnet.ico
-BITCOIN_QT_CPP = aboutdialog.cpp addressbookpage.cpp \
- addresstablemodel.cpp askpassphrasedialog.cpp bitcoinaddressvalidator.cpp \
- bitcoinamountfield.cpp bitcoin.cpp bitcoingui.cpp \
- bitcoinunits.cpp clientmodel.cpp \
+BITCOIN_QT_CPP = \
+ aboutdialog.cpp \
+ bitcoinaddressvalidator.cpp \
+ bitcoinamountfield.cpp \
+ bitcoin.cpp \
+ bitcoingui.cpp \
+ bitcoinunits.cpp \
+ clientmodel.cpp \
+ csvmodelwriter.cpp \
+ guiutil.cpp \
+ intro.cpp \
+ monitoreddatamapper.cpp \
+ notificator.cpp \
+ optionsdialog.cpp \
+ optionsmodel.cpp \
+ qvalidatedlineedit.cpp \
+ qvaluecombobox.cpp \
+ rpcconsole.cpp \
+ signverifymessagedialog.cpp \
+ splashscreen.cpp \
+ trafficgraphwidget.cpp
+
+if ENABLE_WALLET
+BITCOIN_QT_CPP += \
+ addressbookpage.cpp \
+ addresstablemodel.cpp \
+ askpassphrasedialog.cpp \
coincontroldialog.cpp \
coincontroltreewidget.cpp \
- csvmodelwriter.cpp editaddressdialog.cpp \
- guiutil.cpp intro.cpp monitoreddatamapper.cpp notificator.cpp \
+ editaddressdialog.cpp \
openuridialog.cpp \
- optionsdialog.cpp optionsmodel.cpp overviewpage.cpp paymentrequestplus.cpp \
- paymentserver.cpp qvalidatedlineedit.cpp qvaluecombobox.cpp \
- receivecoinsdialog.cpp receiverequestdialog.cpp \
+ overviewpage.cpp \
+ paymentrequestplus.cpp \
+ paymentserver.cpp \
+ receivecoinsdialog.cpp \
+ receiverequestdialog.cpp \
recentrequeststablemodel.cpp \
- rpcconsole.cpp sendcoinsdialog.cpp sendcoinsentry.cpp \
- signverifymessagedialog.cpp splashscreen.cpp trafficgraphwidget.cpp transactiondesc.cpp \
- transactiondescdialog.cpp transactionfilterproxy.cpp transactionrecord.cpp \
- transactiontablemodel.cpp transactionview.cpp walletframe.cpp \
- walletmodel.cpp walletmodeltransaction.cpp walletview.cpp
+ sendcoinsdialog.cpp \
+ sendcoinsentry.cpp \
+ transactiondesc.cpp \
+ transactiondescdialog.cpp \
+ transactionfilterproxy.cpp \
+ transactionrecord.cpp \
+ transactiontablemodel.cpp \
+ transactionview.cpp \
+ walletframe.cpp \
+ walletmodel.cpp \
+ walletmodeltransaction.cpp \
+ walletview.cpp
+endif
RES_IMAGES = res/images/about.png res/images/splash.png \
res/images/splash_testnet.png
@@ -203,7 +326,11 @@ endif
bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(QT_INCLUDES) \
-I$(top_srcdir)/src/qt/forms
bitcoin_qt_SOURCES = bitcoin.cpp
-bitcoin_qt_LDADD = libbitcoinqt.a $(LIBBITCOIN_SERVER) $(LIBBITCOIN_WALLET) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBLEVELDB) $(LIBMEMENV) \
+bitcoin_qt_LDADD = libbitcoinqt.a $(LIBBITCOIN_SERVER)
+if ENABLE_WALLET
+bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
+endif
+bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBLEVELDB) $(LIBMEMENV) \
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
# forms/foo.h -> forms/ui_foo.h
@@ -220,10 +347,10 @@ bitcoinstrings.cpp: FORCE
translate: bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM)
@test -n $(LUPDATE) || echo "lupdate is required for updating translations"
- @$(LUPDATE) $^ -locations relative -no-obsolete -ts locale/bitcoin_en.ts
+ @QT_SELECT=$(QT_SELECT) $(LUPDATE) $^ -locations relative -no-obsolete -ts locale/bitcoin_en.ts
$(QT_QRC_CPP): $(QT_QRC) $(QT_QM) $(QT_FORMS_H) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES) $(PROTOBUF_H)
- @cd $(abs_srcdir); test -f $(RCC) && $(RCC) -name bitcoin -o $(abs_builddir)/$@ $< || \
+ @cd $(abs_srcdir); test -f $(RCC) && QT_SELECT=$(QT_SELECT) $(RCC) -name bitcoin -o $(abs_builddir)/$@ $< || \
echo error: could not build $@
$(SED) -i.bak -e '/^\*\*.*Created:/d' $@ && rm [email protected]
$(SED) -i.bak -e '/^\*\*.*by:/d' $@ && rm [email protected]
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index d78f6fab7..82d8af77d 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -2,6 +2,7 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include "bitcoin-config.h"
#include "bitcoingui.h"
#include "clientmodel.h"
@@ -9,9 +10,11 @@
#include "guiutil.h"
#include "intro.h"
#include "optionsmodel.h"
-#include "paymentserver.h"
#include "splashscreen.h"
+#ifdef ENABLE_WALLET
+#include "paymentserver.h"
#include "walletmodel.h"
+#endif
#include "init.h"
#include "main.h"
@@ -29,59 +32,33 @@
#include <QSettings>
#include <QTimer>
#include <QTranslator>
+#include <QThread>
+#include <QVBoxLayout>
+#include <QLabel>
-#if QT_VERSION < 0x050000
-#include <QTextCodec>
-#endif
-
-#if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED)
-#define _BITCOIN_QT_PLUGINS_INCLUDED
-#define __INSURE__
+#if defined(QT_STATICPLUGIN)
#include <QtPlugin>
+#if QT_VERSION < 0x050000
Q_IMPORT_PLUGIN(qcncodecs)
Q_IMPORT_PLUGIN(qjpcodecs)
Q_IMPORT_PLUGIN(qtwcodecs)
Q_IMPORT_PLUGIN(qkrcodecs)
Q_IMPORT_PLUGIN(qtaccessiblewidgets)
+#else
+Q_IMPORT_PLUGIN(AccessibleFactory)
+Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
+#endif
+#endif
+
+#if QT_VERSION < 0x050000
+#include <QTextCodec>
#endif
// Declare meta types used for QMetaObject::invokeMethod
Q_DECLARE_METATYPE(bool*)
-// Need a global reference for the notifications to find the GUI
-static BitcoinGUI *guiref;
-static SplashScreen *splashref;
-
-static bool ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
-{
- if(guiref)
- {
- bool modal = (style & CClientUIInterface::MODAL);
- bool ret = false;
- // In case of modal message, use blocking connection to wait for user to click a button
- QMetaObject::invokeMethod(guiref, "message",
- modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
- Q_ARG(QString, QString::fromStdString(caption)),
- Q_ARG(QString, QString::fromStdString(message)),
- Q_ARG(unsigned int, style),
- Q_ARG(bool*, &ret));
- return ret;
- }
- else
- {
- LogPrintf("%s: %s\n", caption.c_str(), message.c_str());
- fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
- return false;
- }
-}
-
static void InitMessage(const std::string &message)
{
- if(splashref)
- {
- splashref->showMessage(QString::fromStdString(message), Qt::AlignBottom|Qt::AlignHCenter, QColor(55,55,55));
- qApp->processEvents();
- }
LogPrintf("init message: %s\n", message.c_str());
}
@@ -93,15 +70,6 @@ static std::string Translate(const char* psz)
return QCoreApplication::translate("bitcoin-core", psz).toStdString();
}
-/* Handle runaway exceptions. Shows a message box with the problem and quits the program.
- */
-static void handleRunawayException(std::exception *e)
-{
- PrintExceptionContinue(e, "Runaway exception");
- QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. Bitcoin can no longer continue safely and will quit.") + QString("\n\n") + QString::fromStdString(strMiscWarning));
- exit(1);
-}
-
/** Set up translations */
static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
{
@@ -158,6 +126,319 @@ void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, cons
}
#endif
+/** Class encapsulating Bitcoin Core startup and shutdown.
+ * Allows running startup and shutdown in a different thread from the UI thread.
+ */
+class BitcoinCore: public QObject
+{
+ Q_OBJECT
+public:
+ explicit BitcoinCore();
+
+public slots:
+ void initialize();
+ void shutdown();
+
+signals:
+ void initializeResult(int retval);
+ void shutdownResult(int retval);
+ void runawayException(const QString &message);
+
+private:
+ boost::thread_group threadGroup;
+
+ /// Pass fatal exception message to UI thread
+ void handleRunawayException(std::exception *e);
+};
+
+/** Main Bitcoin application object */
+class BitcoinApplication: public QApplication
+{
+ Q_OBJECT
+public:
+ explicit BitcoinApplication(int &argc, char **argv);
+ ~BitcoinApplication();
+
+#ifdef ENABLE_WALLET
+ /// Create payment server
+ void createPaymentServer();
+#endif
+ /// Create options model
+ void createOptionsModel();
+ /// Create main window
+ void createWindow(bool isaTestNet);
+ /// Create splash screen
+ void createSplashScreen(bool isaTestNet);
+
+ /// Request core initialization
+ void requestInitialize();
+ /// Request core shutdown
+ void requestShutdown();
+
+ /// Get process return value
+ int getReturnValue() { return returnValue; }
+
+public slots:
+ void initializeResult(int retval);
+ void shutdownResult(int retval);
+ /// Handle runaway exceptions. Shows a message box with the problem and quits the program.
+ void handleRunawayException(const QString &message);
+
+signals:
+ void requestedInitialize();
+ void requestedShutdown();
+ void stopThread();
+ void splashFinished(QWidget *window);
+
+private:
+ QThread *coreThread;
+ OptionsModel *optionsModel;
+ ClientModel *clientModel;
+ BitcoinGUI *window;
+ QTimer *pollShutdownTimer;
+#ifdef ENABLE_WALLET
+ PaymentServer* paymentServer;
+ WalletModel *walletModel;
+#endif
+ int returnValue;
+
+ void startThread();
+};
+
+#include "bitcoin.moc"
+
+BitcoinCore::BitcoinCore():
+ QObject()
+{
+}
+
+void BitcoinCore::handleRunawayException(std::exception *e)
+{
+ PrintExceptionContinue(e, "Runaway exception");
+ emit runawayException(QString::fromStdString(strMiscWarning));
+}
+
+void BitcoinCore::initialize()
+{
+ try
+ {
+ LogPrintf("Running AppInit2 in thread\n");
+ int rv = AppInit2(threadGroup);
+ emit initializeResult(rv);
+ } catch (std::exception& e) {
+ handleRunawayException(&e);
+ } catch (...) {
+ handleRunawayException(NULL);
+ }
+}
+
+void BitcoinCore::shutdown()
+{
+ try
+ {
+ LogPrintf("Running Shutdown in thread\n");
+ threadGroup.interrupt_all();
+ threadGroup.join_all();
+ Shutdown();
+ LogPrintf("Shutdown finished\n");
+ emit shutdownResult(1);
+ } catch (std::exception& e) {
+ handleRunawayException(&e);
+ } catch (...) {
+ handleRunawayException(NULL);
+ }
+}
+
+BitcoinApplication::BitcoinApplication(int &argc, char **argv):
+ QApplication(argc, argv),
+ coreThread(0),
+ optionsModel(0),
+ clientModel(0),
+ window(0),
+ pollShutdownTimer(0),
+#ifdef ENABLE_WALLET
+ paymentServer(0),
+ walletModel(0),
+#endif
+ returnValue(0)
+{
+ setQuitOnLastWindowClosed(false);
+ startThread();
+}
+
+BitcoinApplication::~BitcoinApplication()
+{
+ LogPrintf("Stopping thread\n");
+ emit stopThread();
+ coreThread->wait();
+ LogPrintf("Stopped thread\n");
+
+ delete window;
+ window = 0;
+#ifdef ENABLE_WALLET
+ delete paymentServer;
+ paymentServer = 0;
+#endif
+ delete optionsModel;
+ optionsModel = 0;
+}
+
+#ifdef ENABLE_WALLET
+void BitcoinApplication::createPaymentServer()
+{
+ paymentServer = new PaymentServer(this);
+}
+#endif
+
+void BitcoinApplication::createOptionsModel()
+{
+ optionsModel = new OptionsModel();
+}
+
+void BitcoinApplication::createWindow(bool isaTestNet)
+{
+ window = new BitcoinGUI(isaTestNet, 0);
+
+ pollShutdownTimer = new QTimer(window);
+ connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown()));
+ pollShutdownTimer->start(200);
+}
+
+void BitcoinApplication::createSplashScreen(bool isaTestNet)
+{
+ SplashScreen *splash = new SplashScreen(QPixmap(), 0, isaTestNet);
+ splash->setAttribute(Qt::WA_DeleteOnClose);
+ splash->show();
+ connect(this, SIGNAL(splashFinished(QWidget*)), splash, SLOT(slotFinish(QWidget*)));
+}
+
+void BitcoinApplication::startThread()
+{
+ coreThread = new QThread(this);
+ BitcoinCore *executor = new BitcoinCore();
+ executor->moveToThread(coreThread);
+
+ /* communication to and from thread */
+ connect(executor, SIGNAL(initializeResult(int)), this, SLOT(initializeResult(int)));
+ connect(executor, SIGNAL(shutdownResult(int)), this, SLOT(shutdownResult(int)));
+ connect(executor, SIGNAL(runawayException(QString)), this, SLOT(handleRunawayException(QString)));
+ connect(this, SIGNAL(requestedInitialize()), executor, SLOT(initialize()));
+ connect(this, SIGNAL(requestedShutdown()), executor, SLOT(shutdown()));
+ /* make sure executor object is deleted in its own thread */
+ connect(this, SIGNAL(stopThread()), executor, SLOT(deleteLater()));
+ connect(this, SIGNAL(stopThread()), coreThread, SLOT(quit()));
+
+ coreThread->start();
+}
+
+void BitcoinApplication::requestInitialize()
+{
+ LogPrintf("Requesting initialize\n");
+ emit requestedInitialize();
+}
+
+void BitcoinApplication::requestShutdown()
+{
+ LogPrintf("Requesting shutdown\n");
+ window->hide();
+ window->setClientModel(0);
+ pollShutdownTimer->stop();
+
+#ifdef ENABLE_WALLET
+ window->removeAllWallets();
+ delete walletModel;
+ walletModel = 0;
+#endif
+ delete clientModel;
+ clientModel = 0;
+
+ // Show a simple window indicating shutdown status
+ QWidget *shutdownWindow = new QWidget();
+ QVBoxLayout *layout = new QVBoxLayout();
+ layout->addWidget(new QLabel(
+ tr("Bitcoin Core is shutting down...\n") +
+ tr("Do not shut down the computer until this window disappears.")));
+ shutdownWindow->setLayout(layout);
+
+ // Center shutdown window at where main window was
+ const QPoint global = window->mapToGlobal(window->rect().center());
+ shutdownWindow->move(global.x() - shutdownWindow->width() / 2, global.y() - shutdownWindow->height() / 2);
+ shutdownWindow->show();
+
+ // Request shutdown from core thread
+ emit requestedShutdown();
+}
+
+void BitcoinApplication::initializeResult(int retval)
+{
+ LogPrintf("Initialization result: %i\n", retval);
+ // Set exit result: 0 if successful, 1 if failure
+ returnValue = retval ? 0 : 1;
+ if(retval)
+ {
+ // Miscellaneous initialization after core is initialized
+ optionsModel->Upgrade(); // Must be done after AppInit2
+
+#ifdef ENABLE_WALLET
+ PaymentServer::LoadRootCAs();
+ paymentServer->setOptionsModel(optionsModel);
+#endif
+
+ emit splashFinished(window);
+
+ clientModel = new ClientModel(optionsModel);
+ window->setClientModel(clientModel);
+
+#ifdef ENABLE_WALLET
+ if(pwalletMain)
+ {
+ walletModel = new WalletModel(pwalletMain, optionsModel);
+
+ window->addWallet("~Default", walletModel);
+ window->setCurrentWallet("~Default");
+
+ connect(walletModel, SIGNAL(coinsSent(CWallet*,SendCoinsRecipient,QByteArray)),
+ paymentServer, SLOT(fetchPaymentACK(CWallet*,const SendCoinsRecipient&,QByteArray)));
+ }
+#endif
+
+ // If -min option passed, start window minimized.
+ if(GetBoolArg("-min", false))
+ {
+ window->showMinimized();
+ }
+ else
+ {
+ window->show();
+ }
+#ifdef ENABLE_WALLET
+ // Now that initialization/startup is done, process any command-line
+ // bitcoin: URIs or payment requests:
+ connect(paymentServer, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)),
+ window, SLOT(handlePaymentRequest(SendCoinsRecipient)));
+ connect(window, SIGNAL(receivedURI(QString)),
+ paymentServer, SLOT(handleURIOrFile(QString)));
+ connect(paymentServer, SIGNAL(message(QString,QString,unsigned int)),
+ window, SLOT(message(QString,QString,unsigned int)));
+ QTimer::singleShot(100, paymentServer, SLOT(uiReady()));
+#endif
+ } else {
+ quit(); // Exit main loop
+ }
+}
+
+void BitcoinApplication::shutdownResult(int retval)
+{
+ LogPrintf("Shutdown result: %i\n", retval);
+ quit(); // Exit main loop after shutdown finished
+}
+
+void BitcoinApplication::handleRunawayException(const QString &message)
+{
+ QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. Bitcoin can no longer continue safely and will quit.") + QString("\n\n") + message);
+ ::exit(1);
+}
+
#ifndef BITCOIN_QT_TEST
int main(int argc, char *argv[])
{
@@ -169,9 +450,11 @@ int main(int argc, char *argv[])
if (!SelectParamsFromCommandLine()) {
fSelParFromCLFailed = true;
}
+#ifdef ENABLE_WALLET
// Parse URIs on command line -- this can affect TestNet() / RegTest() mode
if (!PaymentServer::ipcParseCommandLine(argc, argv))
exit(0);
+#endif
bool isaTestNet = TestNet() || RegTest();
@@ -185,7 +468,7 @@ int main(int argc, char *argv[])
#endif
Q_INIT_RESOURCE(bitcoin);
- QApplication app(argc, argv);
+ BitcoinApplication app(argc, argv);
#if QT_VERSION > 0x050100
// Generate high-dpi pixmaps
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
@@ -211,6 +494,7 @@ int main(int argc, char *argv[])
// Now that QSettings are accessible, initialize translations
QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
+ uiInterface.Translate.connect(Translate);
// Show help message immediately after parsing command-line options (for "-lang") and setting locale,
// but before showing splash screen.
@@ -239,6 +523,7 @@ int main(int argc, char *argv[])
}
ReadConfigFile(mapArgs, mapMultiArgs);
+#ifdef ENABLE_WALLET
/// 7. URI IPC sending
// - Do this early as we don't want to bother initializing if we are just calling IPC
// - Do this *after* setting up the data directory, as the data directory hash is used in the name
@@ -250,7 +535,8 @@ int main(int argc, char *argv[])
// Start up the payment server early, too, so impatient users that click on
// bitcoin: links repeatedly have their payment requests routed to this process:
- PaymentServer* paymentServer = new PaymentServer(&app);
+ app.createPaymentServer();
+#endif
/// 8. Main GUI initialization
// Install global event filter that makes sure that long tooltips can be word-wrapped
@@ -262,24 +548,22 @@ int main(int argc, char *argv[])
qInstallMessageHandler(DebugMessageHandler);
#endif
// Load GUI settings from QSettings
- OptionsModel optionsModel;
+ app.createOptionsModel();
// Subscribe to global signals from core
- uiInterface.ThreadSafeMessageBox.connect(ThreadSafeMessageBox);
uiInterface.InitMessage.connect(InitMessage);
- uiInterface.Translate.connect(Translate);
- // Show splash screen if appropriate
- SplashScreen splash(QPixmap(), 0, isaTestNet);
- if (GetBoolArg("-splash", true) && !GetBoolArg("-min", false))
+ // Show help message immediately after parsing command-line options (for "-lang") and setting locale,
+ // but before showing splash screen.
+ if (mapArgs.count("-?") || mapArgs.count("--help"))
{
- splash.show();
- splash.setAutoFillBackground(true);
- splashref = &splash;
+ GUIUtil::HelpMessageBox help;
+ help.showOrPrint();
+ return 1;
}
- app.processEvents();
- app.setQuitOnLastWindowClosed(false);
+ if (GetBoolArg("-splash", true) && !GetBoolArg("-min", false))
+ app.createSplashScreen(isaTestNet);
try
{
@@ -289,93 +573,18 @@ int main(int argc, char *argv[])
if (GUIUtil::GetStartOnSystemStartup())
GUIUtil::SetStartOnSystemStartup(true);
#endif
-
- boost::thread_group threadGroup;
-
- BitcoinGUI window(isaTestNet, 0);
- guiref = &window;
-
- QTimer* pollShutdownTimer = new QTimer(guiref);
- QObject::connect(pollShutdownTimer, SIGNAL(timeout()), guiref, SLOT(detectShutdown()));
- pollShutdownTimer->start(200);
-
- if(AppInit2(threadGroup))
- {
- {
- // Put this in a block, so that the Model objects are cleaned up before
- // calling Shutdown().
-
- optionsModel.Upgrade(); // Must be done after AppInit2
-
- PaymentServer::LoadRootCAs();
- paymentServer->setOptionsModel(&optionsModel);
-
- if (splashref)
- splash.finish(&window);
-
- ClientModel clientModel(&optionsModel);
- window.setClientModel(&clientModel);
-
- WalletModel *walletModel = 0;
- if(pwalletMain)
- walletModel = new WalletModel(pwalletMain, &optionsModel);
-
- if(walletModel)
- {
- window.addWallet("~Default", walletModel);
- window.setCurrentWallet("~Default");
- }
-
- // If -min option passed, start window minimized.
- if(GetBoolArg("-min", false))
- {
- window.showMinimized();
- }
- else
- {
- window.show();
- }
-
- // Now that initialization/startup is done, process any command-line
- // bitcoin: URIs or payment requests:
- QObject::connect(paymentServer, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)),
- &window, SLOT(handlePaymentRequest(SendCoinsRecipient)));
- QObject::connect(&window, SIGNAL(receivedURI(QString)),
- paymentServer, SLOT(handleURIOrFile(QString)));
- if(walletModel)
- {
- QObject::connect(walletModel, SIGNAL(coinsSent(CWallet*,SendCoinsRecipient,QByteArray)),
- paymentServer, SLOT(fetchPaymentACK(CWallet*,const SendCoinsRecipient&,QByteArray)));
- }
- QObject::connect(paymentServer, SIGNAL(message(QString,QString,unsigned int)),
- guiref, SLOT(message(QString,QString,unsigned int)));
- QTimer::singleShot(100, paymentServer, SLOT(uiReady()));
-
- app.exec();
-
- window.hide();
- window.setClientModel(0);
- window.removeAllWallets();
- guiref = 0;
- delete walletModel;
- }
- // Shutdown the core and its threads, but don't exit the GUI here
- threadGroup.interrupt_all();
- threadGroup.join_all();
- Shutdown();
- }
- else
- {
- threadGroup.interrupt_all();
- threadGroup.join_all();
- Shutdown();
- return 1;
- }
+ app.createWindow(isaTestNet);
+ app.requestInitialize();
+ app.exec();
+ app.requestShutdown();
+ app.exec();
} catch (std::exception& e) {
- handleRunawayException(&e);
+ PrintExceptionContinue(&e, "Runaway exception");
+ app.handleRunawayException(QString::fromStdString(strMiscWarning));
} catch (...) {
- handleRunawayException(NULL);
+ PrintExceptionContinue(NULL, "Runaway exception");
+ app.handleRunawayException(QString::fromStdString(strMiscWarning));
}
- return 0;
+ return app.getReturnValue();
}
#endif // BITCOIN_QT_TEST
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 6be5a6401..22c41a620 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -14,8 +14,10 @@
#include "optionsdialog.h"
#include "optionsmodel.h"
#include "rpcconsole.h"
+#ifdef ENABLE_WALLET
#include "walletframe.h"
#include "walletmodel.h"
+#endif
#ifdef Q_OS_MAC
#include "macdockiconhandler.h"
@@ -59,6 +61,7 @@ const QString BitcoinGUI::DEFAULT_WALLET = "~Default";
BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) :
QMainWindow(parent),
clientModel(0),
+ walletFrame(0),
encryptWalletAction(0),
changePassphraseAction(0),
aboutQtAction(0),
@@ -69,9 +72,22 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) :
{
GUIUtil::restoreWindowGeometry("nWindow", QSize(850, 550), this);
+ QString windowTitle = tr("Bitcoin Core") + " - ";
+#ifdef ENABLE_WALLET
+ /* if compiled with wallet support, -disablewallet can still disable the wallet */
+ bool enableWallet = !GetBoolArg("-disablewallet", false);
+#else
+ bool enableWallet = false;
+#endif
+ if(enableWallet)
+ {
+ windowTitle += tr("Wallet");
+ } else {
+ windowTitle += tr("Node");
+ }
+
if (!fIsTestnet)
{
- setWindowTitle(tr("Bitcoin Core") + " - " + tr("Wallet"));
#ifndef Q_OS_MAC
QApplication::setWindowIcon(QIcon(":icons/bitcoin"));
setWindowIcon(QIcon(":icons/bitcoin"));
@@ -81,7 +97,7 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) :
}
else
{
- setWindowTitle(tr("Bitcoin Core") + " - " + tr("Wallet") + " " + tr("[testnet]"));
+ windowTitle += " " + tr("[testnet]");
#ifndef Q_OS_MAC
QApplication::setWindowIcon(QIcon(":icons/bitcoin_testnet"));
setWindowIcon(QIcon(":icons/bitcoin_testnet"));
@@ -89,6 +105,7 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) :
MacDockIconHandler::instance()->setIcon(QIcon(":icons/bitcoin_testnet"));
#endif
}
+ setWindowTitle(windowTitle);
#if defined(Q_OS_MAC) && QT_VERSION < 0x050000
// This property is not implemented in Qt 5. Setting it has no effect.
@@ -96,9 +113,21 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) :
setUnifiedTitleAndToolBarOnMac(true);
#endif
- // Create wallet frame and make it the central widget
- walletFrame = new WalletFrame(this);
- setCentralWidget(walletFrame);
+ rpcConsole = new RPCConsole(enableWallet ? this : 0);
+#ifdef ENABLE_WALLET
+ if(enableWallet)
+ {
+ /** Create wallet frame and make it the central widget */
+ walletFrame = new WalletFrame(this);
+ setCentralWidget(walletFrame);
+ } else
+#endif
+ {
+ /* When compiled without wallet or -disablewallet is provided,
+ * the central widget is the rpc console.
+ */
+ setCentralWidget(rpcConsole);
+ }
// Accept D&D of URIs
setAcceptDrops(true);
@@ -160,8 +189,8 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) :
syncIconMovie = new QMovie(":/movies/update_spinner", "mng", this);
- rpcConsole = new RPCConsole(this);
connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show()));
+
// prevents an oben debug window from becoming stuck/unusable on client shutdown
connect(quitAction, SIGNAL(triggered()), rpcConsole, SLOT(hide()));
@@ -170,10 +199,16 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) :
// Initially wallet actions should be disabled
setWalletActionsEnabled(false);
+
+ // Subscribe to notifications from core
+ subscribeToCoreSignals();
}
BitcoinGUI::~BitcoinGUI()
{
+ // Unsubscribe from notifications from core
+ unsubscribeFromCoreSignals();
+
GUIUtil::saveWindowGeometry("nWindow", this);
if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
trayIcon->hide();
@@ -280,14 +315,19 @@ void BitcoinGUI::createActions(bool fIsTestnet)
connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
connect(toggleHideAction, SIGNAL(triggered()), this, SLOT(toggleHidden()));
- connect(encryptWalletAction, SIGNAL(triggered(bool)), walletFrame, SLOT(encryptWallet(bool)));
- connect(backupWalletAction, SIGNAL(triggered()), walletFrame, SLOT(backupWallet()));
- connect(changePassphraseAction, SIGNAL(triggered()), walletFrame, SLOT(changePassphrase()));
- connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab()));
- connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab()));
- connect(usedSendingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedSendingAddresses()));
- connect(usedReceivingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedReceivingAddresses()));
- connect(openAction, SIGNAL(triggered()), this, SLOT(openClicked()));
+#ifdef ENABLE_WALLET
+ if(walletFrame)
+ {
+ connect(encryptWalletAction, SIGNAL(triggered(bool)), walletFrame, SLOT(encryptWallet(bool)));
+ connect(backupWalletAction, SIGNAL(triggered()), walletFrame, SLOT(backupWallet()));
+ connect(changePassphraseAction, SIGNAL(triggered()), walletFrame, SLOT(changePassphrase()));
+ connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab()));
+ connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab()));
+ connect(usedSendingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedSendingAddresses()));
+ connect(usedReceivingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedReceivingAddresses()));
+ connect(openAction, SIGNAL(triggered()), this, SLOT(openClicked()));
+ }
+#endif
}
void BitcoinGUI::createMenuBar()
@@ -302,38 +342,50 @@ void BitcoinGUI::createMenuBar()
// Configure the menus
QMenu *file = appMenuBar->addMenu(tr("&File"));
- file->addAction(openAction);
- file->addAction(backupWalletAction);
- file->addAction(signMessageAction);
- file->addAction(verifyMessageAction);
- file->addSeparator();
- file->addAction(usedSendingAddressesAction);
- file->addAction(usedReceivingAddressesAction);
- file->addSeparator();
+ if(walletFrame)
+ {
+ file->addAction(openAction);
+ file->addAction(backupWalletAction);
+ file->addAction(signMessageAction);
+ file->addAction(verifyMessageAction);
+ file->addSeparator();
+ file->addAction(usedSendingAddressesAction);
+ file->addAction(usedReceivingAddressesAction);
+ file->addSeparator();
+ }
file->addAction(quitAction);
QMenu *settings = appMenuBar->addMenu(tr("&Settings"));
- settings->addAction(encryptWalletAction);
- settings->addAction(changePassphraseAction);
- settings->addSeparator();
+ if(walletFrame)
+ {
+ settings->addAction(encryptWalletAction);
+ settings->addAction(changePassphraseAction);
+ settings->addSeparator();
+ }
settings->addAction(optionsAction);
QMenu *help = appMenuBar->addMenu(tr("&Help"));
- help->addAction(openRPCConsoleAction);
- help->addSeparator();
+ if(walletFrame)
+ {
+ help->addAction(openRPCConsoleAction);
+ help->addSeparator();
+ }
help->addAction(aboutAction);
help->addAction(aboutQtAction);
}
void BitcoinGUI::createToolBars()
{
- QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
- toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
- toolbar->addAction(overviewAction);
- toolbar->addAction(sendCoinsAction);
- toolbar->addAction(receiveCoinsAction);
- toolbar->addAction(historyAction);
- overviewAction->setChecked(true);
+ if(walletFrame)
+ {
+ QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
+ toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ toolbar->addAction(overviewAction);
+ toolbar->addAction(sendCoinsAction);
+ toolbar->addAction(receiveCoinsAction);
+ toolbar->addAction(historyAction);
+ overviewAction->setChecked(true);
+ }
}
void BitcoinGUI::setClientModel(ClientModel *clientModel)
@@ -356,26 +408,39 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
rpcConsole->setClientModel(clientModel);
- walletFrame->setClientModel(clientModel);
+#ifdef ENABLE_WALLET
+ if(walletFrame)
+ {
+ walletFrame->setClientModel(clientModel);
+ }
+#endif
}
}
+#ifdef ENABLE_WALLET
bool BitcoinGUI::addWallet(const QString& name, WalletModel *walletModel)
{
+ if(!walletFrame)
+ return false;
setWalletActionsEnabled(true);
return walletFrame->addWallet(name, walletModel);
}
bool BitcoinGUI::setCurrentWallet(const QString& name)
{
+ if(!walletFrame)
+ return false;
return walletFrame->setCurrentWallet(name);
}
void BitcoinGUI::removeAllWallets()
{
+ if(!walletFrame)
+ return;
setWalletActionsEnabled(false);
walletFrame->removeAllWallets();
}
+#endif
void BitcoinGUI::setWalletActionsEnabled(bool enabled)
{
@@ -483,6 +548,7 @@ void BitcoinGUI::aboutClicked()
dlg.exec();
}
+#ifdef ENABLE_WALLET
void BitcoinGUI::openClicked()
{
OpenURIDialog dlg(this);
@@ -525,6 +591,7 @@ void BitcoinGUI::gotoVerifyMessageTab(QString addr)
{
if (walletFrame) walletFrame->gotoVerifyMessageTab(addr);
}
+#endif
void BitcoinGUI::setNumConnections(int count)
{
@@ -585,7 +652,10 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
- walletFrame->showOutOfSyncWarning(false);
+#ifdef ENABLE_WALLET
+ if(walletFrame)
+ walletFrame->showOutOfSyncWarning(false);
+#endif
progressBarLabel->setVisible(false);
progressBar->setVisible(false);
@@ -619,7 +689,10 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
syncIconMovie->jumpToNextFrame();
prevBlocks = count;
- walletFrame->showOutOfSyncWarning(true);
+#ifdef ENABLE_WALLET
+ if(walletFrame)
+ walletFrame->showOutOfSyncWarning(true);
+#endif
tooltip += QString("<br>");
tooltip += tr("Last received block was generated %1 ago.").arg(timeBehindText);
@@ -732,6 +805,7 @@ void BitcoinGUI::closeEvent(QCloseEvent *event)
QMainWindow::closeEvent(event);
}
+#ifdef ENABLE_WALLET
void BitcoinGUI::incomingTransaction(const QString& date, int unit, qint64 amount, const QString& type, const QString& address)
{
// On new transaction, make an info balloon
@@ -745,6 +819,7 @@ void BitcoinGUI::incomingTransaction(const QString& date, int unit, qint64 amoun
.arg(type)
.arg(address), CClientUIInterface::MSG_INFORMATION);
}
+#endif
void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
{
@@ -777,10 +852,11 @@ bool BitcoinGUI::eventFilter(QObject *object, QEvent *event)
return QMainWindow::eventFilter(object, event);
}
+#ifdef ENABLE_WALLET
bool BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient& recipient)
{
// URI has to be valid
- if (walletFrame->handlePaymentRequest(recipient))
+ if (walletFrame && walletFrame->handlePaymentRequest(recipient))
{
showNormalIfMinimized();
gotoSendCoinsPage();
@@ -818,6 +894,7 @@ void BitcoinGUI::setEncryptionStatus(int status)
break;
}
}
+#endif
void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
{
@@ -849,5 +926,35 @@ void BitcoinGUI::toggleHidden()
void BitcoinGUI::detectShutdown()
{
if (ShutdownRequested())
- QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection);
+ {
+ if(rpcConsole)
+ rpcConsole->hide();
+ qApp->quit();
+ }
+}
+
+static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, const std::string& caption, unsigned int style)
+{
+ bool modal = (style & CClientUIInterface::MODAL);
+ bool ret = false;
+ // In case of modal message, use blocking connection to wait for user to click a button
+ QMetaObject::invokeMethod(gui, "message",
+ modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
+ Q_ARG(QString, QString::fromStdString(caption)),
+ Q_ARG(QString, QString::fromStdString(message)),
+ Q_ARG(unsigned int, style),
+ Q_ARG(bool*, &ret));
+ return ret;
+}
+
+void BitcoinGUI::subscribeToCoreSignals()
+{
+ // Connect signals to client
+ uiInterface.ThreadSafeMessageBox.connect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
+}
+
+void BitcoinGUI::unsubscribeFromCoreSignals()
+{
+ // Disconnect signals from client
+ uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
}
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index 75c61d2a8..1038e2739 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -5,6 +5,10 @@
#ifndef BITCOINGUI_H
#define BITCOINGUI_H
+#if defined(HAVE_CONFIG_H)
+#include "bitcoin-config.h"
+#endif
+
#include <QMainWindow>
#include <QMap>
#include <QSystemTrayIcon>
@@ -43,14 +47,15 @@ public:
*/
void setClientModel(ClientModel *clientModel);
+#ifdef ENABLE_WALLET
/** Set the wallet model.
The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending
functionality.
*/
bool addWallet(const QString& name, WalletModel *walletModel);
bool setCurrentWallet(const QString& name);
-
void removeAllWallets();
+#endif
protected:
void changeEvent(QEvent *e);
@@ -111,6 +116,11 @@ private:
/** Enable or disable all wallet-related actions */
void setWalletActionsEnabled(bool enabled);
+ /** Connect core signals to GUI client */
+ void subscribeToCoreSignals();
+ /** Disconnect core signals from GUI client */
+ void unsubscribeFromCoreSignals();
+
signals:
/** Signal raised when a URI was entered or dragged to the GUI */
void receivedURI(const QString &uri);
@@ -120,11 +130,6 @@ public slots:
void setNumConnections(int count);
/** Set number of blocks shown in the UI */
void setNumBlocks(int count, int nTotalBlocks);
- /** Set the encryption status as shown in the UI.
- @param[in] status current encryption status
- @see WalletModel::EncryptionStatus
- */
- void setEncryptionStatus(int status);
/** Notify the user of an event from the core network or transaction handling code.
@param[in] title the message box / notification title
@@ -135,12 +140,21 @@ public slots:
*/
void message(const QString &title, const QString &message, unsigned int style, bool *ret = NULL);
+#ifdef ENABLE_WALLET
+ /** Set the encryption status as shown in the UI.
+ @param[in] status current encryption status
+ @see WalletModel::EncryptionStatus
+ */
+ void setEncryptionStatus(int status);
+
bool handlePaymentRequest(const SendCoinsRecipient& recipient);
/** Show incoming transaction notification for new transactions. */
void incomingTransaction(const QString& date, int unit, qint64 amount, const QString& type, const QString& address);
+#endif
private slots:
+#ifdef ENABLE_WALLET
/** Switch to overview (home) page */
void gotoOverviewPage();
/** Switch to history (transactions) page */
@@ -155,6 +169,9 @@ private slots:
/** Show Sign/Verify Message dialog and switch to verify message tab */
void gotoVerifyMessageTab(QString addr = "");
+ /** Show open dialog */
+ void openClicked();
+#endif
/** Show configuration dialog */
void optionsClicked();
/** Show about dialog */
@@ -163,8 +180,6 @@ private slots:
/** Handle tray icon clicked */
void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
#endif
- /** Show open dialog */
- void openClicked();
/** Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHidden is true */
void showNormalIfMinimized(bool fToggleHidden = false);
diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp
index 1cef397d1..38a029dbe 100644
--- a/src/qt/notificator.cpp
+++ b/src/qt/notificator.cpp
@@ -14,18 +14,18 @@
#include <QSystemTrayIcon>
#include <QTemporaryFile>
#include <QVariant>
-
-#ifdef Q_OS_MAC
-#include "macnotificationhandler.h"
-
-#include <ApplicationServices/ApplicationServices.h>
-#endif
-
#ifdef USE_DBUS
#include <stdint.h>
-
#include <QtDBus>
#endif
+// Include ApplicationServices.h after QtDbus to avoid redefinition of check().
+// This affects at least OSX 10.6. See /usr/include/AssertMacros.h for details.
+// Note: This could also be worked around using:
+// #define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
+#ifdef Q_OS_MAC
+#include <ApplicationServices/ApplicationServices.h>
+#include "macnotificationhandler.h"
+#endif
// https://wiki.ubuntu.com/NotificationDevelopmentGuidelines recommends at least 128
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
index c7817a94a..1133c457b 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -14,8 +14,10 @@
#include "init.h"
#include "main.h"
#include "net.h"
+#ifdef ENABLE_WALLET
#include "wallet.h"
#include "walletdb.h"
+#endif
#include <QSettings>
#include <QStringList>
@@ -67,8 +69,10 @@ void OptionsModel::Init()
// by command-line and show this in the UI.
// Main
+#ifdef ENABLE_WALLET
if (!settings.contains("nTransactionFee"))
settings.setValue("nTransactionFee", 0);
+#endif
if (!settings.contains("nDatabaseCache"))
settings.setValue("nDatabaseCache", 25);
@@ -137,6 +141,7 @@ void OptionsModel::Upgrade()
settings.setValue("bImportFinished", true);
+#ifdef ENABLE_WALLET
// Move settings from old wallet.dat (if any):
CWalletDB walletdb(strWalletFile);
@@ -181,6 +186,7 @@ void OptionsModel::Upgrade()
walletdb.EraseSetting("addrProxy");
}
}
+#endif
Init();
}
@@ -227,6 +233,7 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
case ProxySocksVersion:
return settings.value("nSocksVersion", 5);
+#ifdef ENABLE_WALLET
case Fee:
// Attention: Init() is called before nTransactionFee is set in AppInit2()!
// To ensure we can change the fee on-the-fly update our QSetting when
@@ -236,6 +243,7 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
// Todo: Consider to revert back to use just nTransactionFee here, if we don't want
// -paytxfee to update our QSettings!
return settings.value("nTransactionFee");
+#endif
case DisplayUnit:
return nDisplayUnit;
case DisplayAddresses:
@@ -318,13 +326,14 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
}
}
break;
-
+#ifdef ENABLE_WALLET
case Fee: // core option - can be changed on-the-fly
// Todo: Add is valid check and warn via message, if not
nTransactionFee = value.toLongLong();
settings.setValue("nTransactionFee", (qint64)nTransactionFee);
emit transactionFeeChanged(nTransactionFee);
break;
+#endif
case DisplayUnit:
nDisplayUnit = value.toInt();
settings.setValue("nDisplayUnit", nDisplayUnit);
diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp
index 6fb834c04..8b16496c1 100644
--- a/src/qt/splashscreen.cpp
+++ b/src/qt/splashscreen.cpp
@@ -6,6 +6,7 @@
#include "clientversion.h"
#include "util.h"
+#include "ui_interface.h"
#include <QApplication>
#include <QPainter>
@@ -13,6 +14,8 @@
SplashScreen::SplashScreen(const QPixmap &pixmap, Qt::WindowFlags f, bool isTestNet) :
QSplashScreen(pixmap, f)
{
+ setAutoFillBackground(true);
+
// set reference point, paddings
int paddingRight = 50;
int paddingTop = 50;
@@ -83,4 +86,37 @@ SplashScreen::SplashScreen(const QPixmap &pixmap, Qt::WindowFlags f, bool isTest
pixPaint.end();
this->setPixmap(newPixmap);
+
+ subscribeToCoreSignals();
+}
+
+SplashScreen::~SplashScreen()
+{
+ unsubscribeFromCoreSignals();
+}
+
+void SplashScreen::slotFinish(QWidget *mainWin)
+{
+ finish(mainWin);
+}
+
+static void InitMessage(SplashScreen *splash, const std::string &message)
+{
+ QMetaObject::invokeMethod(splash, "showMessage",
+ Qt::QueuedConnection,
+ Q_ARG(QString, QString::fromStdString(message)),
+ Q_ARG(int, Qt::AlignBottom|Qt::AlignHCenter),
+ Q_ARG(QColor, QColor(55,55,55)));
+}
+
+void SplashScreen::subscribeToCoreSignals()
+{
+ // Connect signals to client
+ uiInterface.InitMessage.connect(boost::bind(InitMessage, this, _1));
+}
+
+void SplashScreen::unsubscribeFromCoreSignals()
+{
+ // Disconnect signals from client
+ uiInterface.InitMessage.disconnect(boost::bind(InitMessage, this, _1));
}
diff --git a/src/qt/splashscreen.h b/src/qt/splashscreen.h
index 070e376c9..6bc10e60a 100644
--- a/src/qt/splashscreen.h
+++ b/src/qt/splashscreen.h
@@ -15,6 +15,17 @@ class SplashScreen : public QSplashScreen
public:
explicit SplashScreen(const QPixmap &pixmap, Qt::WindowFlags f, bool isTestNet);
+ ~SplashScreen();
+
+public slots:
+ /** Slot to call finish() method as it's not defined as slot */
+ void slotFinish(QWidget *mainWin);
+
+private:
+ /** Connect core signals to splash screen */
+ void subscribeToCoreSignals();
+ /** Disconnect core signals to splash screen */
+ void unsubscribeFromCoreSignals();
};
#endif // SPLASHSCREEN_H
diff --git a/src/qt/test/Makefile.am b/src/qt/test/Makefile.am
index cb6874700..9c3f0417a 100644
--- a/src/qt/test/Makefile.am
+++ b/src/qt/test/Makefile.am
@@ -8,17 +8,35 @@ AM_CPPFLAGS += -I$(top_srcdir)/src \
bin_PROGRAMS = test_bitcoin-qt
TESTS = test_bitcoin-qt
-TEST_QT_MOC_CPP = moc_uritests.cpp moc_paymentservertests.cpp
+TEST_QT_MOC_CPP = moc_uritests.cpp
-TEST_QT_H = uritests.h paymentservertests.h paymentrequestdata.h
+if ENABLE_WALLET
+TEST_QT_MOC_CPP += moc_paymentservertests.cpp
+endif
+
+TEST_QT_H = \
+ uritests.h \
+ paymentservertests.h \
+ paymentrequestdata.h
BUILT_SOURCES = $(TEST_QT_MOC_CPP)
test_bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(QT_INCLUDES) $(QT_TEST_INCLUDES)
-test_bitcoin_qt_SOURCES = test_main.cpp uritests.cpp paymentservertests.cpp $(TEST_QT_H)
+test_bitcoin_qt_SOURCES = \
+ test_main.cpp \
+ uritests.cpp \
+ $(TEST_QT_H)
+if ENABLE_WALLET
+test_bitcoin_qt_SOURCES += \
+ paymentservertests.cpp
+endif
nodist_test_bitcoin_qt_SOURCES = $(TEST_QT_MOC_CPP)
-test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER) $(LIBBITCOIN_WALLET) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBLEVELDB) \
- $(LIBMEMENV) $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) \
+test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER)
+if ENABLE_WALLET
+test_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
+endif
+test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBLEVELDB) \
+ $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
$(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
CLEANFILES = $(BUILT_SOURCES) *.gcda *.gcno
diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp
index ae584706f..a2adb0032 100644
--- a/src/qt/test/test_main.cpp
+++ b/src/qt/test/test_main.cpp
@@ -1,10 +1,25 @@
+#include "bitcoin-config.h"
+#if defined(HAVE_CONFIG_H)
+#include "bitcoin-config.h"
+#endif
+
+#ifdef ENABLE_WALLET
#include "paymentservertests.h"
+#endif
#include "uritests.h"
#include <QCoreApplication>
#include <QObject>
#include <QTest>
+#if defined(QT_STATICPLUGIN) && QT_VERSION < 0x050000
+#include <QtPlugin>
+Q_IMPORT_PLUGIN(qcncodecs)
+Q_IMPORT_PLUGIN(qjpcodecs)
+Q_IMPORT_PLUGIN(qtwcodecs)
+Q_IMPORT_PLUGIN(qkrcodecs)
+#endif
+
// This is all you need to run all the tests
int main(int argc, char *argv[])
{
@@ -18,10 +33,11 @@ int main(int argc, char *argv[])
URITests test1;
if (QTest::qExec(&test1) != 0)
fInvalid = true;
-
+#ifdef ENABLE_WALLET
PaymentServerTests test2;
if (QTest::qExec(&test2) != 0)
fInvalid = true;
+#endif
return fInvalid;
}
diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp
index c61cc4192..f8a7d07fc 100644
--- a/src/rpcmisc.cpp
+++ b/src/rpcmisc.cpp
@@ -4,11 +4,11 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "base58.h"
-#include "rpcserver.h"
#include "init.h"
#include "main.h"
#include "net.h"
#include "netbase.h"
+#include "rpcserver.h"
#include "util.h"
#ifdef ENABLE_WALLET
#include "wallet.h"
@@ -323,4 +323,3 @@ Value verifymessage(const Array& params, bool fHelp)
return (pubkey.GetID() == keyID);
}
-
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
index 86025918e..ff652ca34 100644
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -4,13 +4,13 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "base58.h"
-#include "rpcserver.h"
+#include "core.h"
#include "init.h"
+#include "keystore.h"
+#include "main.h"
#include "net.h"
+#include "rpcserver.h"
#include "uint256.h"
-#include "core.h"
-#include "main.h"
-#include "keystore.h"
#ifdef ENABLE_WALLET
#include "wallet.h"
#endif
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index 9f2100a8d..9d34a900f 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -8,8 +8,8 @@
#include "base58.h"
#include "init.h"
#include "main.h"
-#include "util.h"
#include "ui_interface.h"
+#include "util.h"
#ifdef ENABLE_WALLET
#include "wallet.h"
#endif
diff --git a/src/test/Makefile.am b/src/test/Makefile.am
index 384616e89..667e53c6b 100644
--- a/src/test/Makefile.am
+++ b/src/test/Makefile.am
@@ -6,12 +6,15 @@ bin_PROGRAMS = test_bitcoin
TESTS = test_bitcoin
-JSON_TEST_FILES= data/script_valid.json \
- data/base58_keys_valid.json data/sig_canonical.json \
+JSON_TEST_FILES = \
+ data/script_valid.json \
+ data/base58_keys_valid.json \
+ data/sig_canonical.json \
data/sig_noncanonical.json \
data/base58_encode_decode.json \
data/base58_keys_invalid.json \
- data/script_invalid.json data/tx_invalid.json \
+ data/script_invalid.json \
+ data/tx_invalid.json \
data/tx_valid.json
RAW_TEST_FILES = data/alertTests.raw
@@ -27,18 +30,43 @@ test_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
endif
test_bitcoin_LDADD += $(BDB_LIBS)
-test_bitcoin_SOURCES = alert_tests.cpp \
- allocator_tests.cpp base32_tests.cpp base58_tests.cpp base64_tests.cpp \
- bignum_tests.cpp bloom_tests.cpp canonical_tests.cpp checkblock_tests.cpp \
- Checkpoints_tests.cpp compress_tests.cpp DoS_tests.cpp getarg_tests.cpp \
- key_tests.cpp miner_tests.cpp mruset_tests.cpp multisig_tests.cpp \
- netbase_tests.cpp pmt_tests.cpp rpc_tests.cpp script_P2SH_tests.cpp \
- script_tests.cpp serialize_tests.cpp sigopcount_tests.cpp test_bitcoin.cpp \
- transaction_tests.cpp uint256_tests.cpp util_tests.cpp \
- sighash_tests.cpp $(JSON_TEST_FILES) $(RAW_TEST_FILES)
+test_bitcoin_SOURCES = \
+ alert_tests.cpp \
+ allocator_tests.cpp \
+ base32_tests.cpp \
+ base58_tests.cpp \
+ base64_tests.cpp \
+ bignum_tests.cpp \
+ bloom_tests.cpp \
+ canonical_tests.cpp \
+ checkblock_tests.cpp \
+ Checkpoints_tests.cpp \
+ compress_tests.cpp \
+ DoS_tests.cpp \
+ getarg_tests.cpp \
+ key_tests.cpp \
+ miner_tests.cpp \
+ mruset_tests.cpp \
+ multisig_tests.cpp \
+ netbase_tests.cpp \
+ pmt_tests.cpp \
+ rpc_tests.cpp \
+ script_P2SH_tests.cpp \
+ script_tests.cpp \
+ serialize_tests.cpp \
+ sigopcount_tests.cpp \
+ test_bitcoin.cpp \
+ transaction_tests.cpp \
+ uint256_tests.cpp \
+ util_tests.cpp \
+ sighash_tests.cpp \
+ $(JSON_TEST_FILES) $(RAW_TEST_FILES)
if ENABLE_WALLET
-test_bitcoin_SOURCES += accounting_tests.cpp wallet_tests.cpp rpc_wallet_tests.cpp
+test_bitcoin_SOURCES += \
+ accounting_tests.cpp \
+ wallet_tests.cpp \
+ rpc_wallet_tests.cpp
endif
nodist_test_bitcoin_SOURCES = $(BUILT_SOURCES)