diff options
| -rw-r--r-- | configure.ac | 221 | ||||
| -rwxr-xr-x | qa/rpc-tests/send.sh | 14 | ||||
| -rw-r--r-- | qa/rpc-tests/util.sh | 5 | ||||
| -rwxr-xr-x | qa/rpc-tests/wallet.sh | 1 | ||||
| -rw-r--r-- | src/Makefile.am | 79 | ||||
| -rw-r--r-- | src/Makefile.include | 9 | ||||
| -rw-r--r-- | src/m4/bitcoin_qt.m4 | 380 | ||||
| -rw-r--r-- | src/net.h | 4 | ||||
| -rw-r--r-- | src/qt/Makefile.am | 253 | ||||
| -rw-r--r-- | src/qt/bitcoin.cpp | 503 | ||||
| -rw-r--r-- | src/qt/bitcoingui.cpp | 185 | ||||
| -rw-r--r-- | src/qt/bitcoingui.h | 31 | ||||
| -rw-r--r-- | src/qt/notificator.cpp | 16 | ||||
| -rw-r--r-- | src/qt/optionsmodel.cpp | 11 | ||||
| -rw-r--r-- | src/qt/splashscreen.cpp | 36 | ||||
| -rw-r--r-- | src/qt/splashscreen.h | 11 | ||||
| -rw-r--r-- | src/qt/test/Makefile.am | 28 | ||||
| -rw-r--r-- | src/qt/test/test_main.cpp | 18 | ||||
| -rw-r--r-- | src/rpcmisc.cpp | 3 | ||||
| -rw-r--r-- | src/rpcrawtransaction.cpp | 8 | ||||
| -rw-r--r-- | src/rpcserver.cpp | 2 | ||||
| -rw-r--r-- | src/test/Makefile.am | 54 |
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" +]) + @@ -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) |