diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index a1821cafe3..c407ab95f6 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -105,6 +105,7 @@ QT_QRC_LOCALE_CPP = qt/qrc_bitcoin_locale.cpp QT_QRC_LOCALE = qt/bitcoin_locale.qrc BITCOIN_QT_H = \ + qml/bitcoin.h \ qt/addressbookpage.h \ qt/addresstablemodel.h \ qt/askpassphrasedialog.h \ @@ -276,6 +277,13 @@ BITCOIN_QT_WALLET_CPP = \ qt/walletmodeltransaction.cpp \ qt/walletview.cpp +BITCOIN_QML_BASE_CPP = \ + qml/bitcoin.cpp + +QML_QRC_CPP = qml/qrc_bitcoin.cpp +QML_QRC = qml/bitcoin_qml.qrc +RES_QML = $(wildcard $(srcdir)/qml/pages/*.qml) + BITCOIN_QT_CPP = $(BITCOIN_QT_BASE_CPP) if TARGET_WINDOWS BITCOIN_QT_CPP += $(BITCOIN_QT_WINDOWS_CPP) @@ -303,6 +311,11 @@ endif nodist_qt_libbitcoinqt_a_SOURCES = $(QT_MOC_CPP) $(QT_MOC) $(QT_QRC_CPP) $(QT_QRC_LOCALE_CPP) +if BUILD_WITH_QML + qt_libbitcoinqt_a_SOURCES += $(BITCOIN_QML_BASE_CPP) $(QML_QRC) $(RES_QML) + nodist_qt_libbitcoinqt_a_SOURCES += $(QML_QRC_CPP) +endif # BUILD_WITH_QML + # forms/foo.h -> forms/ui_foo.h QT_FORMS_H=$(join $(dir $(QT_FORMS_UI)),$(addprefix ui_, $(notdir $(QT_FORMS_UI:.ui=.h)))) @@ -372,6 +385,12 @@ $(QT_QRC_CPP): $(QT_QRC) $(QT_FORMS_H) $(RES_FONTS) $(RES_ICONS) $(RES_ANIMATION @test -f $(RCC) $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) -name bitcoin --format-version 1 $< > $@ +if BUILD_WITH_QML +$(QML_QRC_CPP): $(QML_QRC) $(RES_QML) + @test -f $(RCC) + $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) --name bitcoin_qml --format-version 1 $< > $@ +endif # BUILD_WITH_QML + CLEAN_QT = $(nodist_qt_libbitcoinqt_a_SOURCES) $(QT_QM) $(QT_FORMS_H) qt/*.gcda qt/*.gcno qt/temp_bitcoin_locale.qrc CLEANFILES += $(CLEAN_QT) diff --git a/src/qml/bitcoin.cpp b/src/qml/bitcoin.cpp new file mode 100644 index 0000000000..099073a103 --- /dev/null +++ b/src/qml/bitcoin.cpp @@ -0,0 +1,65 @@ +// Copyright (c) 2021 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 +#include + +namespace { +void SetupUIArgs(ArgsManager& argsman) +{ + argsman.AddArg("-lang=", "Set language, for example \"de_DE\" (default: system locale)", ArgsManager::ALLOW_ANY, OptionsCategory::GUI); + argsman.AddArg("-min", "Start minimized", ArgsManager::ALLOW_ANY, OptionsCategory::GUI); + argsman.AddArg("-resetguisettings", "Reset all settings changed in the GUI", ArgsManager::ALLOW_ANY, OptionsCategory::GUI); + argsman.AddArg("-splash", strprintf("Show splash screen on startup (default: %u)", DEFAULT_SPLASHSCREEN), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); +} +} // namespace + + +int QmlGuiMain(int argc, char* argv[]) +{ + NodeContext node_context; + std::unique_ptr node = interfaces::MakeNode(&node_context); + + // Subscribe to global signals from core + boost::signals2::scoped_connection handler_message_box = ::uiInterface.ThreadSafeMessageBox_connect(noui_ThreadSafeMessageBox); + boost::signals2::scoped_connection handler_question = ::uiInterface.ThreadSafeQuestion_connect(noui_ThreadSafeQuestion); + boost::signals2::scoped_connection handler_init_message = ::uiInterface.InitMessage_connect(noui_InitMessage); + + Q_INIT_RESOURCE(bitcoin_qml); + + QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QGuiApplication app(argc, argv); + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:///qml/pages/stub.qml"))); + if (engine.rootObjects().isEmpty()) { + return EXIT_FAILURE; + } + + // Parse command-line options. We do this after qt in order to show an error if there are problems parsing these. + SetupServerArgs(gArgs); + SetupUIArgs(gArgs); + std::string error; + if (!gArgs.ParseParameters(argc, argv, error)) { + InitError(strprintf(Untranslated("Error parsing command line arguments: %s\n"), error)); + return EXIT_FAILURE; + } + + return app.exec(); +} diff --git a/src/qml/bitcoin.h b/src/qml/bitcoin.h new file mode 100644 index 0000000000..77e7102e6d --- /dev/null +++ b/src/qml/bitcoin.h @@ -0,0 +1,10 @@ +// Copyright (c) 2021 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_QML_BITCOIN_H +#define BITCOIN_QML_BITCOIN_H + +int QmlGuiMain(int argc, char* argv[]); + +#endif // BITCOIN_QML_BITCOIN_H diff --git a/src/qml/bitcoin_qml.qrc b/src/qml/bitcoin_qml.qrc new file mode 100644 index 0000000000..66ad312f8f --- /dev/null +++ b/src/qml/bitcoin_qml.qrc @@ -0,0 +1,5 @@ + + + pages/stub.qml + + diff --git a/src/qml/pages/stub.qml b/src/qml/pages/stub.qml new file mode 100644 index 0000000000..b535b249cc --- /dev/null +++ b/src/qml/pages/stub.qml @@ -0,0 +1,9 @@ +import QtQuick.Controls 2.12 + +ApplicationWindow { + id: appWindow + title: "Bitcoin Core TnG" + minimumWidth: 750 + minimumHeight: 450 + visible: true +} diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 442c813a5a..a2a5bbfffc 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -454,13 +454,6 @@ static void SetupUIArgs(ArgsManager& argsman) int GuiMain(int argc, char* argv[]) { -#ifdef WIN32 - util::WinCmdLineArgs winArgs; - std::tie(argc, argv) = winArgs.get(); -#endif - SetupEnvironment(); - util::ThreadSetInternalName("main"); - NodeContext node_context; std::unique_ptr node = interfaces::MakeNode(&node_context); diff --git a/src/qt/main.cpp b/src/qt/main.cpp index 6e772d58c5..b4c1a1fc7e 100644 --- a/src/qt/main.cpp +++ b/src/qt/main.cpp @@ -2,8 +2,18 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifdef HAVE_CONFIG_H +#include +#endif + +#if USE_QML +#include +#else #include +#endif // USE_QML +#include +#include #include #include @@ -11,6 +21,7 @@ #include #include +#include /** Translate string to current locale using Qt. */ extern const std::function G_TRANSLATION_FUN = [](const char* psz) { @@ -18,4 +29,19 @@ extern const std::function G_TRANSLATION_FUN = [](cons }; UrlDecodeFn* const URL_DECODE = urlDecode; -int main(int argc, char* argv[]) { return GuiMain(argc, argv); } +int main(int argc, char* argv[]) +{ +#ifdef WIN32 + util::WinCmdLineArgs win_args; + std::tie(argc, argv) = win_args.get(); +#endif // WIN32 + + SetupEnvironment(); + util::ThreadSetInternalName("main"); + +#if USE_QML + return QmlGuiMain(argc, argv); +#else + return GuiMain(argc, argv); +#endif // USE_QML +}