diff --git a/cmake/platforms/OSX.cmake b/cmake/platforms/OSX.cmake
index 20c292788..624f1febb 100644
--- a/cmake/platforms/OSX.cmake
+++ b/cmake/platforms/OSX.cmake
@@ -1,41 +1,41 @@
# Copyright (c) 2017 The Bitcoin developers
set(CMAKE_SYSTEM_NAME Darwin)
-set(TOOLCHAIN_PREFIX x86_64-apple-darwin11)
+set(TOOLCHAIN_PREFIX x86_64-apple-darwin14)
# On OSX, we use clang by default.
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
# On OSX we use various stuff from Apple's SDK.
set(OSX_SDK_PATH "${CMAKE_CURRENT_SOURCE_DIR}/depends/SDKs/MacOSX10.11.sdk")
set(CMAKE_OSX_SYSROOT ${OSX_SDK_PATH})
-set(CMAKE_OSX_DEPLOYMENT_TARGET 10.8)
+set(CMAKE_OSX_DEPLOYMENT_TARGET 10.10)
# target environment on the build host system
# set 1st to dir with the cross compiler's C/C++ headers/libs
set(CMAKE_FIND_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/depends/${TOOLCHAIN_PREFIX};${OSX_SDK_PATH}")
# We also may have built dependencies for the native plateform.
set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/depends/${TOOLCHAIN_PREFIX}/native")
# modify default behavior of FIND_XXX() commands to
# search for headers/libs in the target environment and
# search for programs in the build host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# Sysroot clang
set(OSX_EXTRA_FLAGS
" -target ${TOOLCHAIN_PREFIX}"
" -mlinker-version=253.9"
)
string(APPEND CMAKE_C_FLAGS_INIT ${OSX_EXTRA_FLAGS})
string(APPEND CMAKE_CXX_FLAGS_INIT ${OSX_EXTRA_FLAGS} " -stdlib=libc++")
# Ensure we use an OSX specific version of ar, ranlib and nm.
find_program(CMAKE_AR ${TOOLCHAIN_PREFIX}-ar)
find_program(CMAKE_RANLIB ${TOOLCHAIN_PREFIX}-ranlib)
find_program(CMAKE_NM ${TOOLCHAIN_PREFIX}-nm)
diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml
index 4b985431f..e554bff8b 100644
--- a/contrib/gitian-descriptors/gitian-osx.yml
+++ b/contrib/gitian-descriptors/gitian-osx.yml
@@ -1,161 +1,161 @@
---
name: "bitcoin-abc-0.20-osx"
enable_cache: true
distro: "debian"
suites:
- "stretch"
architectures:
- "amd64"
packages:
- "ca-certificates"
- "curl"
- "g++"
- "git"
- "pkg-config"
- "autoconf"
- "librsvg2-bin"
- "libtiff-tools"
- "libtool"
- "automake"
- "faketime"
- "bsdmainutils"
- "cmake"
- "ninja-build"
- "imagemagick"
- "libcap-dev"
- "libz-dev"
- "libbz2-dev"
- "python"
- "python-dev"
- "python-setuptools"
- "fonts-tuffy"
remotes:
- "url": "https://github.com/Bitcoin-ABC/bitcoin-abc.git"
"dir": "bitcoin"
files:
- "MacOSX10.11.sdk.tar.gz"
script: |
WRAP_DIR=$HOME/wrapped
- HOSTS="x86_64-apple-darwin11"
+ HOSTS="x86_64-apple-darwin14"
CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests GENISOIMAGE=$WRAP_DIR/genisoimage"
FAKETIME_HOST_PROGS=""
FAKETIME_PROGS="ar ranlib date dmg genisoimage"
export QT_RCC_TEST=1
export QT_RCC_SOURCE_DATE_OVERRIDE=1
export GZIP="-9n"
export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
export TZ="UTC"
export BUILD_DIR=`pwd`
mkdir -p ${WRAP_DIR}
if test -n "$GBUILD_CACHE_ENABLED"; then
export SOURCES_PATH=${GBUILD_COMMON_CACHE}
export BASE_CACHE=${GBUILD_PACKAGE_CACHE}
mkdir -p ${BASE_CACHE} ${SOURCES_PATH}
fi
export ZERO_AR_DATE=1
function create_global_faketime_wrappers {
for prog in ${FAKETIME_PROGS}; do
echo '#!/bin/bash' > ${WRAP_DIR}/${prog}
echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog}
echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog}
echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog}
echo "\$REAL \$@" >> $WRAP_DIR/${prog}
chmod +x ${WRAP_DIR}/${prog}
done
}
function create_per-host_faketime_wrappers {
for i in $HOSTS; do
for prog in ${FAKETIME_HOST_PROGS}; do
echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog}
echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog}
echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog}
echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog}
echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog}
chmod +x ${WRAP_DIR}/${i}-${prog}
done
done
}
# Faketime for depends so intermediate results are comparable
export PATH_orig=${PATH}
create_global_faketime_wrappers "2000-01-01 12:00:00"
create_per-host_faketime_wrappers "2000-01-01 12:00:00"
export PATH=${WRAP_DIR}:${PATH}
cd bitcoin
BASEPREFIX=`pwd`/depends
mkdir -p ${BASEPREFIX}/SDKs
tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.11.sdk.tar.gz
# Build dependencies for each host
for i in $HOSTS; do
make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
done
# Faketime for binaries
export PATH=${PATH_orig}
create_global_faketime_wrappers "${REFERENCE_DATETIME}"
create_per-host_faketime_wrappers "${REFERENCE_DATETIME}"
export PATH=${WRAP_DIR}:${PATH}
# Create the release tarball using (arbitrarily) the first host
./autogen.sh
CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/
make dist
SOURCEDIST=`echo bitcoin-abc-*.tar.gz`
DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'`
# Correct tar file order
mkdir -p temp
pushd temp
tar xf ../$SOURCEDIST
find bitcoin-abc-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST
popd
ORIGPATH="$PATH"
# Extract the release tarball into a dir for each host and build
for i in ${HOSTS}; do
export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH}
mkdir -p distsrc-${i}
cd distsrc-${i}
INSTALLPATH=`pwd`/installed/${DISTNAME}
mkdir -p ${INSTALLPATH}
tar --strip-components=1 -xf ../$SOURCEDIST
CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS}
make ${MAKEOPTS}
make install-strip DESTDIR=${INSTALLPATH}
make osx_volname
make deploydir
OSX_VOLNAME="$(cat osx_volname)"
mkdir -p unsigned-app-${i}
cp osx_volname unsigned-app-${i}/
cp contrib/macdeploy/detached-sig-apply.sh unsigned-app-${i}
cp contrib/macdeploy/detached-sig-create.sh unsigned-app-${i}
cp ${BASEPREFIX}/${i}/native/bin/dmg ${BASEPREFIX}/${i}/native/bin/genisoimage unsigned-app-${i}
cp ${BASEPREFIX}/${i}/native/bin/${i}-codesign_allocate unsigned-app-${i}/codesign_allocate
cp ${BASEPREFIX}/${i}/native/bin/${i}-pagestuff unsigned-app-${i}/pagestuff
mv dist unsigned-app-${i}
pushd unsigned-app-${i}
find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz
popd
make deploy
${WRAP_DIR}/dmg dmg "${OSX_VOLNAME}.dmg" ${OUTDIR}/${DISTNAME}-osx-unsigned.dmg
cd installed
find . -name "lib*.la" -delete
find . -name "lib*.a" -delete
rm -rf ${DISTNAME}/lib/pkgconfig
find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
cd ../../
done
mkdir -p $OUTDIR/src
mv $SOURCEDIST $OUTDIR/src
mv ${OUTDIR}/${DISTNAME}-x86_64-*.tar.gz ${OUTDIR}/${DISTNAME}-osx64.tar.gz
diff --git a/depends/Makefile b/depends/Makefile
index 472ce2597..1b03ac5d2 100644
--- a/depends/Makefile
+++ b/depends/Makefile
@@ -1,197 +1,197 @@
.NOTPARALLEL :
SOURCES_PATH ?= $(BASEDIR)/sources
BASE_CACHE ?= $(BASEDIR)/built
SDK_PATH ?= $(BASEDIR)/SDKs
NO_QT ?=
NO_WALLET ?=
NO_UPNP ?=
FALLBACK_DOWNLOAD_PATH ?= https://download.bitcoinabc.org/depends-sources
BUILD = $(shell ./config.guess)
HOST ?= $(BUILD)
PATCHES_PATH = $(BASEDIR)/patches
BASEDIR = $(CURDIR)
HASH_LENGTH:=11
DOWNLOAD_CONNECT_TIMEOUT:=30
DOWNLOAD_RETRIES:=3
HOST_ID_SALT ?= salt
BUILD_ID_SALT ?= salt
host:=$(BUILD)
ifneq ($(HOST),)
host:=$(HOST)
host_toolchain:=$(HOST)-
endif
ifneq ($(DEBUG),)
release_type=debug
else
release_type=release
endif
base_build_dir=$(BASEDIR)/work/build
base_staging_dir=$(BASEDIR)/work/staging
base_download_dir=$(BASEDIR)/work/download
canonical_host:=$(shell ./config.sub $(HOST))
build:=$(shell ./config.sub $(BUILD))
build_arch =$(firstword $(subst -, ,$(build)))
build_vendor=$(word 2,$(subst -, ,$(build)))
full_build_os:=$(subst $(build_arch)-$(build_vendor)-,,$(build))
build_os:=$(findstring linux,$(full_build_os))
build_os+=$(findstring darwin,$(full_build_os))
build_os:=$(strip $(build_os))
ifeq ($(build_os),)
build_os=$(full_build_os)
endif
host_arch=$(firstword $(subst -, ,$(canonical_host)))
host_vendor=$(word 2,$(subst -, ,$(canonical_host)))
full_host_os:=$(subst $(host_arch)-$(host_vendor)-,,$(canonical_host))
host_os:=$(findstring linux,$(full_host_os))
host_os+=$(findstring darwin,$(full_host_os))
host_os+=$(findstring mingw32,$(full_host_os))
host_os:=$(strip $(host_os))
ifeq ($(host_os),)
host_os=$(full_host_os)
endif
$(host_arch)_$(host_os)_prefix=$(BASEDIR)/$(host)
$(host_arch)_$(host_os)_host=$(host)
host_prefix=$($(host_arch)_$(host_os)_prefix)
build_prefix=$(host_prefix)/native
build_host=$(build)
AT_$(V):=
AT_:=@
AT:=$(AT_$(V))
all: install
include hosts/$(host_os).mk
include hosts/default.mk
include builders/$(build_os).mk
include builders/default.mk
include packages/packages.mk
build_id_string:=$(BUILD_ID_SALT)
build_id_string+=$(shell $(build_CC) --version 2>/dev/null)
build_id_string+=$(shell $(build_AR) --version 2>/dev/null)
build_id_string+=$(shell $(build_CXX) --version 2>/dev/null)
build_id_string+=$(shell $(build_RANLIB) --version 2>/dev/null)
build_id_string+=$(shell $(build_STRIP) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string:=$(HOST_ID_SALT)
$(host_arch)_$(host_os)_id_string+=$(shell $(host_CC) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string+=$(shell $(host_AR) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string+=$(shell $(host_CXX) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string+=$(shell $(host_RANLIB) --version 2>/dev/null)
$(host_arch)_$(host_os)_id_string+=$(shell $(host_STRIP) --version 2>/dev/null)
qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch)_$(host_os)_packages)
wallet_packages_$(NO_WALLET) = $(wallet_packages)
upnp_packages_$(NO_UPNP) = $(upnp_packages)
packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(wallet_packages_) $(upnp_packages_)
native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages)
ifneq ($(qt_packages_),)
native_packages += $(qt_native_packages)
endif
all_packages = $(packages) $(native_packages)
meta_depends = Makefile funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk
$(host_arch)_$(host_os)_native_toolchain?=$($(host_os)_native_toolchain)
include funcs.mk
toolchain_path=$($($(host_arch)_$(host_os)_native_toolchain)_prefixbin)
final_build_id_long+=$(shell $(build_SHA256SUM) config.site.in)
final_build_id+=$(shell echo -n "$(final_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH))
$(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages)
$(AT)rm -rf $(@D)
$(AT)mkdir -p $(@D)
$(AT)echo copying packages: $^
$(AT)echo to: $(@D)
$(AT)cd $(@D); $(foreach package,$^, tar xf $($(package)_cached); )
$(AT)touch $@
$(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_build_id)
$(AT)@mkdir -p $(@D)
$(AT)sed -e 's|@HOST@|$(host)|' \
-e 's|@CC@|$(toolchain_path)$(host_CC)|' \
-e 's|@CXX@|$(toolchain_path)$(host_CXX)|' \
-e 's|@AR@|$(toolchain_path)$(host_AR)|' \
-e 's|@RANLIB@|$(toolchain_path)$(host_RANLIB)|' \
-e 's|@NM@|$(toolchain_path)$(host_NM)|' \
-e 's|@STRIP@|$(toolchain_path)$(host_STRIP)|' \
-e 's|@build_os@|$(build_os)|' \
-e 's|@host_os@|$(host_os)|' \
-e 's|@CFLAGS@|$(strip $(host_CFLAGS) $(host_$(release_type)_CFLAGS))|' \
-e 's|@CXXFLAGS@|$(strip $(host_CXXFLAGS) $(host_$(release_type)_CXXFLAGS))|' \
-e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS) $(host_$(release_type)_CPPFLAGS))|' \
-e 's|@LDFLAGS@|$(strip $(host_LDFLAGS) $(host_$(release_type)_LDFLAGS))|' \
-e 's|@no_qt@|$(NO_QT)|' \
-e 's|@no_wallet@|$(NO_WALLET)|' \
-e 's|@no_upnp@|$(NO_UPNP)|' \
-e 's|@debug@|$(DEBUG)|' \
$< > $@
$(AT)touch $@
define check_or_remove_cached
mkdir -p $(BASE_CACHE)/$(host)/$(package) && cd $(BASE_CACHE)/$(host)/$(package); \
$(build_SHA256SUM) -c $($(package)_cached_checksum) >/dev/null 2>/dev/null || \
( rm -f $($(package)_cached_checksum); \
if test -f "$($(package)_cached)"; then echo "Checksum mismatch for $(package). Forcing rebuild.."; rm -f $($(package)_cached_checksum) $($(package)_cached); fi )
endef
define check_or_remove_sources
mkdir -p $($(package)_source_dir); cd $($(package)_source_dir); \
test -f $($(package)_fetched) && ( $(build_SHA256SUM) -c $($(package)_fetched) >/dev/null 2>/dev/null || \
( echo "Checksum missing or mismatched for $(package) source. Forcing re-download."; \
rm -f $($(package)_all_sources) $($(1)_fetched))) || true
endef
check-packages:
@$(foreach package,$(all_packages),$(call check_or_remove_cached,$(package));)
check-sources:
@$(foreach package,$(all_packages),$(call check_or_remove_sources,$(package));)
$(host_prefix)/share/config.site: check-packages
check-packages: check-sources
install: check-packages $(host_prefix)/share/config.site
download-one: check-sources $(all_sources)
download-osx:
- @$(MAKE) -s HOST=x86_64-apple-darwin11 download-one
+ @$(MAKE) -s HOST=x86_64-apple-darwin14 download-one
download-linux:
@$(MAKE) -s HOST=x86_64-unknown-linux-gnu download-one
download-win:
@$(MAKE) -s HOST=x86_64-w64-mingw32 download-one
download: download-osx download-linux download-win
build-linux64: download-linux
@$(MAKE) -s HOST=x86_64-linux-gnu install
build-linux32: download-linux
@$(MAKE) -s HOST=i686-pc-linux-gnu install
build-linux-arm: download-linux
@$(MAKE) -s HOST=arm-linux-gnueabihf install
build-linux-aarch64: download-linux
@$(MAKE) -s HOST=aarch64-linux-gnu install
build-osx: download-osx
@$(MAKE) -s HOST=x86_64-apple-darwin11 install
build-win32: download-win
@$(MAKE) -s HOST=i686-w64-mingw32 install
build-win64: download-win
@$(MAKE) -s HOST=x86_64-w64-mingw32 install
build-all: build-linux64 build-linux32 build-linux-arm build-linux-aarch64 build-osx build-win32 build-win64
.PHONY: install cached download-one download-osx download-linux download-win download check-packages check-sources
diff --git a/depends/README.md b/depends/README.md
index 62b08f5ac..65652a78b 100644
--- a/depends/README.md
+++ b/depends/README.md
@@ -1,59 +1,59 @@
### Usage
To build dependencies for the current arch+OS:
make
To build for another arch/OS:
make HOST=host-platform-triplet
For example:
make HOST=x86_64-w64-mingw32 -j4
A prefix will be generated that's suitable for plugging into Bitcoin's
configure. In the above example, a dir named x86_64-w64-mingw32 will be
created. To use it for bitcoin-abc:
./configure --prefix=`pwd`/depends/x86_64-w64-mingw32
Common `host-platform-triplets` for cross compilation are:
- `i686-w64-mingw32` for Win32
- `x86_64-w64-mingw32` for Win64
-- `x86_64-apple-darwin11` for macOS
+- `x86_64-apple-darwin14` for macOS
- `arm-linux-gnueabihf` for Linux ARM 32 bit
- `aarch64-linux-gnu` for Linux ARM 64 bit
No other options are needed, the paths are automatically configured.
Dependency Options:
The following can be set when running make: make FOO=bar
SOURCES_PATH: downloaded sources will be placed here
BASE_CACHE: built packages will be placed here
SDK_PATH: Path where sdk's can be found (used by macOS)
FALLBACK_DOWNLOAD_PATH: If a source file can't be fetched, try here before giving up
NO_QT: Don't download/build/cache qt and its dependencies
NO_WALLET: Don't download/build/cache libs needed to enable the wallet
NO_UPNP: Don't download/build/cache packages needed for enabling upnp
DEBUG: disable some optimizations and enable more runtime checking
HOST_ID_SALT: Optional salt to use when generating host package ids
BUILD_ID_SALT: Optional salt to use when generating build package ids
If some packages are not built, for example `make NO_WALLET=1`, the appropriate
options will be passed to bitcoin's configure. In this case, `--disable-wallet`.
Additional targets:
download: run 'make download' to fetch all sources without building them
download-osx: run 'make download-osx' to fetch all sources needed for macOS builds
download-win: run 'make download-win' to fetch all sources needed for win builds
download-linux: run 'make download-linux' to fetch all sources needed for linux builds
### Other documentation
- [description.md](description.md): General description of the depends system
- [packages.md](packages.md): Steps for adding packages
diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk
index 4e58bec74..a1c943d60 100644
--- a/depends/hosts/darwin.mk
+++ b/depends/hosts/darwin.mk
@@ -1,17 +1,17 @@
-OSX_MIN_VERSION=10.8
+OSX_MIN_VERSION=10.10
OSX_SDK_VERSION=10.11
OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk
LD64_VERSION=253.9
darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION)
darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -stdlib=libc++
darwin_CFLAGS=-pipe
darwin_CXXFLAGS=$(darwin_CFLAGS)
darwin_release_CFLAGS=-O2
darwin_release_CXXFLAGS=$(darwin_release_CFLAGS)
darwin_debug_CFLAGS=-O1
darwin_debug_CXXFLAGS=$(darwin_debug_CFLAGS)
darwin_native_toolchain=native_cctools
diff --git a/doc/release-notes.md b/doc/release-notes.md
index d33372758..3c7abec82 100644
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -1,5 +1,8 @@
Bitcoin ABC version 0.20.1 is now available from:
This release includes the following features and fixes:
+ - From 0.20.1 onwards macOS <10.10 is no longer supported.
+ 0.20.1 is built using Qt 5.9.6, which doesn't support
+ versions of macOS older than 10.10.
diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in
index 21fadd946..9e141f1d9 100644
--- a/share/qt/Info.plist.in
+++ b/share/qt/Info.plist.in
@@ -1,106 +1,106 @@
LSMinimumSystemVersion
- 10.8.0
+ 10.10.0
LSArchitecturePriority
x86_64
CFBundleIconFile
bitcoin.icns
CFBundlePackageType
APPL
CFBundleGetInfoString
@CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@, Copyright © 2009-@COPYRIGHT_YEAR@ @COPYRIGHT_HOLDERS_FINAL@
CFBundleShortVersionString
@CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@
CFBundleVersion
@CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@
CFBundleSignature
????
CFBundleExecutable
BitcoinABC-Qt
CFBundleName
BitcoinABC-Qt
LSHasLocalizedDisplayName
CFBundleIdentifier
org.bitcoinabc.BitcoinABC-Qt
CFBundleURLTypes
CFBundleTypeRole
Editor
CFBundleURLName
org.bitcoincash.BitcoinPayment
CFBundleURLSchemes
bitcoincash
UTExportedTypeDeclarations
UTTypeIdentifier
org.bitcoincash.paymentrequest
UTTypeDescription
Bitcoin Cash payment request
UTTypeConformsTo
public.data
UTTypeTagSpecification
public.mime-type
application/bitcoincash-paymentrequest
public.filename-extension
bitcoincashpaymentrequest
CFBundleDocumentTypes
CFBundleTypeRole
Editor
LSItemContentTypes
org.bitcoincash.paymentrequest
LSHandlerRank
Owner
NSPrincipalClass
NSApplication
NSHighResolutionCapable
True
LSAppNapIsDisabled
True
LSApplicationCategoryType
public.app-category.finance
diff --git a/src/compat/byteswap.h b/src/compat/byteswap.h
index c30b60189..99378031a 100644
--- a/src/compat/byteswap.h
+++ b/src/compat/byteswap.h
@@ -1,64 +1,64 @@
// Copyright (c) 2014-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_COMPAT_BYTESWAP_H
#define BITCOIN_COMPAT_BYTESWAP_H
#if defined(HAVE_CONFIG_H)
#include
#endif
#include
#if defined(HAVE_BYTESWAP_H)
#include
#endif
-#if defined(__APPLE__)
+#if defined(MAC_OSX)
#if !defined(bswap_16)
// Mac OS X / Darwin features; we include a check for bswap_16 because if it is
// already defined, protobuf has defined these macros for us already; if it
// isn't, we do it ourselves. In either case, we get the exact same result
// regardless which path was taken
#include
#define bswap_16(x) OSSwapInt16(x)
#define bswap_32(x) OSSwapInt32(x)
#define bswap_64(x) OSSwapInt64(x)
#endif // !defined(bswap_16)
#else
// Non-Mac OS X / non-Darwin
#if HAVE_DECL_BSWAP_16 == 0
inline uint16_t bswap_16(uint16_t x) {
return (x >> 8) | ((x & 0x00ff) << 8);
}
#endif // HAVE_DECL_BSWAP16
#if HAVE_DECL_BSWAP_32 == 0
inline uint32_t bswap_32(uint32_t x) {
return (((x & 0xff000000U) >> 24) | ((x & 0x00ff0000U) >> 8) |
((x & 0x0000ff00U) << 8) | ((x & 0x000000ffU) << 24));
}
#endif // HAVE_DECL_BSWAP32
#if HAVE_DECL_BSWAP_64 == 0
inline uint64_t bswap_64(uint64_t x) {
return (((x & 0xff00000000000000ull) >> 56) |
((x & 0x00ff000000000000ull) >> 40) |
((x & 0x0000ff0000000000ull) >> 24) |
((x & 0x000000ff00000000ull) >> 8) |
((x & 0x00000000ff000000ull) << 8) |
((x & 0x0000000000ff0000ull) << 24) |
((x & 0x000000000000ff00ull) << 40) |
((x & 0x00000000000000ffull) << 56));
}
#endif // HAVE_DECL_BSWAP64
-#endif // defined(__APPLE__)
+#endif // defined(MAC_OSX)
#endif // BITCOIN_COMPAT_BYTESWAP_H
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 377c716c6..5a52d1bfa 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -1,858 +1,857 @@
// Copyright (c) 2011-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
#include
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef ENABLE_WALLET
#include
#include
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#if defined(QT_STATICPLUGIN)
#include
#if QT_VERSION < 0x050400
Q_IMPORT_PLUGIN(AccessibleFactory)
#endif
#if defined(QT_QPA_PLATFORM_XCB)
Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
#elif defined(QT_QPA_PLATFORM_WINDOWS)
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
#elif defined(QT_QPA_PLATFORM_COCOA)
Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
#endif
#endif
#include
// Declare meta types used for QMetaObject::invokeMethod
Q_DECLARE_METATYPE(bool *)
Q_DECLARE_METATYPE(Amount)
Q_DECLARE_METATYPE(uint256)
// Config is non-copyable so we can only register pointers to it
Q_DECLARE_METATYPE(Config *)
static void InitMessage(const std::string &message) {
LogPrintf("init message: %s\n", message);
}
/**
* Translate string to current locale using Qt.
*/
static std::string Translate(const char *psz) {
return QCoreApplication::translate("bitcoin-abc", psz).toStdString();
}
static QString GetLangTerritory() {
QSettings settings;
// Get desired locale (e.g. "de_DE")
// 1) System default language
QString lang_territory = QLocale::system().name();
// 2) Language from QSettings
QString lang_territory_qsettings =
settings.value("language", "").toString();
if (!lang_territory_qsettings.isEmpty()) {
lang_territory = lang_territory_qsettings;
}
// 3) -lang command line argument
lang_territory = QString::fromStdString(
gArgs.GetArg("-lang", lang_territory.toStdString()));
return lang_territory;
}
/** Set up translations */
static void initTranslations(QTranslator &qtTranslatorBase,
QTranslator &qtTranslator,
QTranslator &translatorBase,
QTranslator &translator) {
// Remove old translators
QApplication::removeTranslator(&qtTranslatorBase);
QApplication::removeTranslator(&qtTranslator);
QApplication::removeTranslator(&translatorBase);
QApplication::removeTranslator(&translator);
// Get desired locale (e.g. "de_DE")
// 1) System default language
QString lang_territory = GetLangTerritory();
// Convert to "de" only by truncating "_DE"
QString lang = lang_territory;
lang.truncate(lang_territory.lastIndexOf('_'));
// Load language files for configured locale:
// - First load the translator for the base language, without territory
// - Then load the more specific locale translator
// Load e.g. qt_de.qm
if (qtTranslatorBase.load(
"qt_" + lang,
QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
QApplication::installTranslator(&qtTranslatorBase);
}
// Load e.g. qt_de_DE.qm
if (qtTranslator.load(
"qt_" + lang_territory,
QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
QApplication::installTranslator(&qtTranslator);
}
// Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in
// bitcoin.qrc)
if (translatorBase.load(lang, ":/translations/")) {
QApplication::installTranslator(&translatorBase);
}
// Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in
// bitcoin.qrc)
if (translator.load(lang_territory, ":/translations/")) {
QApplication::installTranslator(&translator);
}
}
/* qDebug() message handler --> debug.log */
void DebugMessageHandler(QtMsgType type, const QMessageLogContext &context,
const QString &msg) {
Q_UNUSED(context);
if (type == QtDebugMsg) {
LogPrint(BCLog::QT, "GUI: %s\n", msg.toStdString());
} else {
LogPrintf("GUI: %s\n", msg.toStdString());
}
}
/**
* Class encapsulating Bitcoin ABC startup and shutdown.
* Allows running startup and shutdown in a different thread from the UI thread.
*/
class BitcoinABC : public QObject {
Q_OBJECT
public:
explicit BitcoinABC(interfaces::Node &node);
public Q_SLOTS:
void initialize(Config *config, RPCServer *rpcServer,
HTTPRPCRequestProcessor *httpRPCRequestProcessor);
void shutdown();
Q_SIGNALS:
void initializeResult(bool success);
void shutdownResult();
void runawayException(const QString &message);
private:
/// Pass fatal exception message to UI thread
void handleRunawayException(const std::exception *e);
interfaces::Node &m_node;
};
/** Main Bitcoin application object */
class BitcoinApplication : public QApplication {
Q_OBJECT
public:
explicit BitcoinApplication(interfaces::Node &node, int &argc, char **argv);
~BitcoinApplication();
#ifdef ENABLE_WALLET
/// Create payment server
void createPaymentServer();
#endif
/// parameter interaction/setup based on rules
void parameterSetup();
/// Create options model
void createOptionsModel(bool resetSettings);
/// Create main window
void createWindow(const Config *, const NetworkStyle *networkStyle);
/// Create splash screen
void createSplashScreen(const NetworkStyle *networkStyle);
/// Request core initialization
void requestInitialize(Config &config, RPCServer &rpcServer,
HTTPRPCRequestProcessor &httpRPCRequestProcessor);
/// Request core shutdown
void requestShutdown(Config &config);
/// Get process return value
int getReturnValue() const { return returnValue; }
/// Get window identifier of QMainWindow (BitcoinGUI)
WId getMainWinId() const;
/// Setup platform style
void setupPlatformStyle();
public Q_SLOTS:
void initializeResult(bool success);
void shutdownResult();
/// Handle runaway exceptions. Shows a message box with the problem and
/// quits the program.
void handleRunawayException(const QString &message);
Q_SIGNALS:
void requestedInitialize(Config *config, RPCServer *rpcServer,
HTTPRPCRequestProcessor *httpRPCRequestProcessor);
void requestedShutdown();
void stopThread();
void splashFinished(QWidget *window);
private:
QThread *coreThread;
interfaces::Node &m_node;
OptionsModel *optionsModel;
ClientModel *clientModel;
BitcoinGUI *window;
QTimer *pollShutdownTimer;
#ifdef ENABLE_WALLET
PaymentServer *paymentServer;
std::vector m_wallet_models;
#endif
int returnValue;
const PlatformStyle *platformStyle;
std::unique_ptr shutdownWindow;
void startThread();
};
#include
BitcoinABC::BitcoinABC(interfaces::Node &node) : QObject(), m_node(node) {}
void BitcoinABC::handleRunawayException(const std::exception *e) {
PrintExceptionContinue(e, "Runaway exception");
Q_EMIT runawayException(QString::fromStdString(m_node.getWarnings("gui")));
}
void BitcoinABC::initialize(Config *config, RPCServer *rpcServer,
HTTPRPCRequestProcessor *httpRPCRequestProcessor) {
try {
qDebug() << __func__ << ": Running initialization in thread";
bool rv =
m_node.appInitMain(*config, *rpcServer, *httpRPCRequestProcessor);
Q_EMIT initializeResult(rv);
} catch (const std::exception &e) {
handleRunawayException(&e);
} catch (...) {
handleRunawayException(nullptr);
}
}
void BitcoinABC::shutdown() {
try {
qDebug() << __func__ << ": Running Shutdown in thread";
m_node.appShutdown();
qDebug() << __func__ << ": Shutdown finished";
Q_EMIT shutdownResult();
} catch (const std::exception &e) {
handleRunawayException(&e);
} catch (...) {
handleRunawayException(nullptr);
}
}
BitcoinApplication::BitcoinApplication(interfaces::Node &node, int &argc,
char **argv)
: QApplication(argc, argv), coreThread(0), m_node(node), optionsModel(0),
clientModel(0), window(0), pollShutdownTimer(0),
#ifdef ENABLE_WALLET
paymentServer(0), m_wallet_models(),
#endif
returnValue(0), platformStyle(0) {
setQuitOnLastWindowClosed(false);
}
void BitcoinApplication::setupPlatformStyle() {
// UI per-platform customization
// This must be done inside the BitcoinApplication constructor, or after it,
// because PlatformStyle::instantiate requires a QApplication.
std::string platformName;
platformName = gArgs.GetArg("-uiplatform", BitcoinGUI::DEFAULT_UIPLATFORM);
platformStyle =
PlatformStyle::instantiate(QString::fromStdString(platformName));
// Fall back to "other" if specified name not found.
if (!platformStyle) {
platformStyle = PlatformStyle::instantiate("other");
}
assert(platformStyle);
}
BitcoinApplication::~BitcoinApplication() {
if (coreThread) {
qDebug() << __func__ << ": Stopping thread";
Q_EMIT stopThread();
coreThread->wait();
qDebug() << __func__ << ": Stopped thread";
}
delete window;
window = 0;
#ifdef ENABLE_WALLET
delete paymentServer;
paymentServer = 0;
#endif
delete optionsModel;
optionsModel = 0;
delete platformStyle;
platformStyle = 0;
}
#ifdef ENABLE_WALLET
void BitcoinApplication::createPaymentServer() {
paymentServer = new PaymentServer(this);
}
#endif
void BitcoinApplication::createOptionsModel(bool resetSettings) {
optionsModel = new OptionsModel(m_node, nullptr, resetSettings);
}
void BitcoinApplication::createWindow(const Config *config,
const NetworkStyle *networkStyle) {
window = new BitcoinGUI(m_node, config, platformStyle, networkStyle, 0);
pollShutdownTimer = new QTimer(window);
connect(pollShutdownTimer, SIGNAL(timeout()), window,
SLOT(detectShutdown()));
}
void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle) {
SplashScreen *splash = new SplashScreen(m_node, 0, networkStyle);
// We don't hold a direct pointer to the splash screen after creation, but
// the splash screen will take care of deleting itself when slotFinish
// happens.
splash->show();
connect(this, SIGNAL(splashFinished(QWidget *)), splash,
SLOT(slotFinish(QWidget *)));
connect(this, SIGNAL(requestedShutdown()), splash, SLOT(close()));
}
void BitcoinApplication::startThread() {
if (coreThread) {
return;
}
coreThread = new QThread(this);
BitcoinABC *executor = new BitcoinABC(m_node);
executor->moveToThread(coreThread);
/* communication to and from thread */
connect(executor, SIGNAL(initializeResult(bool)), this,
SLOT(initializeResult(bool)));
connect(executor, SIGNAL(shutdownResult()), this, SLOT(shutdownResult()));
connect(executor, SIGNAL(runawayException(QString)), this,
SLOT(handleRunawayException(QString)));
// Note on how Qt works: it tries to directly invoke methods if the signal
// is emitted on the same thread that the target object 'lives' on.
// But if the target object 'lives' on another thread (executor here does)
// the SLOT will be invoked asynchronously at a later time in the thread
// of the target object. So.. we pass a pointer around. If you pass
// a reference around (even if it's non-const) you'll get Qt generating
// code to copy-construct the parameter in question (Q_DECLARE_METATYPE
// and qRegisterMetaType generate this code). For the Config class,
// which is noncopyable, we can't do this. So.. we have to pass
// pointers to Config around. Make sure Config &/Config * isn't a
// temporary (eg it lives somewhere aside from the stack) or this will
// crash because initialize() gets executed in another thread at some
// unspecified time (after) requestedInitialize() is emitted!
connect(this,
SIGNAL(requestedInitialize(Config *, RPCServer *,
HTTPRPCRequestProcessor *)),
executor,
SLOT(initialize(Config *, RPCServer *, HTTPRPCRequestProcessor *)));
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::parameterSetup() {
m_node.initLogging();
m_node.initParameterInteraction();
}
void BitcoinApplication::requestInitialize(
Config &config, RPCServer &rpcServer,
HTTPRPCRequestProcessor &httpRPCRequestProcessor) {
qDebug() << __func__ << ": Requesting initialize";
startThread();
// IMPORTANT: config must NOT be a reference to a temporary because below
// signal may be connected to a slot that will be executed as a queued
// connection in another thread!
Q_EMIT requestedInitialize(&config, &rpcServer, &httpRPCRequestProcessor);
}
void BitcoinApplication::requestShutdown(Config &config) {
// Show a simple window indicating shutdown status. Do this first as some of
// the steps may take some time below, for example the RPC console may still
// be executing a command.
shutdownWindow.reset(ShutdownWindow::showShutdownWindow(window));
qDebug() << __func__ << ": Requesting shutdown";
startThread();
window->hide();
window->setClientModel(0);
pollShutdownTimer->stop();
#ifdef ENABLE_WALLET
window->removeAllWallets();
for (WalletModel *walletModel : m_wallet_models) {
delete walletModel;
}
m_wallet_models.clear();
#endif
delete clientModel;
clientModel = 0;
m_node.startShutdown();
// Request shutdown from core thread
Q_EMIT requestedShutdown();
}
void BitcoinApplication::initializeResult(bool success) {
qDebug() << __func__ << ": Initialization result: " << success;
returnValue = success ? EXIT_SUCCESS : EXIT_FAILURE;
if (!success) {
// Make sure splash screen doesn't stick around during shutdown.
Q_EMIT splashFinished(window);
// Exit first main loop invocation.
quit();
return;
}
// Log this only after AppInitMain finishes, as then logging setup is
// guaranteed complete.
qWarning() << "Platform customization:" << platformStyle->getName();
#ifdef ENABLE_WALLET
PaymentServer::LoadRootCAs();
paymentServer->setOptionsModel(optionsModel);
#endif
clientModel = new ClientModel(m_node, optionsModel);
window->setClientModel(clientModel);
#ifdef ENABLE_WALLET
bool fFirstWallet = true;
auto wallets = m_node.getWallets();
for (auto &wallet : wallets) {
WalletModel *const walletModel = new WalletModel(
std::move(wallet), m_node, platformStyle, optionsModel);
window->addWallet(walletModel);
if (fFirstWallet) {
window->setCurrentWallet(walletModel->getWalletName());
fFirstWallet = false;
}
connect(
walletModel,
SIGNAL(coinsSent(WalletModel *, SendCoinsRecipient, QByteArray)),
paymentServer,
SLOT(fetchPaymentACK(WalletModel *, const SendCoinsRecipient &,
QByteArray)));
m_wallet_models.push_back(walletModel);
}
#endif
// If -min option passed, start window minimized.
if (gArgs.GetBoolArg("-min", false)) {
window->showMinimized();
} else {
window->show();
}
Q_EMIT splashFinished(window);
#ifdef ENABLE_WALLET
// Now that initialization/startup is done, process any command-line
// bitcoincash: 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
pollShutdownTimer->start(200);
}
void BitcoinApplication::shutdownResult() {
// Exit second main loop invocation after shutdown finished.
quit();
}
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(EXIT_FAILURE);
}
WId BitcoinApplication::getMainWinId() const {
if (!window) {
return 0;
}
return window->winId();
}
static void SetupUIArgs() {
#ifdef ENABLE_WALLET
gArgs.AddArg("-allowselfsignedrootcertificates",
strprintf("Allow self signed root certificates (default: %d)",
DEFAULT_SELFSIGNED_ROOTCERTS),
true, OptionsCategory::GUI);
#endif
gArgs.AddArg(
"-choosedatadir",
strprintf(QObject::tr("Choose data directory on startup (default: %d)")
.toStdString(),
DEFAULT_CHOOSE_DATADIR),
false, OptionsCategory::GUI);
gArgs.AddArg(
"-lang=",
QObject::tr(
"Set language, for example \"de_DE\" (default: system locale)")
.toStdString(),
false, OptionsCategory::GUI);
gArgs.AddArg("-min", QObject::tr("Start minimized").toStdString(), false,
OptionsCategory::GUI);
gArgs.AddArg(
"-rootcertificates=",
QObject::tr(
"Set SSL root certificates for payment request (default: -system-)")
.toStdString(),
false, OptionsCategory::GUI);
gArgs.AddArg(
"-splash",
strprintf(QObject::tr("Show splash screen on startup (default: %d)")
.toStdString(),
DEFAULT_SPLASHSCREEN),
false, OptionsCategory::GUI);
gArgs.AddArg(
"-resetguisettings",
QObject::tr("Reset all settings changed in the GUI").toStdString(),
false, OptionsCategory::GUI);
gArgs.AddArg("-uiplatform",
strprintf("Select platform to customize UI for (one of "
"windows, macosx, other; default: %s)",
BitcoinGUI::DEFAULT_UIPLATFORM),
true, OptionsCategory::GUI);
}
#ifndef BITCOIN_QT_TEST
static void MigrateSettings() {
assert(!QApplication::applicationName().isEmpty());
static const QString legacyAppName("Bitcoin-Qt"),
#ifdef Q_OS_DARWIN
// Macs and/or iOS et al use a domain-style name for Settings
// files. All other platforms use a simple orgname. This
// difference is documented in the QSettings class documentation.
legacyOrg("bitcoin.org");
#else
legacyOrg("Bitcoin");
#endif
QSettings
// below picks up settings file location based on orgname,appname
legacy(legacyOrg, legacyAppName),
// default c'tor below picks up settings file location based on
// QApplication::applicationName(), et al -- which was already set
// in main()
abc;
#ifdef Q_OS_DARWIN
// Disable bogus OSX keys from MacOS system-wide prefs that may cloud our
// judgement ;) (this behavior is also documented in QSettings docs)
legacy.setFallbacksEnabled(false);
abc.setFallbacksEnabled(false);
#endif
const QStringList legacyKeys(legacy.allKeys());
// We only migrate settings if we have Core settings but no Bitcoin-ABC
// settings
if (!legacyKeys.isEmpty() && abc.allKeys().isEmpty()) {
for (const QString &key : legacyKeys) {
// now, copy settings over
abc.setValue(key, legacy.value(key));
}
}
}
int main(int argc, char *argv[]) {
SetupEnvironment();
std::unique_ptr node = interfaces::MakeNode();
// Do not refer to data directory yet, this can be overridden by
// Intro::pickDataDirectory
/// 1. Basic Qt initialization (not dependent on parameters or
/// configuration)
Q_INIT_RESOURCE(bitcoin);
Q_INIT_RESOURCE(bitcoin_locale);
BitcoinApplication app(*node, argc, argv);
#if QT_VERSION > 0x050100
// Generate high-dpi pixmaps
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
#if QT_VERSION >= 0x050600
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
#ifdef Q_OS_MAC
QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
#endif
// Register meta types used for QMetaObject::invokeMethod
qRegisterMetaType();
// Need to pass name here as Amount is a typedef (see
// http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType)
// IMPORTANT if it is no longer a typedef use the normal variant above
qRegisterMetaType("Amount");
qRegisterMetaType>("std::function");
// Need to register any types Qt doesn't know about if you intend
// to use them with the signal/slot mechanism Qt provides. Even pointers.
// Note that class Config is noncopyable and so we can't register a
// non-pointer version of it with Qt, because Qt expects to be able to
// copy-construct non-pointers to objects for invoking slots
// behind-the-scenes in the 'Queued' connection case.
qRegisterMetaType();
/// 2. Parse command-line options. We do this after qt in order to show an
/// error if there are problems parsing these
// Command-line options take precedence:
node->setupServerArgs();
SetupUIArgs();
std::string error;
if (!node->parseParameters(argc, argv, error)) {
QMessageBox::critical(
0, QObject::tr(PACKAGE_NAME),
QObject::tr("Error parsing command line arguments: %1.")
.arg(QString::fromStdString(error)));
return EXIT_FAILURE;
}
// Now that the QApplication is setup and we have parsed our parameters, we
// can set the platform style
app.setupPlatformStyle();
/// 3. Application identification
// must be set before OptionsModel is initialized or translations are
// loaded, as it is used to locate QSettings.
// Note: If you move these calls somewhere else, be sure to bring
// MigrateSettings() below along for the ride.
QApplication::setOrganizationName(QAPP_ORG_NAME);
QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN);
QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT);
// Migrate settings from core's/our old GUI settings to Bitcoin ABC
// only if core's exist but Bitcoin ABC's doesn't.
// NOTE -- this function needs to be called *after* the above 3 lines
// that set the app orgname and app name! If you move the above 3 lines
// to elsewhere, take this call with you!
MigrateSettings();
- GUIUtil::SubstituteFonts(GetLangTerritory());
/// 4. Initialization of translations, so that intro dialog is in user's
/// language. Now that QSettings are accessible, initialize translations.
QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
initTranslations(qtTranslatorBase, qtTranslator, translatorBase,
translator);
translationInterface.Translate.connect(Translate);
// Show help message immediately after parsing command-line options (for
// "-lang") and setting locale, but before showing splash screen.
if (HelpRequested(gArgs) || gArgs.IsArgSet("-version")) {
HelpMessageDialog help(*node, nullptr, gArgs.IsArgSet("-version"));
help.showOrPrint();
return EXIT_SUCCESS;
}
/// 5. Now that settings and translations are available, ask user for data
/// directory. User language is set up: pick a data directory.
if (!Intro::pickDataDirectory(*node)) {
return EXIT_SUCCESS;
}
/// 6. Determine availability of data and blocks directory and parse
/// bitcoin.conf
/// - Do not call GetDataDir(true) before this step finishes.
if (!fs::is_directory(GetDataDir(false))) {
QMessageBox::critical(
0, QObject::tr(PACKAGE_NAME),
QObject::tr(
"Error: Specified data directory \"%1\" does not exist.")
.arg(QString::fromStdString(gArgs.GetArg("-datadir", ""))));
return EXIT_FAILURE;
}
if (!node->readConfigFiles(error)) {
QMessageBox::critical(
0, QObject::tr(PACKAGE_NAME),
QObject::tr("Error: Cannot parse configuration file: %1.")
.arg(QString::fromStdString(error)));
return EXIT_FAILURE;
}
/// 7. Determine network (and switch to network specific options)
// - Do not call Params() before this step.
// - Do this after parsing the configuration file, as the network can be
// switched there.
// - QSettings() will use the new application name after this, resulting in
// network-specific settings.
// - Needs to be done before createOptionsModel.
// Check for -testnet or -regtest parameter (Params() calls are only valid
// after this clause)
try {
node->selectParams(gArgs.GetChainName());
} catch (std::exception &e) {
QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
QObject::tr("Error: %1").arg(e.what()));
return EXIT_FAILURE;
}
#ifdef ENABLE_WALLET
// Parse URIs on command line -- this can affect Params()
PaymentServer::ipcParseCommandLine(*node, argc, argv);
#endif
QScopedPointer networkStyle(NetworkStyle::instantiate(
QString::fromStdString(Params().NetworkIDString())));
assert(!networkStyle.isNull());
// Allow for separate UI settings for testnets
QApplication::setApplicationName(networkStyle->getAppName());
// Re-initialize translations after changing application name (language in
// network-specific settings can be different)
initTranslations(qtTranslatorBase, qtTranslator, translatorBase,
translator);
#ifdef ENABLE_WALLET
/// 8. 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
// of the server.
// - Do this after creating app and setting up translations, so errors are
// translated properly.
if (PaymentServer::ipcSendCommandLine()) {
exit(EXIT_SUCCESS);
}
// Start up the payment server early, too, so impatient users that click on
// bitcoincash: links repeatedly have their payment requests routed to this
// process:
app.createPaymentServer();
#endif
/// 9. Main GUI initialization
// Install global event filter that makes sure that long tooltips can be
// word-wrapped.
app.installEventFilter(
new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
#if defined(Q_OS_WIN)
// Install global event filter for processing Windows session related
// Windows messages (WM_QUERYENDSESSION and WM_ENDSESSION)
qApp->installNativeEventFilter(new WinShutdownMonitor());
#endif
// Install qDebug() message handler to route to debug.log
qInstallMessageHandler(DebugMessageHandler);
// Allow parameter interaction before we create the options model
app.parameterSetup();
// Load GUI settings from QSettings
app.createOptionsModel(gArgs.GetBoolArg("-resetguisettings", false));
// Subscribe to global signals from core
std::unique_ptr handler =
node->handleInitMessage(InitMessage);
// Get global config
Config &config = const_cast(GetConfig());
if (gArgs.GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) &&
!gArgs.GetBoolArg("-min", false)) {
app.createSplashScreen(networkStyle.data());
}
RPCServer rpcServer;
HTTPRPCRequestProcessor httpRPCRequestProcessor(config, rpcServer);
try {
app.createWindow(&config, networkStyle.data());
// Perform base initialization before spinning up
// initialization/shutdown thread. This is acceptable because this
// function only contains steps that are quick to execute, so the GUI
// thread won't be held up.
if (!node->baseInitialize(config)) {
// A dialog with detailed error will have been shown by InitError()
return EXIT_FAILURE;
}
app.requestInitialize(config, rpcServer, httpRPCRequestProcessor);
#if defined(Q_OS_WIN)
WinShutdownMonitor::registerShutdownBlockReason(
QObject::tr("%1 didn't yet exit safely...")
.arg(QObject::tr(PACKAGE_NAME)),
(HWND)app.getMainWinId());
#endif
app.exec();
app.requestShutdown(config);
app.exec();
return app.getReturnValue();
} catch (const std::exception &e) {
PrintExceptionContinue(&e, "Runaway exception");
app.handleRunawayException(
QString::fromStdString(node->getWarnings("gui")));
} catch (...) {
PrintExceptionContinue(nullptr, "Runaway exception");
app.handleRunawayException(
QString::fromStdString(node->getWarnings("gui")));
}
return EXIT_FAILURE;
}
#endif // BITCOIN_QT_TEST
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 45f707e8f..850e3f206 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -1,1001 +1,951 @@
// Copyright (c) 2011-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include