diff --git a/.github/gui-testnet.yml b/.github/gui-testnet.yml deleted file mode 100644 index e3e7b75af..000000000 --- a/.github/gui-testnet.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: "gui-testnet" -on: - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - push: - paths-ignore: - - '**.md' - pull_request: - paths-ignore: - - '**.md' - -env: - CCACHE_SETTINGS: | - ccache --max-size=150M - ccache --set-config=compression=true - -jobs: - macos-amd64: - runs-on: macos-latest - env: - CCACHE_TEMPDIR: /tmp/.ccache-temp - steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.9.1 - with: - access_token: ${{ github.token }} - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - submodules: recursive - - uses: actions/cache@v2 - with: - path: /Users/runner/Library/Caches/ccache - key: ccache-${{ runner.os }}-build-${{ github.sha }} - restore-keys: ccache-${{ runner.os }}-build- - - name: install dependencies - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install openssl boost icu4c ccache miniupnpc qt@5 - - name: build GUI - env: - PKG_CONFIG_PATH: "/usr/local/opt/openssl@3/lib/pkgconfig" - OPENSSL_ROOT_DIR: "/usr/local/opt/openssl@3" - ZANO_QT_PATH: "/usr/local/opt/qt@5" - ZANO_BOOST_ROOT: "/opt/homebrew/opt/boost" - ZANO_BOOST_LIBS_PATH: "/opt/homebrew/opt/boost/lib" - CMAKE_OSX_SYSROOT: "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk" - run: | - ${{env.CCACHE_SETTINGS}} - export LIBRARY_PATH=${LIBRARY_PATH}:/usr/local/opt/icu4c/lib - ./utils/build/testnet_mac_osx_gui.sh - - name: Tar files - run: cd build/release/src/gui && tar -cvf ../../../../testnet-desktop-macos-amd64.tar Lethean.app - - uses: actions/upload-artifact@v3 - with: - name: testnet-desktop-macos-amd64 - if-no-files-found: error - path: testnet-desktop-macos-amd64.tar diff --git a/.github/workflows/cli-testnet.yml b/.github/workflows/cli-testnet.yml index c3568cf38..a88a05f07 100644 --- a/.github/workflows/cli-testnet.yml +++ b/.github/workflows/cli-testnet.yml @@ -35,7 +35,7 @@ jobs: key: ccache-${{ runner.os }}-build-testnet-cli-${{ github.sha }} restore-keys: ccache-${{ runner.os }}-build-testnet-cli- - name: update apt - run: sudo apt update & sudo apt-get upgrade -y + run: sudo apt update - name: install dependencies run: sudo apt-get install -y python-dev autotools-dev libboost-all-dev libicu-dev libbz2-dev git screen checkinstall zlib1g-dev ccache miniupnpc - name: build server diff --git a/.github/workflows/gui-testnet.yml b/.github/workflows/gui-testnet.yml new file mode 100644 index 000000000..fc5d79e59 --- /dev/null +++ b/.github/workflows/gui-testnet.yml @@ -0,0 +1,164 @@ +name: "gui-testnet" +on: + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + push: + paths-ignore: + - '**.md' + pull_request: + paths-ignore: + - '**.md' + +env: + CCACHE_SETTINGS: | + ccache --max-size=150M + ccache --set-config=compression=true + +jobs: + linux-amd64: + runs-on: ubuntu-20.04 + env: + CCACHE_TEMPDIR: /tmp/.ccache-temp + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.9.1 + with: + access_token: ${{ github.token }} + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + submodules: recursive + - uses: actions/cache@v3 + with: + path: ~/.ccache + key: ccache-${{ runner.os }}-build-testnet-gui + restore-keys: ccache-${{ runner.os }}-build-testnet-gui + - name: update apt + run: sudo apt update + - name: install dependencies + run: sudo apt-get install -y qt5-default qtwebengine5-dev libqt5websockets5-dev python-dev autotools-dev libboost-all-dev libicu-dev libbz2-dev git screen checkinstall zlib1g-dev ccache miniupnpc + - name: build server + env: + QT_PREFIX_PATH: /usr/lib/qt5 + run: | + ${{env.CCACHE_SETTINGS}} + ./utils/build/testnet_linux_gui.sh + - uses: actions/upload-artifact@v3 + with: + name: lethean-gui-bundle-linux-testnet-x86_64 + if-no-files-found: error + path: lethean-gui-bundle-linux-testnet-x86_64.tar.bz2 + - name: Release + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') + with: + files: ${{ github.workspace }}/lethean-gui-bundle-linux-testnet-x86_64.tar.bz2 + macos-amd64: + runs-on: macos-latest + env: + CCACHE_TEMPDIR: /tmp/.ccache-temp + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.9.1 + with: + access_token: ${{ github.token }} + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + submodules: recursive + - uses: actions/cache@v3 + with: + path: /Users/runner/Library/Caches/ccache + key: ccache-${{ runner.os }}-build-testnet-gui + restore-keys: ccache-${{ runner.os }}-build-testnet-gui + - name: install dependencies + run: HOMEBREW_NO_AUTO_UPDATE=1 brew install openssl boost icu4c ccache miniupnpc qt@5 + - name: build server + env: + PKG_CONFIG_PATH: "/usr/local/opt/openssl@3/lib/pkgconfig" + OPENSSL_ROOT_DIR: "/usr/local/opt/openssl@3" + ZANO_BOOST_ROOT: "/usr/local/opt/boost" + ZANO_BOOST_LIBS_PATH: "/usr/local/opt/boost/lib" + ZANO_QT_PATH: "/usr/local/opt/qt@5" + CMAKE_OSX_SYSROOT: "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk" + run: | + ${{env.CCACHE_SETTINGS}} + export LIBRARY_PATH=${LIBRARY_PATH}:/usr/local/opt/icu4c/lib + ./utils/build/testnet_mac_osx_gui.sh + - uses: actions/upload-artifact@v3 + with: + name: lethean-gui-bundle-macos-testnet-i386 + if-no-files-found: error + path: lethean-gui-bundle-macos-testnet-i386.tar.bz2 + - name: Release + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') + with: + files: ${{ github.workspace }}/lethean-gui-bundle-macos-testnet-i386.tar.bz2 + windows-amd64: + runs-on: windows-latest + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.9.1 + with: + access_token: ${{ github.token }} + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + submodules: recursive + - uses: actions/cache@v3 + with: + path: ~\.ccache + key: ccache-${{ runner.os }}-build-testnet-cli + restore-keys: ccache-${{ runner.os }}-build-testnet-cli + - name: Eat the Choco + run: | + choco install openssl --version 1.1.1.1500 -y + choco install ccache -y + choco install zip -y + - name: Install Qt + uses: jurplel/install-qt-action@v3 + with: + version: '5.15.2' + host: 'windows' + target: 'desktop' + arch: 'win64_msvc2019_64' + dir: '${{ github.workspace }}/example/' + modules: 'qtcharts qtwebengine' + - name: install msvc toolset + uses: ilammy/msvc-dev-cmd@v1 + - name: Install boost + uses: MarkusJx/install-boost@v2.4.1 + id: install-boost + with: + # REQUIRED: Specify the required boost version + # A list of supported versions can be found here: + # https://github.com/MarkusJx/prebuilt-boost/blob/main/versions-manifest.json + boost_version: 1.80.0 + platform_version: 2022 + toolset: msvc + link: static + - name: Set up Visual Studio shell + uses: egor-tensin/vs-shell@v2 + with: + arch: x64 + - name: build server + env: + QT_PREFIX_PATH: ${{ github.workspace }}/example/Qt/5.15.2/win64_msvc2019_64 + BOOST_ROOT: ${{ steps.install-boost.outputs.BOOST_ROOT }} + LOCAL_BOOST_PATH: ${{ steps.install-boost.outputs.BOOST_ROOT }} + OPENSSL_ROOT_DIR: "C:\\Program Files\\OpenSSL-Win64" + run: | + refreshenv + ${{env.CCACHE_SETTINGS}} + .\utils\build\testnet_windows_gui.bat + - uses: actions/upload-artifact@v3 + with: + name: lethean-gui-bundle-win-testnet-x64 + if-no-files-found: error + path: ${{ github.workspace }}\lethean-gui-bundle-win-testnet-x64.zip + - name: Release + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') + with: + files: ${{ github.workspace }}\lethean-gui-bundle-win-testnet-x64.zip diff --git a/.gitmodules b/.gitmodules index bc13a0d33..c5495c2c3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,10 +1,6 @@ [submodule "contrib/miniupnp"] path = contrib/miniupnp url = https://github.com/miniupnp/miniupnp -[submodule "src/gui/qt-daemon/layout"] - path = src/gui/qt-daemon/layout - url = https://github.com/letheanVPN/iTw3_ui.git - branch = main [submodule "contrib/tor-connect"] path = contrib/tor-connect url = https://github.com/letheanVPN/tor-connect.git diff --git a/.idea/cmake.xml b/.idea/cmake.xml index e9a23f41c..bb2d9a142 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -2,8 +2,8 @@ - - + + diff --git a/.idea/runConfigurations/daemon.xml b/.idea/runConfigurations/daemon.xml index 7e66deb56..ef91459ef 100644 --- a/.idea/runConfigurations/daemon.xml +++ b/.idea/runConfigurations/daemon.xml @@ -1,7 +1,7 @@ - + - \ No newline at end of file + diff --git a/.idea/runConfigurations/simplewallet.xml b/.idea/runConfigurations/simplewallet.xml index 62947b9d2..fd3cc171a 100644 --- a/.idea/runConfigurations/simplewallet.xml +++ b/.idea/runConfigurations/simplewallet.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/wallet.xml b/.idea/runConfigurations/wallet.xml index 81a5160f1..074532787 100644 --- a/.idea/runConfigurations/wallet.xml +++ b/.idea/runConfigurations/wallet.xml @@ -1,7 +1,7 @@ - + - \ No newline at end of file + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f52276061..a69a237cd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -69,14 +69,11 @@ file(GLOB_RECURSE WALLET wallet/*) file(GLOB_RECURSE MINER miner/*) if(BUILD_GUI) - if(MSVC) - file(GLOB_RECURSE QTDAEMON gui/qt-daemon/*.cpp gui/qt-daemon/*.h gui/qt-daemon/app.rc) - elseif(APPLE) - file(GLOB_RECURSE QTDAEMON gui/qt-daemon/*.cpp gui/qt-daemon/*.h gui/qt-daemon/*.mm) + if(APPLE) + file(GLOB_RECURSE QTSERVER gui/*.cpp gui/*.h gui/*.mm) else() - file(GLOB_RECURSE QTDAEMON gui/qt-daemon/*.cpp gui/qt-daemon/*.h) + file(GLOB_RECURSE QTSERVER gui/*.cpp gui/*.h) endif() - list(FILTER QTDAEMON EXCLUDE REGEX "node_modules") endif() @@ -94,7 +91,7 @@ source_group(connectivity-tool FILES ${CONN_TOOL}) source_group(wallet FILES ${WALLET}) if(BUILD_GUI) - source_group(qtdaemon FILES ${QTDAEMON}) + source_group(qtserver FILES ${QTSERVER}) endif() @@ -183,23 +180,27 @@ set_property(TARGET common crypto currency_core rpc stratum wallet PROPERTY FOLD set_property(TARGET daemon simplewallet connectivity_tool PROPERTY FOLDER "prog") set_property(TARGET daemon PROPERTY OUTPUT_NAME "letheand") + if(BUILD_GUI) if(APPLE) FIND_LIBRARY(COCOA_LIBRARY Cocoa) endif() + set(AUTORCC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) - SET(MACOSX_BUNDLE_ICON_FILE app.icns) - add_executable(Lethean WIN32 MACOSX_BUNDLE ${QTDAEMON} ) - ENABLE_SHARED_PCH(Lethean QTDAEMON) +# SET(MACOSX_BUNDLE_ICON_FILE app.icns) + qt5_add_resources (RCC_SOURCES gui/resources/files.qrc) + add_executable(Lethean WIN32 MACOSX_BUNDLE ${QTSERVER} ${RCC_SOURCES} ) + ENABLE_SHARED_PCH(Lethean QTSERVER) ENABLE_SHARED_PCH_EXECUTABLE(Lethean) + set_property(TARGET Lethean PROPERTY OUTPUT_NAME "lethean-gui-server") - QT5_USE_MODULES(Lethean WebEngineWidgets WebChannel) + QT5_USE_MODULES(Lethean WebEngineWidgets WebChannel WebSockets) find_package(Qt5PrintSupport REQUIRED) - target_link_libraries(Lethean wallet rpc currency_core crypto common zlibstatic ethash Qt5::WebEngineWidgets Qt5::PrintSupport ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) + target_link_libraries(Lethean wallet rpc currency_core crypto common zlibstatic ethash Qt5::WebSockets Qt5::WebEngineWidgets Qt5::PrintSupport ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) if (UNIX AND NOT APPLE) target_link_libraries(Lethean rt) endif() @@ -213,33 +214,7 @@ if(BUILD_GUI) endif() set_property(TARGET Lethean PROPERTY FOLDER "prog") - set_target_properties(Lethean PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/gui/qt-daemon/Info.plist.in) - - set(HTML_DIR ${CMAKE_CURRENT_SOURCE_DIR}/gui/qt-daemon/layout/html) - set_target_properties(Lethean PROPERTIES VS_DEBUGGER_COMMAND_ARGUMENTS "--html-path=${HTML_DIR}") set(CMAKE_AUTOMOC OFF) - # GUI convenience "bundle" - # set(GUI_DIR ${CMAKE_CURRENT_BINARY_DIR}/gui) - # set_target_properties(Lethean PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${GUI_DIR}) - # add_custom_command(TARGET Lethean POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${HTML_DIR} ${GUI_DIR}/html) -endif() - -if(APPLE) - set(SIMPLE_BUNDLE 1) -endif() - -if(SIMPLE_BUNDLE) - set(INSTALL_DIR "${CMAKE_BINARY_DIR}/hp-${VERSION}") - install(TARGETS daemon simplewallet connectivity_tool - RUNTIME DESTINATION "${INSTALL_DIR}" COMPONENT Runtime - ) - - install(FILES ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} DESTINATION "${INSTALL_DIR}/lib") - - if(APPLE) - set(FIXUP_COMMAND ${CMAKE_SOURCE_DIR}/utils/macosx_fixup.sh " " ${INSTALL_DIR}) - install(CODE "execute_process(COMMAND ${FIXUP_COMMAND})") - endif() endif() diff --git a/src/gui/qt-daemon/application/gui_utils.cpp b/src/gui/gui_utils.cpp similarity index 100% rename from src/gui/qt-daemon/application/gui_utils.cpp rename to src/gui/gui_utils.cpp diff --git a/src/gui/qt-daemon/application/gui_utils.h b/src/gui/gui_utils.h similarity index 100% rename from src/gui/qt-daemon/application/gui_utils.h rename to src/gui/gui_utils.h diff --git a/src/gui/main.cpp b/src/gui/main.cpp new file mode 100644 index 000000000..f00644edb --- /dev/null +++ b/src/gui/main.cpp @@ -0,0 +1,49 @@ +#include "websocketclientwrapper.h" +#include "websockettransport.h" +#include "mainwindow.h" +#include "include_base_utils.h" + +#include +#include +#include +#include +#ifdef Q_OS_DARWIN +# include "urleventfilter.h" +#endif +int main(int argc, char** argv) +{ +// epee::log_space::get_set_log_detalisation_level(true, LOG_LEVEL_0); +// epee::log_space::get_set_need_thread_id(true, true); +// epee::log_space::log_singletone::enable_channels("core,currency_protocol,tx_pool,p2p,wallet"); + + QApplication app(argc, argv, Qt::SubWindow); + + // setup the QWebSocketServer + QWebSocketServer webSocketServer(QStringLiteral("Lethean GUI Backend Server"), QWebSocketServer::NonSecureMode); + if(!webSocketServer.listen(QHostAddress::LocalHost, 12345)) { + qWarning() << "Failed to open web socket server." << webSocketServer.errorString(); + return 1; + } + WebSocketClientWrapper clientWrapper(&webSocketServer); + + // setup the channel + QWebChannel channel; + QObject::connect(&clientWrapper, &WebSocketClientWrapper::clientConnected, + &channel, &QWebChannel::connectTo); + MainWindow viewer; + + // register QObjects to be exposed to JavaScript + if(!viewer.init_backend(argc, argv)) { + return 1; + } + + channel.registerObject(QStringLiteral("mediator_object"), &viewer); + +#ifdef Q_OS_DARWIN + URLEventFilter url_event_filter(&viewer); + app.installEventFilter(&url_event_filter); +#endif + app.installNativeEventFilter(&viewer); + + return app.exec(); +} diff --git a/src/gui/qt-daemon/application/mainwindow.cpp b/src/gui/mainwindow.cpp similarity index 80% rename from src/gui/qt-daemon/application/mainwindow.cpp rename to src/gui/mainwindow.cpp index c3f0f82a2..35ea25e73 100644 --- a/src/gui/qt-daemon/application/mainwindow.cpp +++ b/src/gui/mainwindow.cpp @@ -6,8 +6,7 @@ #include #include -#include -#include +#include #include "string_coding.h" #include "gui_utils.h" @@ -39,7 +38,7 @@ QString make_response_dbg(const T& r, const std::string& location) return str.c_str(); } -#define PREPARE_RESPONSE(rsp_type, var_name) view::api_response_t var_name = AUTO_VAL_INIT(var_name) +#define PREPARE_RESPONSE(rsp_type, var_name) view::api_response_t var_name = AUTO_VAL_INIT(var_name) #define MAKE_RESPONSE(r) (r.error_code == API_RETURN_CODE_OK || r.error_code == API_RETURN_CODE_TRUE) ? make_response(r) : make_response_dbg(r, LOCATION_STR) #define LOG_API_TIMING() const char* pfunc_call_name = LOCAL_FUNCTION_DEF__; LOG_PRINT_BLUE("[API:" << pfunc_call_name << "]-->>", LOG_LEVEL_0); uint64_t ticks_before_start = epee::misc_utils::get_tick_count(); \ @@ -65,27 +64,6 @@ QString make_response_dbg(const T& r, const std::string& location) } #include "mainwindow.h" -// -// void MediatorObject::from_html_to_c(const QString &text) -// { -// from_c_to_html(text); -// } -// -// template -// struct InvokeWrapper { -// R *receiver; -// void (C::*memberFun)(Arg); -// void operator()(Arg result) { -// (receiver->*memberFun)(result); -// } -// }; -// -// template -// InvokeWrapper invoke(R *receiver, void (C::*memberFun)(Arg)) -// { -// InvokeWrapper wrapper = { receiver, memberFun }; -// return wrapper; -// } std::wstring convert_to_lower_via_qt(const std::wstring& w) @@ -98,8 +76,6 @@ MainWindow::MainWindow() : m_gui_deinitialize_done_1(false) , m_backend_stopped_2(false) , m_system_shutdown(false) - , m_view(nullptr) - , m_channel(nullptr) , m_ui_dispatch_id_counter(0) { #ifndef _MSC_VER @@ -111,17 +87,7 @@ MainWindow::MainWindow() MainWindow::~MainWindow() { m_backend.subscribe_to_core_events(nullptr); - if (m_view) - { - m_view->page()->setWebChannel(nullptr); - m_view = nullptr; - } - if (m_channel) - { - m_channel->deregisterObject(this); - delete m_channel; - m_channel = nullptr; - } + if (m_ipc_worker.joinable()) { m_ipc_worker.join(); @@ -135,82 +101,6 @@ void MainWindow::on_load_finished(bool ok) CATCH_ENTRY2(void()); } -bool MainWindow::init_window() -{ - m_view = new QWebEngineView(this); - m_channel = new QWebChannel(m_view->page()); - m_view->page()->setWebChannel(m_channel); - - QWidget* central_widget_to_be_set = m_view; - - std::string qt_dev_tools_option = m_backend.get_qt_dev_tools_option(); - if (!qt_dev_tools_option.empty()) - { -#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) - std::vector qt_dev_tools_option_parts; - boost::split(qt_dev_tools_option_parts, qt_dev_tools_option, [](char c) { return c == ','; }); - - Qt::Orientation orientation = Qt::Vertical; - if (qt_dev_tools_option_parts.size() >= 1 && qt_dev_tools_option_parts[0] == "horizontal") - orientation = Qt::Horizontal; - - double zoom_factor = 1.3; - if (qt_dev_tools_option_parts.size() >= 2) - epee::string_tools::get_xtype_from_string(zoom_factor, qt_dev_tools_option_parts[1]); - - QSplitter* spliter = new QSplitter(orientation); - spliter->addWidget(m_view); - QWebEngineView* inspector = new QWebEngineView(); - spliter->addWidget(inspector); - m_view->page()->setDevToolsPage(inspector->page()); - inspector->setZoomFactor(zoom_factor); - - spliter->setCollapsible(0, false); - spliter->setCollapsible(1, false); - - QList Sizes; - Sizes.append(0.5 * m_view->sizeHint().height()); - Sizes.append(0.5 * m_view->sizeHint().height()); - spliter->setSizes(Sizes); - - central_widget_to_be_set = spliter; -#else - LOG_ERROR("Qt Dev Tool is not available for this Qt version, try building with Qt 5.11.0 or higher"); -#endif - } - - // register QObjects to be exposed to JavaScript - m_channel->registerObject(QStringLiteral("mediator_object"), this); - - connect(m_view, SIGNAL(loadFinished(bool)), SLOT(on_load_finished(bool))); - - setCentralWidget(central_widget_to_be_set); - //this->setMouseTracking(true); - - m_view->page()->settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessFileUrls, true); - m_view->page()->settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true); - m_view->page()->settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); - - m_view->settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessFileUrls, true); - m_view->settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true); - m_view->settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); - - m_localization.resize(localization_id_couter); - m_localization[localization_id_quit] = "Quit"; - m_localization[localization_id_is_received] = " is received"; - m_localization[localization_id_is_confirmed] = " is confirmed"; - m_localization[localization_id_income_transfer_unconfirmed] = "Income transfer (unconfirmed)"; - m_localization[localization_id_income_transfer_confirmed] = "Income transfer confirmed"; - m_localization[localization_id_locked] = "(locked)"; - m_localization[localization_id_mined] = "(mined)"; - m_localization[localization_id_minimized_title] = "Lethean app is minimized to tray"; - m_localization[localization_id_minimized_text] = "You can restore it with double-click or context menu"; - m_localization[localization_id_tray_menu_show] = "localization_id_tray_menu_show"; - m_localization[localization_id_tray_menu_minimize] = "localization_id_tray_menu_minimize"; - - return true; -} - QString MainWindow::get_default_user_dir(const QString& param) { TRY_ENTRY(); @@ -287,7 +177,7 @@ QString MainWindow::get_options() void MainWindow::tray_quit_requested() { TRY_ENTRY(); - LOG_PRINT_MAGENTA("[GUI]->[HTML] tray_quit_requested", LOG_LEVEL_0); + LOG_PRINT_MAGENTA("[GUI]->[HTML] tray_quit_requested", LOG_LEVEL_0); emit quit_requested("{}"); CATCH_ENTRY2(void()); } @@ -296,7 +186,7 @@ void MainWindow::closeEvent(QCloseEvent *event) { TRY_ENTRY(); LOG_PRINT_L0("[GUI] CLOSE EVENT"); - CHECK_AND_ASSERT_MES(m_gui_deinitialize_done_1 == m_backend_stopped_2, void(), "m_gui_deinitialize_done_1 != m_backend_stopped_2, m_gui_deinitialize_done_1 = " << m_gui_deinitialize_done_1 + CHECK_AND_ASSERT_MES(m_gui_deinitialize_done_1 == m_backend_stopped_2, void(), "m_gui_deinitialize_done_1 != m_backend_stopped_2, m_gui_deinitialize_done_1 = " << m_gui_deinitialize_done_1 << "m_backend_stopped_2 = " << m_backend_stopped_2); @@ -309,7 +199,6 @@ void MainWindow::closeEvent(QCloseEvent *event) } else if (m_gui_deinitialize_done_1 && m_backend_stopped_2) { - store_pos(true); store_app_config(); event->accept(); } @@ -342,53 +231,6 @@ std::string state_to_text(int s) CATCH_ENTRY2(""); } -void MainWindow::changeEvent(QEvent *e) -{ - TRY_ENTRY(); - switch (e->type()) - { - case QEvent::WindowStateChange: - { - QWindowStateChangeEvent* event = static_cast< QWindowStateChangeEvent* >(e); - qDebug() << "Old state: " << state_to_text(event->oldState()).c_str() << ", new state: " << state_to_text(this->windowState()).c_str(); - - if (event->oldState() & Qt::WindowMinimized && !(this->windowState() & Qt::WindowMinimized)) - { - qDebug() << "Window restored (to normal or maximized state)!"; - if (m_tray_icon) - { - //QTimer::singleShot(250, this, SLOT(show())); - } - restore_pos(); - } - else if (!(event->oldState() & Qt::WindowMinimized) && (this->windowState() & Qt::WindowMinimized)) - { - store_pos(); - qDebug() << "Window minimized"; - show_notification(m_localization[localization_id_minimized_title], m_localization[localization_id_minimized_text]); - } - else if (!(event->oldState() & Qt::WindowFullScreen) && (this->windowState() & Qt::WindowFullScreen)) - { - //maximize - store_window_pos(); - this->update(); - } - else if ((event->oldState() & Qt::WindowFullScreen) && !(this->windowState() & Qt::WindowFullScreen)) - { - //restore - this->update(); - } - - break; - } - default: - break; - } - - QWidget::changeEvent(e); - CATCH_ENTRY2(void()); -} - bool MainWindow::store_app_config() { TRY_ENTRY(); @@ -413,42 +255,21 @@ bool MainWindow::load_app_config() bool MainWindow::init(const std::string& html_path) { TRY_ENTRY(); - //QtWebEngine::initialize(); - init_tray_icon(html_path); - set_html_path(html_path); m_threads_pool.init(2); m_backend.subscribe_to_core_events(this); bool r = QSslSocket::supportsSsl(); - if (r) - { + if (r) { LOG_PRINT_GREEN("[Support SSL]: YES", LOG_LEVEL_0); - } - else - { -// QMessageBox::question(this, "OpenSSL support disabled.", "OpenSSL support disabled.", -// QMessageBox::Ok); + } else { LOG_PRINT_RED("[Support SSL]: NO", LOG_LEVEL_0); } - //---- - this->setContextMenuPolicy(Qt::ContextMenuPolicy::NoContextMenu); - m_view->setContextMenuPolicy(Qt::ContextMenuPolicy::NoContextMenu); - return true; CATCH_ENTRY2(false); } -void MainWindow::on_menu_show() -{ - TRY_ENTRY(); - qDebug() << "Context menu: show()"; - this->show(); - this->activateWindow(); - CATCH_ENTRY2(void()); -} - -void MainWindow::init_tray_icon(const std::string& html_path) +void MainWindow::init_tray_icon() { TRY_ENTRY(); if (!QSystemTrayIcon::isSystemTrayAvailable()) @@ -457,40 +278,26 @@ void MainWindow::init_tray_icon(const std::string& html_path) return; } - - m_restore_action = std::unique_ptr(new QAction(tr("&Restore"), this)); - connect(m_restore_action.get(), SIGNAL(triggered()), this, SLOT(on_menu_show())); - m_quit_action = std::unique_ptr(new QAction(tr("&Quit"), this)); connect(m_quit_action.get(), SIGNAL(triggered()), this, SLOT(tray_quit_requested())); - m_minimize_action = std::unique_ptr(new QAction(tr("minimizeAction"), this)); - connect(m_minimize_action.get(), SIGNAL(triggered()), this, SLOT(showMinimized())); - m_tray_icon_menu = std::unique_ptr(new QMenu(this)); - m_tray_icon_menu->addAction(m_minimize_action.get()); + m_tray_icon_menu = std::unique_ptr(new QMenu()); //m_tray_icon_menu->addAction(m_restore_action.get()); - m_tray_icon_menu->addSeparator(); m_tray_icon_menu->addAction(m_quit_action.get()); m_tray_icon = std::unique_ptr(new QSystemTrayIcon(this)); m_tray_icon->setContextMenu(m_tray_icon_menu.get()); - //setup icon #ifdef TARGET_OS_MAC - m_normal_icon_path = html_path + "/files/app22macos.png"; // X11 tray icon size is 22x22 - m_blocked_icon_path = html_path + "/files/app22macos_blocked.png"; // X11 tray icon size is 22x22 + QIcon qi( ":/lthn.png" ); #else - m_normal_icon_path = html_path + "/files/app22windows.png"; // X11 tray icon size is 22x22 - m_blocked_icon_path = html_path + "/files/app22windows_blocked.png"; // X11 tray icon size + QIcon qi( ":/lthn.png" ); #endif //setWindowIcon(QIcon(iconPath.c_str())); - QIcon qi( QString::fromWCharArray(epee::string_encoding::utf8_to_wstring(m_normal_icon_path).c_str()) ); - qi.setIsMask(true); + //qi.setIsMask(true); m_tray_icon->setIcon(qi); - m_tray_icon->setToolTip(CURRENCY_NAME_BASE); - connect(m_tray_icon.get(), SIGNAL(activated(QSystemTrayIcon::ActivationReason)), - this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); + m_tray_icon->setToolTip( "Lethean Blockchain API Server"); m_tray_icon->show(); CATCH_ENTRY2(void()); } @@ -520,103 +327,6 @@ QString MainWindow::get_log_file() CATCH_ENTRY2(""); } -void MainWindow::store_window_pos() -{ - TRY_ENTRY(); - QPoint pos = this->pos(); - QSize sz = this->size(); - m_config.m_window_position.first = pos.x(); - m_config.m_window_position.second = pos.y(); - m_config.m_window_size.first = sz.height(); - m_config.m_window_size.second = sz.width(); - - CATCH_ENTRY2(void()); -} -void MainWindow::store_pos(bool consider_showed) -{ - TRY_ENTRY(); - m_config.is_maximazed = this->isMaximized(); - //here position supposed to be filled from last unserialize or filled on maximize handler - if (!m_config.is_maximazed) - store_window_pos(); - if (consider_showed) - m_config.is_showed = this->isVisible(); - - CATCH_ENTRY2(void()); -} -void MainWindow::restore_pos(bool consider_showed) -{ - TRY_ENTRY(); - if (m_config.is_maximazed) - { - this->setWindowState(windowState() | Qt::WindowMaximized); - } - else - { - QPoint point = QApplication::desktop()->screenGeometry().bottomRight(); - if (m_config.m_window_position.first + m_config.m_window_size.second > point.x() || - m_config.m_window_position.second + m_config.m_window_size.first > point.y() - ) - { - QSize sz = AUTO_VAL_INIT(sz); - sz.setHeight(770); - sz.setWidth(1200); - this->resize(sz); - store_window_pos(); - //reset position(screen changed or other reason) - } - else - { - QPoint pos = AUTO_VAL_INIT(pos); - QSize sz = AUTO_VAL_INIT(sz); - pos.setX(m_config.m_window_position.first); - pos.setY(m_config.m_window_position.second); - sz.setHeight(m_config.m_window_size.first); - sz.setWidth(m_config.m_window_size.second); - this->move(pos); - this->resize(sz); - } - } - - if (consider_showed) - { - if (m_config.is_showed) - this->showNormal(); - else - this->showMinimized(); - } - - CATCH_ENTRY2(void()); -} -void MainWindow::trayIconActivated(QSystemTrayIcon::ActivationReason reason) -{ - TRY_ENTRY(); - if (reason == QSystemTrayIcon::ActivationReason::Trigger) - { - if ( !(this->windowState() & Qt::WindowMinimized)) - { - showMinimized(); - } - else - { - showNormal(); - activateWindow(); - } - - - } - CATCH_ENTRY2(void()); -} - -void MainWindow::load_file(const QString &fileName) -{ - TRY_ENTRY(); - LOG_PRINT_L0("Loading html from path: " << fileName.toStdString()); - QUrl url = QUrl::fromLocalFile(QFileInfo(fileName).absoluteFilePath()); - m_view->load(url); - CATCH_ENTRY2(void()); -} - QString MainWindow::set_clipboard(const QString& param) { TRY_ENTRY(); @@ -647,35 +357,6 @@ QString MainWindow::on_request_quit() CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR); } -bool MainWindow::do_close() -{ - TRY_ENTRY(); - this->close(); - return true; - CATCH_ENTRY2(false); -} - -bool MainWindow::show_inital() -{ - TRY_ENTRY(); - if (load_app_config()) - restore_pos(true); - else - { - m_config = AUTO_VAL_INIT(m_config); - this->show(); - QSize sz = AUTO_VAL_INIT(sz); - sz.setHeight(770); - sz.setWidth(1200); - this->resize(sz); - store_window_pos(); - m_config.is_maximazed = false; - m_config.is_showed = true; - m_config.disable_notifications = false; - } - return true; - CATCH_ENTRY2(false); -} bool MainWindow::on_backend_stopped() { @@ -686,7 +367,7 @@ bool MainWindow::on_backend_stopped() // if (m_quit_requested) // { - /*bool r = */QMetaObject::invokeMethod(this, "do_close", Qt::QueuedConnection); +// /*bool r = */QMetaObject::invokeMethod(this, "do_close", Qt::QueuedConnection); // } return true; CATCH_ENTRY2(false); @@ -712,14 +393,6 @@ bool MainWindow::update_daemon_status(const view::daemon_status_info& info) } -bool MainWindow::show_msg_box(const std::string& message) -{ - TRY_ENTRY(); - QMessageBox::information(this, "Error", message.c_str(), QMessageBox::Ok); - return true; - CATCH_ENTRY2(false); -} - void qt_log_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QByteArray local_msg = msg.toLocal8Bit(); @@ -755,13 +428,13 @@ bool MainWindow::remove_ipc() } return true; } - + bool MainWindow::init_ipc_server() { - //in case previous instance wasn't close graceful, ipc channel will remain open and new creation will fail, so we - //trying to close it anyway before open, to make sure there are no dead channels. If there are another running instance, it wom't + //in case previous instance wasn't close graceful, ipc channel will remain open and new creation will fail, so we + //trying to close it anyway before open, to make sure there are no dead channels. If there are another running instance, it wom't //let channel to close, so it will fail later on creating channel remove_ipc(); #define GUI_IPC_BUFFER_SIZE 10000 @@ -790,7 +463,7 @@ bool MainWindow::init_ipc_server() buff.resize(recvd_size, '*'); handle_ipc_event(buff);//todo process token } - } + } remove_ipc(); LOG_PRINT_L0("IPC Handling thread finished"); } @@ -868,20 +541,12 @@ bool MainWindow::init_backend(int argc, char* argv[]) return false; } - if (!init_window()) - { - this->show_msg_box("Failed to main screen launch, check logs for the more detais."); - return false; - } - if (!m_backend.init(this)) { this->show_msg_box("Failed to initialize backend, check debug logs for more details."); return false; } - - if (m_backend.is_qt_logs_enabled()) { qInstallMessageHandler(qt_log_message_handler); @@ -894,6 +559,8 @@ bool MainWindow::init_backend(int argc, char* argv[]) return false; } + init_tray_icon(); + return true; CATCH_ENTRY2(false); } @@ -960,11 +627,11 @@ bool MainWindow::update_wallet_status(const view::wallet_status_info& wsi) { TRY_ENTRY(); m_wallet_states->operator [](wsi.wallet_id) = wsi.wallet_state; - + std::string json_str_pub; epee::serialization::store_t_to_json(static_cast(wsi), json_str_pub, 0, epee::serialization::eol_lf); LOG_PRINT_L0(get_wallet_log_prefix(wsi.wallet_id) + "SENDING SIGNAL -> [update_wallet_status]:" << std::endl << json_str_pub); - + std::string json_str; epee::serialization::store_t_to_json(wsi, json_str, 0, epee::serialization::eol_lf); QMetaObject::invokeMethod(this, "update_wallet_status", Qt::QueuedConnection, Q_ARG(QString, json_str.c_str())); @@ -1034,7 +701,7 @@ bool MainWindow::update_wallets_info(const view::wallets_summary_info& wsi) std::string json_str; epee::serialization::store_t_to_json(wsi, json_str, 0, epee::serialization::eol_lf); LOG_PRINT_L0("SENDING SIGNAL -> [update_wallets_info]"<< std::endl << json_str ); - + QMetaObject::invokeMethod(this, "update_wallets_info", Qt::QueuedConnection, Q_ARG(QString, json_str.c_str())); return true; CATCH_ENTRY2(false); @@ -1088,7 +755,7 @@ bool MainWindow::money_transfer(const view::transfer_event_info& tei) else if (tei.ti.unlock_time) msg += m_localization[localization_id_locked]; - + show_notification(title, msg); return true; @@ -1119,21 +786,6 @@ bool MainWindow::wallet_sync_progress(const view::wallet_sync_progres_param& p) CATCH_ENTRY2(false); } -bool MainWindow::set_html_path(const std::string& path) -{ - TRY_ENTRY(); - //init_tray_icon(path); -#ifdef _MSC_VER - QString url = QString::fromUtf8(path.c_str()) + "/index.html"; - load_file(url); -#else -// load_file(QString((std::string("file://") + path + "/index.html").c_str())); - load_file(QString((std::string("") + path + "/index.html").c_str())); -#endif - return true; - CATCH_ENTRY2(false); -} - bool MainWindow::pos_block_found(const currency::block& block_found) { TRY_ENTRY(); @@ -1318,7 +970,7 @@ void MainWindow::on_core_event(const std::string event_name, const currency::cor std::string get_events_que_json_string(const std::list& eq, std::string& methods_list) { TRY_ENTRY(); - //t the moment portable_storage is not supporting polymorphic objects lists, so + //t the moment portable_storage is not supporting polymorphic objects lists, so //there is no hope to make serialization with variant list, lets handle it manual std::stringstream ss; ss << "{ \"events\" : ["; @@ -1350,13 +1002,13 @@ void MainWindow::on_complete_events() TIME_MEASURE_START_MS(json_buff_generate_time); std::string json_buff = get_events_que_json_string(m_events.m_que, methods_list); TIME_MEASURE_FINISH_MS(json_buff_generate_time); - + QMetaObject::invokeMethod(this, "on_core_event", Qt::QueuedConnection, Q_ARG(QString, QString(json_buff.c_str()))); TIME_MEASURE_FINISH_MS(core_events_handl_time); - LOG_PRINT_L0("SENT SIGNAL -> [CORE_EVENTS]: " << m_events.m_que.size() + LOG_PRINT_L0("SENT SIGNAL -> [CORE_EVENTS]: " << m_events.m_que.size() << ", handle_time: " << core_events_handl_time << "(json: " << json_buff_generate_time << ")ms, json_buff size = " << json_buff.size() << ", methods: " << methods_list); LOG_PRINT_L2("CORE_EVENTS sent signal details: " << ENDL << json_buff); m_events.m_que.clear(); @@ -1416,7 +1068,7 @@ QString MainWindow::get_secure_app_data(const QString& param) std::string filename = m_backend.get_config_folder() + "/" + GUI_SECURE_CONFIG_FILENAME; std::string res_body; - std::string rsp_code = tools::load_encrypted_file(filename, pwd.pass, res_body, APP_DATA_FILE_BINARY_SIGNATURE); + std::string rsp_code = tools::load_encrypted_file(filename, pwd.pass, res_body, APP_DATA_FILE_BINARY_SIGNATURE); if (rsp_code != API_RETURN_CODE_OK) { view::api_response ar; @@ -1475,7 +1127,7 @@ QString MainWindow::check_master_password(const QString& param) crypto::hash master_password_hash = crypto::cn_fast_hash(&master_password_pre_hash, sizeof master_password_pre_hash); crypto::hash pwd_pre_hash = crypto::cn_fast_hash(pwd.pass.c_str(), pwd.pass.length()); crypto::hash pwd_hash = crypto::cn_fast_hash(&pwd_pre_hash, sizeof pwd_pre_hash); - + if (m_master_password != pwd.pass) { ar.error_code = API_RETURN_CODE_WRONG_PASSWORD; @@ -1561,7 +1213,7 @@ QString MainWindow::store_to_file(const QString& path, const QString& buff) return API_RETURN_CODE_ACCESS_DENIED; } - + CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR); } @@ -1686,7 +1338,7 @@ QString MainWindow::set_log_level(const QString& param) epee::log_space::get_set_log_detalisation_level(true, lvl.v); default_ar.error_code = API_RETURN_CODE_OK; LOG_PRINT("[LOG LEVEL]: set to " << lvl.v, LOG_LEVEL_MIN); - + return MAKE_RESPONSE(default_ar); CATCH_ENTRY_FAIL_API_RESPONCE(); } @@ -1724,23 +1376,23 @@ QString MainWindow::set_enable_tor(const QString& param) // QString path = QFileDialog::getOpenFileName(this, "Select file", // "", // ""); -// +// // if (!path.length()) // { // ar.error_code = API_RETURN_CODE_CANCELED; // return MAKE_RESPONSE(ar); // } -// +// // currency::COMMAND_RPC_GET_OFFERS_EX::response rp = AUTO_VAL_INIT(rp); // ar.error_code = m_backend.get_all_offers(rp); -// +// // std::string buff = epee::serialization::store_t_to_json(rp); // bool r = file_io_utils::save_string_to_file(path.toStdString(), buff); // if (!r) // ar.error_code = API_RETURN_CODE_FAIL; // else // ar.error_code = API_RETURN_CODE_OK; -// +// // return MAKE_RESPONSE(ar); // } @@ -1752,55 +1404,6 @@ QString MainWindow::webkit_launched_script() CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR); } //////////////////// -QString MainWindow::show_openfile_dialog(const QString& param) -{ - TRY_ENTRY(); - view::system_filedialog_request ofdr = AUTO_VAL_INIT(ofdr); - view::system_filedialog_response ofdres = AUTO_VAL_INIT(ofdres); - if (!epee::serialization::load_t_from_json(ofdr, param.toStdString())) - { - ofdres.error_code = API_RETURN_CODE_BAD_ARG; - return epee::serialization::store_t_to_json(ofdres, 0, epee::serialization::eol_lf).c_str(); - } - - QString path = QFileDialog::getOpenFileName(this, ofdr.caption.c_str(), - ofdr.default_dir.c_str(), - ofdr.filemask.c_str()); - - if (!path.length()) - { - ofdres.error_code = API_RETURN_CODE_CANCELED; - return epee::serialization::store_t_to_json(ofdres, 0, epee::serialization::eol_lf).c_str(); - } - - ofdres.error_code = API_RETURN_CODE_OK; - ofdres.path = path.toStdString(); - return MAKE_RESPONSE(ofdres); - CATCH_ENTRY_FAIL_API_RESPONCE(); -} - - -QString MainWindow::show_savefile_dialog(const QString& param) -{ - TRY_ENTRY(); - PREPARE_ARG_FROM_JSON(view::system_filedialog_request, ofdr); - view::system_filedialog_response ofdres = AUTO_VAL_INIT(ofdres); - - QString path = QFileDialog::getSaveFileName(this, ofdr.caption.c_str(), - ofdr.default_dir.c_str(), - ofdr.filemask.c_str()); - - if (!path.length()) - { - ofdres.error_code = API_RETURN_CODE_CANCELED; - return epee::serialization::store_t_to_json(ofdres, 0, epee::serialization::eol_lf).c_str(); - } - - ofdres.error_code = API_RETURN_CODE_OK; - ofdres.path = path.toStdString(); - return MAKE_RESPONSE(ofdres); - CATCH_ENTRY_FAIL_API_RESPONCE(); -} QString MainWindow::close_wallet(const QString& param) { @@ -2005,7 +1608,7 @@ QString MainWindow::push_offer(const QString& param) ar.error_code = m_backend.push_offer(a.wallet_id, a.od, res_tx); if (ar.error_code != API_RETURN_CODE_OK) return MAKE_RESPONSE(ar); - + ar.response_data.success = true; ar.response_data.tx_hash = string_tools::pod_to_hex(currency::get_transaction_hash(res_tx)); ar.response_data.tx_blob_size = currency::get_object_blobsize(res_tx); @@ -2228,43 +1831,6 @@ QString MainWindow::get_seed_phrase_info(const QString& param) CATCH_ENTRY_FAIL_API_RESPONCE(); } -void MainWindow::contextMenuEvent(QContextMenuEvent * event) -{ - TRY_ENTRY(); - - CATCH_ENTRY2(void()); -} -QString MainWindow::print_text(const QString& param) -{ - TRY_ENTRY(); - LOG_API_TIMING(); - PREPARE_ARG_FROM_JSON(view::print_text_param, ptp); - - //in >> htmlContent; - - QTextDocument *document = new QTextDocument(); - document->setHtml(ptp.html_text.c_str()); - - QPrinter printer; - default_ar.error_code = API_RETURN_CODE_CANCELED; - - QPrintDialog *dialog = new QPrintDialog(&printer, this); - dialog->setOptions(QAbstractPrintDialog::PrintToFile); - auto res = dialog->exec(); - if (res != QDialog::Accepted) - { - LOG_PRINT_L0("[PRINT_TEXT] exec != QDialog::Accepted, res=" << res); - return MAKE_RESPONSE(default_ar); - } - - document->print(&printer); - - delete document; - default_ar.error_code = API_RETURN_CODE_OK; - LOG_PRINT_L0("[PRINT_TEXT] default_ar.error_code = " << default_ar.error_code); - return MAKE_RESPONSE(default_ar); - CATCH_ENTRY_FAIL_API_RESPONCE(); -} QString MainWindow::print_log(const QString& param) { @@ -2282,9 +1848,9 @@ void MainWindow::show_notification(const std::string& title, const std::string& { TRY_ENTRY(); LOG_PRINT_L1("system notification: \"" << title << "\", \"" << message << "\""); - + // it's expected that title and message are utf-8 encoded! - + #if !defined(__APPLE__) // use Qt tray icon to show messages on Windows and Linux CHECK_AND_ASSERT_MES(m_tray_icon != nullptr, (void)(0), "m_tray_icon is null!"); @@ -2295,5 +1861,13 @@ void MainWindow::show_notification(const std::string& title, const std::string& #endif CATCH_ENTRY2(void()); } - - +QString MainWindow::get_wallet_info(const QString& param) +{ + TRY_ENTRY(); + LOG_API_TIMING(); + PREPARE_ARG_FROM_JSON(view::wallet_id_obj, waid); + PREPARE_RESPONSE(view::wallet_info, ar); + ar.error_code = m_backend.get_wallet_info(waid.wallet_id, ar.response_data); + return MAKE_RESPONSE(ar); + CATCH_ENTRY_FAIL_API_RESPONCE(); +} diff --git a/src/gui/qt-daemon/application/mainwindow.h b/src/gui/mainwindow.h similarity index 91% rename from src/gui/qt-daemon/application/mainwindow.h rename to src/gui/mainwindow.h index f01dbe93f..46ec587fc 100644 --- a/src/gui/qt-daemon/application/mainwindow.h +++ b/src/gui/mainwindow.h @@ -32,15 +32,15 @@ QT_END_NAMESPACE // class MediatorObject : public QObject // { // Q_OBJECT -// +// // public: -// +// // signals : // /*! // This signal is emitted from the C++ side and the text displayed on the HTML client side. // */ // void from_c_to_html(const QString &text); -// +// // public slots: // /*! // This slot is invoked from the HTML client side and the text displayed on the server side. @@ -49,25 +49,24 @@ QT_END_NAMESPACE // }; // -class MainWindow : public QMainWindow, +class MainWindow : public QObject, public currency::i_core_event_handler, - public view::i_view, + public view::i_view, public QAbstractNativeEventFilter { Q_OBJECT -public: + public: MainWindow(); ~MainWindow(); bool init_backend(int argc, char* argv[]); - bool show_inital(); void show_notification(const std::string& title, const std::string& message); bool handle_ipc_event(const std::string& arguments); struct app_config { - + epee::kvserializable_pair m_window_position; epee::kvserializable_pair m_window_size; bool is_maximazed; @@ -86,12 +85,9 @@ class MainWindow : public QMainWindow, protected slots: void on_load_finished(bool ok); - bool do_close(); public slots: - QString show_openfile_dialog(const QString& param); - QString show_savefile_dialog(const QString& param); QString open_wallet(const QString& param); QString get_my_offers(const QString& param); QString get_fav_offers(const QString& param); @@ -156,7 +152,6 @@ class MainWindow : public QMainWindow, QString toggle_autostart(const QString& param); QString is_valid_restore_wallet_text(const QString& param); QString get_seed_phrase_info(const QString& param); - QString print_text(const QString& param); QString print_log(const QString& param); QString set_clipboard(const QString& param); QString set_localization_strings(const QString str); @@ -166,9 +161,9 @@ class MainWindow : public QMainWindow, QString get_exchange_last_top(const QString& params); QString get_tx_pool_info(); QString get_default_fee(); - QString get_options(); + QString get_options(); void bool_toggle_icon(const QString& param); - + bool get_is_disabled_notifications(); bool set_is_disabled_notifications(const bool& param); QString export_wallet_history(const QString& param); @@ -176,15 +171,13 @@ class MainWindow : public QMainWindow, QString check_available_sources(const QString& param); QString open_url_in_browser(const QString& param); - void trayIconActivated(QSystemTrayIcon::ActivationReason reason); void tray_quit_requested(); - void on_menu_show(); QString is_remnotenode_mode_preconfigured(); QString start_backend(const QString& params); QString async_call(const QString& func_name, const QString& params); QString sync_call(const QString& func_name, const QString& params); - + QString get_wallet_info(const QString& param); //for test purposes onlys QString request_dummy(); @@ -213,7 +206,6 @@ class MainWindow : public QMainWindow, //------- i_view --------- virtual bool update_daemon_status(const view::daemon_status_info& info); virtual bool on_backend_stopped(); - virtual bool show_msg_box(const std::string& message); virtual bool update_wallet_status(const view::wallet_status_info& wsi); virtual bool update_wallets_info(const view::wallets_summary_info& wsi); virtual bool money_transfer(const view::transfer_event_info& tei); @@ -229,34 +221,23 @@ class MainWindow : public QMainWindow, void closeEvent(QCloseEvent *event); - void contextMenuEvent(QContextMenuEvent * event); - void changeEvent(QEvent *e); void on_maximized(); bool handle_deeplink_params_in_commandline(); //void setOrientation(Qt::ScreenOrientation orientation); - - - void init_tray_icon(const std::string& htmlPath); + + + void init_tray_icon(); bool set_html_path(const std::string& path); void load_file(const QString &fileName); - void store_pos(bool consider_showed = false); - void store_window_pos(); - void restore_pos(bool consider_showed = false); bool store_app_config(); bool load_app_config(); bool init_window(); bool init_ipc_server(); bool remove_ipc(); - - - std::string get_wallet_log_prefix(size_t wallet_id) const { return m_backend.get_wallet_log_prefix(wallet_id); } - //MediatorObject mo; - // UI - QWebEngineView *m_view; - QWebChannel* m_channel; + std::string get_wallet_log_prefix(size_t wallet_id) const { return m_backend.get_wallet_log_prefix(wallet_id); } // DATA wallets_manager m_backend; @@ -269,7 +250,6 @@ class MainWindow : public QMainWindow, std::string m_master_password; - app_config m_config; epee::locked_object> m_wallet_states; @@ -277,7 +257,7 @@ class MainWindow : public QMainWindow, struct events_que_struct { std::list m_que; - + BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(m_que) END_KV_SERIALIZE_MAP() @@ -289,10 +269,10 @@ class MainWindow : public QMainWindow, enum localization_string_indices { // order is surprisingly important here! (see also updateLocalisation in AppController.js) - localization_id_quit = 0, + localization_id_quit = 0, localization_id_is_received, - localization_id_is_confirmed, - localization_id_income_transfer_unconfirmed, + localization_id_is_confirmed, + localization_id_income_transfer_unconfirmed, localization_id_income_transfer_confirmed, localization_id_mined, localization_id_locked, diff --git a/src/gui/qt-daemon/application/notification_helper.h b/src/gui/notification_helper.h similarity index 100% rename from src/gui/qt-daemon/application/notification_helper.h rename to src/gui/notification_helper.h diff --git a/src/gui/qt-daemon/application/notification_helper.mm b/src/gui/notification_helper.mm similarity index 100% rename from src/gui/qt-daemon/application/notification_helper.mm rename to src/gui/notification_helper.mm diff --git a/src/gui/qt-daemon/.gitignore b/src/gui/qt-daemon/.gitignore deleted file mode 100644 index 8a9d35c88..000000000 --- a/src/gui/qt-daemon/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.user diff --git a/src/gui/qt-daemon/Info.plist.in b/src/gui/qt-daemon/Info.plist.in deleted file mode 100644 index e966d32ee..000000000 --- a/src/gui/qt-daemon/Info.plist.in +++ /dev/null @@ -1,63 +0,0 @@ - - - - - LSEnvironment - - - BuildMachineOSBuild - 14E46 - CFBundleDevelopmentRegion - English - CFBundleExecutable - Lethean - CFBundleIconFile - app.icns - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - - CFBundlePackageType - APPL - CFBundleSignature - ???? - CFBundleVersion - - CFBundleIdentifier - Lethean - CSResourcesFileMapped - - DTCompiler - com.apple.compilers.llvm.clang.1_0 - DTPlatformBuild - 6E35b - DTPlatformVersion - GM - DTSDKBuild - 14D125 - DTSDKName - macosx10.10 - DTXcode - 0640 - DTXcodeBuild - 6E35b - LSRequiresCarbon - - NSHumanReadableCopyright - - NSHighResolutionCapable - True - CFBundleURLTypes - - - CFBundleURLName - LetheanApp - CFBundleURLSchemes - - lethean - - - - - - diff --git a/src/gui/qt-daemon/app.icns b/src/gui/qt-daemon/app.icns deleted file mode 100644 index 50e0fad5c..000000000 Binary files a/src/gui/qt-daemon/app.icns and /dev/null differ diff --git a/src/gui/qt-daemon/app.ico b/src/gui/qt-daemon/app.ico deleted file mode 100644 index 34837e0e1..000000000 Binary files a/src/gui/qt-daemon/app.ico and /dev/null differ diff --git a/src/gui/qt-daemon/app.qrc b/src/gui/qt-daemon/app.qrc deleted file mode 100644 index b828a4508..000000000 --- a/src/gui/qt-daemon/app.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - app.ico - - \ No newline at end of file diff --git a/src/gui/qt-daemon/app.rc b/src/gui/qt-daemon/app.rc deleted file mode 100644 index 05c8afbc3..000000000 --- a/src/gui/qt-daemon/app.rc +++ /dev/null @@ -1,2 +0,0 @@ - -IDI_ICON1 ICON DISCARDABLE "app.ico" \ No newline at end of file diff --git a/src/gui/qt-daemon/layout b/src/gui/qt-daemon/layout deleted file mode 160000 index f336b3d94..000000000 --- a/src/gui/qt-daemon/layout +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f336b3d94184e0e02e3b49f1819809c78018ffed diff --git a/src/gui/qt-daemon/main.cpp b/src/gui/qt-daemon/main.cpp deleted file mode 100644 index 84edebc74..000000000 --- a/src/gui/qt-daemon/main.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2014-2018 Zano Project -// Copyright (c) 2014-2018 The Louisdor Project -// Copyright (c) 2012-2013 The Boolberry developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include -#include "application/mainwindow.h" -#include "qdebug.h" -#include -#include -//#include "qtlogger.h" -#include "include_base_utils.h" -#include "currency_config.h" -#ifdef Q_OS_DARWIN -#include "application/urleventfilter.h" -#endif - -int main(int argc, char *argv[]) -{ -//#if defined(ARCH_CPU_X86_64) && _MSC_VER <= 1800 - // VS2013's CRT only checks the existence of FMA3 instructions, not the - // enabled-ness of them at the OS level (this is fixed in VS2015). We force - // off usage of FMA3 instructions in the CRT to avoid using that path and - // hitting illegal instructions when running on CPUs that support FMA3, but - // OSs that don't. Because we use the static library CRT we have to call - // this function once in each DLL. - // See http://crbug.com/436603. -// _set_FMA3_enable(0); -//#endif // ARCH_CPU_X86_64 && _MSC_VER <= 1800 - - if(argc > 1) - std::cout << argv[1] << std::endl; - -#ifdef _MSC_VER - #ifdef _WIN64 - _set_FMA3_enable(0); - #endif - //mutex to let InnoSetup know about running instance - ::CreateMutex(NULL, FALSE, CURRENCY_NAME_BASE "_instance"); - //::CreateMutex(NULL, FALSE, "Global\\" CURRENCY_NAME_BASE "_instance"); -#endif - - -#ifdef WIN32 - WCHAR sz_file_name[MAX_PATH + 1] = L""; - ::GetModuleFileNameW(NULL, sz_file_name, MAX_PATH + 1); - std::string path_to_process_utf8 = epee::string_encoding::wstring_to_utf8(sz_file_name); -#else - std::string path_to_process_utf8 = argv[0]; -#endif - - TRY_ENTRY(); - epee::string_tools::set_module_name_and_folder(path_to_process_utf8); - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); -#ifdef _MSC_VER -#if _MSC_VER >= 1910 - QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); //HiDPI pixmaps - qputenv("QT_SCALE_FACTOR", "0.75"); -#endif -#endif - - log_space::get_set_log_detalisation_level(true, LOG_LEVEL_0); - log_space::get_set_need_thread_id(true, true); - log_space::log_singletone::enable_channels("core,currency_protocol,tx_pool,p2p,wallet"); - - - QApplication app(argc, argv); - - MainWindow viewer; - if (!viewer.init_backend(argc, argv)) - { - return 1; - } - -#ifdef Q_OS_DARWIN - URLEventFilter url_event_filter(&viewer); - app.installEventFilter(&url_event_filter); -#endif - - app.installNativeEventFilter(&viewer); - viewer.setWindowTitle(CURRENCY_NAME_BASE); - viewer.show_inital(); - - int res = app.exec(); - LOG_PRINT_L0("Process exit with code: " << res); - return res; - CATCH_ENTRY2(0); -} diff --git a/src/gui/qt-daemon/qtlogger.h b/src/gui/qt-daemon/qtlogger.h deleted file mode 100644 index b1ff2e765..000000000 --- a/src/gui/qt-daemon/qtlogger.h +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2014-2018 Zano Project -// Copyright (c) 2014-2018 The Louisdor Project -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#pragma once - -#include - -//#define QT_CONSOLE_STREAM qDebug() - -#define QT_CONSOLE_STREAM(s) \ -{std::stringstream ss; ss << s; fputs(ss.str().c_str(), stderr); fflush(stderr);} - - - -//fputs(buf.c_str(), stderr); -//fflush(stderr); - - -void customHandler(QtMsgType type, const char* msg) { - fputs(msg, stderr); - fflush(stderr); -} - - -class qt_console_stream : public epee::log_space::ibase_log_stream -{ - QDebug db; -public: - qt_console_stream() : db(qDebug()) - { - // Somewhere in your program - //qInstallMsgHandler(customHandler); - } - - ~qt_console_stream() - { - } - - int get_type(){ return LOGGER_CONSOLE; } - - inline void set_console_color(int color, bool bright) - { - switch (color) - { - case epee::log_space::console_color_default: - if (bright) - {QT_CONSOLE_STREAM("\033[1;37m");} - else - {QT_CONSOLE_STREAM("\033[0m");} - break; - case epee::log_space::console_color_white: - if (bright) - {QT_CONSOLE_STREAM("\033[1;37m");} - else - {QT_CONSOLE_STREAM("\033[0;37m");} - break; - case epee::log_space::console_color_red: - if (bright) - {QT_CONSOLE_STREAM("\033[1;31m");} - else - {QT_CONSOLE_STREAM("\033[0;31m");} - break; - case epee::log_space::console_color_green: - if (bright) - {QT_CONSOLE_STREAM("\033[1;32m");} - else - {QT_CONSOLE_STREAM("\033[0;32m");} - break; - - case epee::log_space::console_color_blue: - if (bright) - {QT_CONSOLE_STREAM("\033[1;34m");} - else - {QT_CONSOLE_STREAM("\033[0;34m");} - break; - - case epee::log_space::console_color_cyan: - if (bright) - {QT_CONSOLE_STREAM("\033[1;36m");} - else - {QT_CONSOLE_STREAM("\033[0;36m");} - break; - - case epee::log_space::console_color_magenta: - if (bright) - {QT_CONSOLE_STREAM("\033[1;35m");} - else - {QT_CONSOLE_STREAM("\033[0;35m");} - break; - - case epee::log_space::console_color_yellow: - if (bright) - {QT_CONSOLE_STREAM("\033[1;33m");} - else - {QT_CONSOLE_STREAM("\033[0;33m");} - break; - - } - } - - inline void reset_console_color() - { - {QT_CONSOLE_STREAM("\033[0m");} - } - - virtual bool out_buffer(const char* buffer, int buffer_len, int log_level, int color, const char* plog_name = NULL) - { - if (plog_name) - return true; //skip alternative logs from console - - set_console_color(color, log_level < 1); - - std::string buf(buffer, buffer_len); - for (size_t i = 0; i != buf.size(); i++) - { - if (buf[i] == 7 || buf[i] == -107) - buf[i] = '^'; - //remove \n - //if (i == buf.size()-1) - // buf[i] = ' '; - } - - QT_CONSOLE_STREAM(buf.c_str()); - - - reset_console_color(); - return true; - } - - -}; diff --git a/src/gui/resources/app22macos.png b/src/gui/resources/app22macos.png new file mode 100644 index 000000000..8fc0f796b Binary files /dev/null and b/src/gui/resources/app22macos.png differ diff --git a/src/gui/resources/app22macos_blocked.png b/src/gui/resources/app22macos_blocked.png new file mode 100644 index 000000000..d4ebb03f4 Binary files /dev/null and b/src/gui/resources/app22macos_blocked.png differ diff --git a/src/gui/resources/app22windows.png b/src/gui/resources/app22windows.png new file mode 100644 index 000000000..e681d94f6 Binary files /dev/null and b/src/gui/resources/app22windows.png differ diff --git a/src/gui/resources/app22windows_blocked.png b/src/gui/resources/app22windows_blocked.png new file mode 100644 index 000000000..1e309a5b4 Binary files /dev/null and b/src/gui/resources/app22windows_blocked.png differ diff --git a/src/gui/resources/desktop_linux_icon.png b/src/gui/resources/desktop_linux_icon.png new file mode 100644 index 000000000..ad457440b Binary files /dev/null and b/src/gui/resources/desktop_linux_icon.png differ diff --git a/src/gui/resources/files.qrc b/src/gui/resources/files.qrc new file mode 100644 index 000000000..a42e00bb1 --- /dev/null +++ b/src/gui/resources/files.qrc @@ -0,0 +1,7 @@ + + + app22macos.png + app22windows.png + lthn.png + + diff --git a/src/gui/resources/lthn.png b/src/gui/resources/lthn.png new file mode 100644 index 000000000..0958f3453 Binary files /dev/null and b/src/gui/resources/lthn.png differ diff --git a/src/gui/qt-daemon/application/urleventfilter.cpp b/src/gui/urleventfilter.cpp similarity index 100% rename from src/gui/qt-daemon/application/urleventfilter.cpp rename to src/gui/urleventfilter.cpp diff --git a/src/gui/qt-daemon/application/urleventfilter.h b/src/gui/urleventfilter.h similarity index 100% rename from src/gui/qt-daemon/application/urleventfilter.h rename to src/gui/urleventfilter.h diff --git a/src/gui/websocketclientwrapper.cpp b/src/gui/websocketclientwrapper.cpp new file mode 100644 index 000000000..68c1fb5c1 --- /dev/null +++ b/src/gui/websocketclientwrapper.cpp @@ -0,0 +1,34 @@ +#include "websocketclientwrapper.h" +#include "websockettransport.h" + +#include + +/*! + \brief Wraps connected QWebSockets clients in WebSocketTransport objects. + + This code is all that is required to connect incoming WebSockets to the WebChannel. Any kind + of remote JavaScript client that supports WebSockets can thus receive messages and access the + published objects. +*/ + +/*! + Construct the client wrapper with the given parent. + + All clients connecting to the QWebSocketServer will be automatically wrapped + in WebSocketTransport objects. +*/ +WebSocketClientWrapper::WebSocketClientWrapper(QWebSocketServer *server, QObject *parent) + : QObject(parent) + , m_server(server) +{ + connect(server, &QWebSocketServer::newConnection, + this, &WebSocketClientWrapper::handleNewConnection); +} + +/*! + Wrap an incoming WebSocket connection in a WebSocketTransport object. +*/ +void WebSocketClientWrapper::handleNewConnection() +{ + emit clientConnected(new WebSocketTransport(m_server->nextPendingConnection())); +} diff --git a/src/gui/websocketclientwrapper.h b/src/gui/websocketclientwrapper.h new file mode 100644 index 000000000..376fad9a1 --- /dev/null +++ b/src/gui/websocketclientwrapper.h @@ -0,0 +1,29 @@ +#ifndef WEBSOCKETCLIENTWRAPPER_H +#define WEBSOCKETCLIENTWRAPPER_H + +#include + +class WebSocketTransport; + +QT_BEGIN_NAMESPACE +class QWebSocketServer; +QT_END_NAMESPACE + +class WebSocketClientWrapper : public QObject +{ + Q_OBJECT + + public: + explicit WebSocketClientWrapper(QWebSocketServer *server, QObject *parent = nullptr); + + signals: + void clientConnected(WebSocketTransport *client); + + private slots: + void handleNewConnection(); + + private: + QWebSocketServer *m_server; +}; + +#endif // WEBSOCKETCLIENTWRAPPER_H diff --git a/src/gui/websockettransport.cpp b/src/gui/websockettransport.cpp new file mode 100644 index 000000000..145ff8b3b --- /dev/null +++ b/src/gui/websockettransport.cpp @@ -0,0 +1,64 @@ +#include "websockettransport.h" + +#include +#include +#include +#include + +/*! + \brief QWebChannelAbstractSocket implementation that uses a QWebSocket internally. + + The transport delegates all messages received over the QWebSocket over its + textMessageReceived signal. Analogously, all calls to sendTextMessage will + be send over the QWebSocket to the remote client. +*/ + +/*! + Construct the transport object and wrap the given socket. + + The socket is also set as the parent of the transport object. +*/ +WebSocketTransport::WebSocketTransport(QWebSocket *socket) + : QWebChannelAbstractTransport(socket) + , m_socket(socket) +{ + connect(socket, &QWebSocket::textMessageReceived, + this, &WebSocketTransport::textMessageReceived); + connect(socket, &QWebSocket::disconnected, + this, &WebSocketTransport::deleteLater); +} + +/*! + Destroys the WebSocketTransport. +*/ +WebSocketTransport::~WebSocketTransport() +{ + m_socket->deleteLater(); +} + +/*! + Serialize the JSON message and send it as a text message via the WebSocket to the client. +*/ +void WebSocketTransport::sendMessage(const QJsonObject &message) +{ + QJsonDocument doc(message); + m_socket->sendTextMessage(QString::fromUtf8(doc.toJson(QJsonDocument::Compact))); +} + +/*! + Deserialize the stringified JSON messageData and emit messageReceived. +*/ +void WebSocketTransport::textMessageReceived(const QString &messageData) +{ + QJsonParseError error; + QJsonDocument message = QJsonDocument::fromJson(messageData.toUtf8(), &error); + if (error.error) { + qWarning() << "Failed to parse text message as JSON object:" << messageData + << "Error is:" << error.errorString(); + return; + } else if (!message.isObject()) { + qWarning() << "Received JSON message that is not an object: " << messageData; + return; + } + emit messageReceived(message.object(), this); +} diff --git a/src/gui/websockettransport.h b/src/gui/websockettransport.h new file mode 100644 index 000000000..b3018385e --- /dev/null +++ b/src/gui/websockettransport.h @@ -0,0 +1,26 @@ +#ifndef WEBSOCKETTRANSPORT_H +#define WEBSOCKETTRANSPORT_H + +#include + +QT_BEGIN_NAMESPACE +class QWebSocket; +QT_END_NAMESPACE + +class WebSocketTransport : public QWebChannelAbstractTransport +{ + Q_OBJECT + public: + explicit WebSocketTransport(QWebSocket *socket); + virtual ~WebSocketTransport(); + + void sendMessage(const QJsonObject &message) override; + + private slots: + void textMessageReceived(const QString &message); + + private: + QWebSocket *m_socket; +}; + +#endif // WEBSOCKETTRANSPORT_H diff --git a/utils/build/testnet_linux_gui.sh b/utils/build/testnet_linux_gui.sh index 07802f6bd..435214ea9 100755 --- a/utils/build/testnet_linux_gui.sh +++ b/utils/build/testnet_linux_gui.sh @@ -1,38 +1,6 @@ #!/bin/bash -x -# Environment prerequisites: -# 1) QT_PREFIX_PATH should be set to Qt libs folder -# 2) BOOST_ROOT should be set to the root of Boost -# 3) OPENSSL_ROOT_DIR should be set to the root of OpenSSL -# -# for example, place these lines to the end of your ~/.bashrc : -# -# export BOOST_ROOT=/home/user/boost_1_66_0 -# export QT_PREFIX_PATH=/home/user/Qt5.10.1/5.10.1/gcc_64 -# export OPENSSL_ROOT_DIR=/home/user/openssl - -ARCHIVE_NAME_PREFIX=lethean-linux-x64- - -: "${BOOST_ROOT:?BOOST_ROOT should be set to the root of Boost, ex.: /home/user/boost_1_66_0}" -: "${QT_PREFIX_PATH:?QT_PREFIX_PATH should be set to Qt libs folder, ex.: /home/user/Qt5.10.1/5.10.1/gcc_64}" -: "${OPENSSL_ROOT_DIR:?OPENSSL_ROOT_DIR should be set to OpenSSL root folder, ex.: /home/user/openssl}" - -if [ -n "$build_prefix" ]; then - ARCHIVE_NAME_PREFIX=${ARCHIVE_NAME_PREFIX}${build_prefix}- - build_prefix_label="$build_prefix " -fi - -if [ "$testnet" == true ]; then - testnet_def="-D TESTNET=TRUE" - testnet_label="testnet " - ARCHIVE_NAME_PREFIX=${ARCHIVE_NAME_PREFIX}testnet- -fi - -if [ "$testnet" == true ] || [ -n "$qt_dev_tools" ]; then - copy_qt_dev_tools=true - copy_qt_dev_tools_label="devtools " - ARCHIVE_NAME_PREFIX=${ARCHIVE_NAME_PREFIX}devtools- -fi +ARCHIVE_NAME_PREFIX=lethean-gui-bundle-linux-testnet-$(arch) prj_root=$(pwd) @@ -40,81 +8,25 @@ prj_root=$(pwd) echo "---------------- BUILDING PROJECT ----------------" echo "--------------------------------------------------" -echo "Building...." +echo "Building...." -rm -rf build; mkdir -p build/release; cd build/release; -cmake $testnet_def -D STATIC=true -D ARCH=x86-64 -D BUILD_GUI=TRUE -D OPENSSL_ROOT_DIR="$OPENSSL_ROOT_DIR" -D CMAKE_PREFIX_PATH="$QT_PREFIX_PATH" -D CMAKE_BUILD_TYPE=Release ../.. +rm -rf build; mkdir -p build/release; cd build/release; +cmake -D TESTNET=TRUE -D STATIC=true -D ARCH=x86-64 -D BUILD_GUI=TRUE -D CMAKE_BUILD_TYPE=Release ../.. if [ $? -ne 0 ]; then echo "Failed to run cmake" exit 1 fi -make -j daemon simplewallet connectivity_tool +make -j2 Lethean if [ $? -ne 0 ]; then echo "Failed to make!" exit 1 fi -make -j Lethean -if [ $? -ne 0 ]; then - echo "Failed to make!" - exit 1 -fi - - -read version_str <<< $(./src/letheand --version | awk '/^Lethean/ { print $2 }') -version_str=${version_str} -echo $version_str - -rm -rf Lethean; -mkdir -p Lethean; - -rsync -a ../../src/gui/qt-daemon/layout/html ./Lethean --exclude less --exclude package.json --exclude gulpfile.js -cp -Rv ../../utils/Lethean.sh ./Lethean -chmod 777 ./Lethean/Lethean.sh -mkdir ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libicudata.so.56 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libicui18n.so.56 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libicuuc.so.56 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5Core.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5DBus.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5Gui.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5Network.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5OpenGL.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5Positioning.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5PrintSupport.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5Qml.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5Quick.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5Sensors.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5Sql.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5Widgets.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5WebEngine.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5WebEngineCore.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5WebEngineWidgets.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5WebChannel.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5XcbQpa.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/lib/libQt5QuickWidgets.so.5 ./Lethean/lib -cp $QT_PREFIX_PATH/libexec/QtWebEngineProcess ./Lethean -cp $QT_PREFIX_PATH/resources/qtwebengine_resources.pak ./Lethean -cp $QT_PREFIX_PATH/resources/qtwebengine_resources_100p.pak ./Lethean -cp $QT_PREFIX_PATH/resources/qtwebengine_resources_200p.pak ./Lethean -cp $QT_PREFIX_PATH/resources/icudtl.dat ./Lethean - -if [ "$copy_qt_dev_tools" = true ] ; then - cp $QT_PREFIX_PATH/resources/qtwebengine_devtools_resources.pak ./Lethean -fi - -mkdir ./Lethean/lib/platforms -cp $QT_PREFIX_PATH/plugins/platforms/libqxcb.so ./Lethean/lib/platforms -mkdir ./Lethean/xcbglintegrations -cp $QT_PREFIX_PATH/plugins/xcbglintegrations/libqxcb-glx-integration.so ./Lethean/xcbglintegrations - -cp -Rv src/letheand src/Lethean src/simplewallet src/connectivity_tool ./Lethean - -package_filename=${ARCHIVE_NAME_PREFIX}${version_str}.tar.bz2 +package_filename=${ARCHIVE_NAME_PREFIX}.tar.bz2 rm -f ./$package_filename -tar -cjvf $package_filename Lethean +tar -cjvf ../../$package_filename src/lethean-gui-server if [ $? -ne 0 ]; then echo "Failed to pack" exit 1 @@ -122,6 +34,4 @@ fi echo "Build success" - - exit 0 diff --git a/utils/build/testnet_mac_osx_cli.sh b/utils/build/testnet_mac_osx_cli.sh index 983172f03..11cf3d249 100755 --- a/utils/build/testnet_mac_osx_cli.sh +++ b/utils/build/testnet_mac_osx_cli.sh @@ -39,8 +39,6 @@ fi rm -rf Lethean; mkdir -p Lethean; - - chmod 0777 ./src/letheand src/simplewallet src/connectivity_tool cp -Rv src/letheand src/simplewallet src/connectivity_tool ./Lethean diff --git a/utils/build/testnet_mac_osx_gui.sh b/utils/build/testnet_mac_osx_gui.sh index 7172909e9..423e2addb 100755 --- a/utils/build/testnet_mac_osx_gui.sh +++ b/utils/build/testnet_mac_osx_gui.sh @@ -9,41 +9,22 @@ curr_path=${BASH_SOURCE%/*} : "${CMAKE_OSX_SYSROOT:?CMAKE_OSX_SYSROOT should be set to macOS SDK path, e.g.: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk}" : "${OPENSSL_ROOT_DIR:?variable not set, see also macosx_build_config.command}" -ARCHIVE_NAME_PREFIX=lethean-macos-x64- - -if [ -n "$build_prefix" ]; then - ARCHIVE_NAME_PREFIX=${ARCHIVE_NAME_PREFIX}${build_prefix}- - build_prefix_label="$build_prefix " -fi - -testnet_def="-D TESTNET=TRUE" -testnet_label="testnet " -ARCHIVE_NAME_PREFIX=${ARCHIVE_NAME_PREFIX}testnet- - +ARCHIVE_NAME_PREFIX=lethean-gui-bundle-macos-testnet-$(arch) rm -rf build; mkdir -p build/release; cd build/release; -cmake $testnet_def -D OPENSSL_ROOT_DIR=$OPENSSL_ROOT_DIR -D CMAKE_OSX_SYSROOT=$CMAKE_OSX_SYSROOT -D BUILD_GUI=TRUE -D CMAKE_PREFIX_PATH="$ZANO_QT_PATH" -D CMAKE_BUILD_TYPE=Release -D BOOST_ROOT="$ZANO_BOOST_ROOT" -D BOOST_LIBRARYDIR="$ZANO_BOOST_LIBS_PATH" ../.. +cmake -D TESTNET=TRUE -D OPENSSL_ROOT_DIR=$OPENSSL_ROOT_DIR -D CMAKE_OSX_SYSROOT=$CMAKE_OSX_SYSROOT -D BUILD_GUI=TRUE -D CMAKE_PREFIX_PATH="$ZANO_QT_PATH" -D CMAKE_BUILD_TYPE=Release -D BOOST_ROOT="$ZANO_BOOST_ROOT" -D BOOST_LIBRARYDIR="$ZANO_BOOST_LIBS_PATH" ../.. if [ $? -ne 0 ]; then echo "Failed to cmake" exit 1 fi - - -make -j Lethean +make -j2 Lethean if [ $? -ne 0 ]; then echo "Failed to make Lethean" exit 1 fi -make -j connectivity_tool daemon simplewallet -if [ $? -ne 0 ]; then - echo "Failed to make binaries!" - exit 1 -fi - - cd src/ if [ $? -ne 0 ]; then echo "Failed to cd src" @@ -51,167 +32,33 @@ if [ $? -ne 0 ]; then fi # copy all necessary libs into the bundle in order to workaround El Capitan's SIP restrictions -mkdir -p Lethean.app/Contents/Frameworks/boost_libs -cp -R "$ZANO_BOOST_LIBS_PATH/" Lethean.app/Contents/Frameworks/boost_libs/ +mkdir -p lethean-gui-server.app/Contents/Frameworks/boost_libs +cp -R "$ZANO_BOOST_LIBS_PATH/" lethean-gui-server.app/Contents/Frameworks/boost_libs/ if [ $? -ne 0 ]; then echo "Failed to cp workaround to MacOS" exit 1 fi -# rename process name to big letter -mv Lethean.app/Contents/MacOS/lethean Lethean.app/Contents/MacOS/Lethean -if [ $? -ne 0 ]; then - echo "Failed to rename process" - exit 1 -fi - -cp letheand simplewallet Lethean.app/Contents/MacOS/ -if [ $? -ne 0 ]; then - echo "Failed to copy binaries to Lethean.app folder" - exit 1 -fi - # fix boost libs paths in main executable and libs to workaround El Capitan's SIP restrictions source $(pwd)/../../../utils/build/extras/macos/fix_boost_libs_path.sh -fix_boost_libs_in_binary @executable_path/../Frameworks/boost_libs Lethean.app/Contents/MacOS/Lethean -fix_boost_libs_in_binary @executable_path/../Frameworks/boost_libs Lethean.app/Contents/MacOS/simplewallet -fix_boost_libs_in_binary @executable_path/../Frameworks/boost_libs Lethean.app/Contents/MacOS/letheand -fix_boost_libs_in_libs @executable_path/../Frameworks/boost_libs Lethean.app/Contents/Frameworks/boost_libs +fix_boost_libs_in_binary @executable_path/../Frameworks/boost_libs lethean-gui-server.app/Contents/MacOS/lethean-gui-server +fix_boost_libs_in_libs @executable_path/../Frameworks/boost_libs lethean-gui-server.app/Contents/Frameworks/boost_libs -"$ZANO_QT_PATH/bin/macdeployqt" Lethean.app +"$ZANO_QT_PATH/bin/macdeployqt" lethean-gui-server.app if [ $? -ne 0 ]; then - echo "Failed to macdeployqt Lethean.app" + echo "Failed to macdeployqt lethean-gui-server.app" exit 1 fi - - -rsync -a ../../../src/gui/qt-daemon/layout/html Lethean.app/Contents/MacOS --exclude less --exclude package.json --exclude gulpfile.js -if [ $? -ne 0 ]; then - echo "Failed to cp html to MacOS" - exit 1 -fi - -cp ../../../src/gui/qt-daemon/app.icns Lethean.app/Contents/Resources -if [ $? -ne 0 ]; then - echo "Failed to cp app.icns to resources" - exit 1 -fi - -codesign -s "Developer ID Application: Lethean LTD (W2DNA5L5DY)" --timestamp --options runtime -f --entitlements ../../../utils/build/extras/macos/entitlements.plist --deep ./Lethean.app -if [ $? -ne 0 ]; then - echo "Failed to sign Lethean.app" - exit 1 -fi - - -read version_str <<< $(DYLD_LIBRARY_PATH=$ZANO_BOOST_LIBS_PATH ./connectivity_tool --version | awk '/^Lethean/ { print $2 }') -version_str=${version_str} -echo $version_str - - echo "############### Prepearing archive... ################" -mkdir package_folder -if [ $? -ne 0 ]; then - echo "Failed to zip app" - exit 1 -fi - -mv Lethean.app package_folder -if [ $? -ne 0 ]; then - echo "Failed to top app package" - exit 1 -fi +package_filename=${ARCHIVE_NAME_PREFIX}.tar.bz2 -#fi - -package_filename=${ARCHIVE_NAME_PREFIX}${version_str}.dmg - -source ../../../utils/macosx_dmg_builder.sh -build_fancy_dmg package_folder $package_filename -if [ $? -ne 0 ]; then - echo "Failed to create fancy dmg" - exit 1 -fi +rm -f ./$package_filename +cd lethean-gui-server.app +tar -cjvf ../../../../$package_filename * echo "Build success" - -echo "############### Uploading... ################" - -package_filepath=$package_filename - -scp $package_filepath lethean_build_server:/var/www/html/builds/ -if [ $? -ne 0 ]; then - echo "Failed to upload to remote server" - exit 1 -fi - - -read checksum <<< $( shasum -a 256 $package_filepath | awk '/^/ { print $1 }' ) - -mail_msg="New ${build_prefix_label}${testnet_label}build for macOS-x64:
-https://build.lethean.org/builds/$package_filename
-sha256: $checksum" - -echo "$mail_msg" - -echo "$mail_msg" | mail -s "Lethean macOS-x64 ${build_prefix_label}${testnet_label}build $version_str" ${emails} - - -###################### -# notarization -###################### - -cd package_folder - -echo "Notarizing..." - -# creating archive for notarizing -echo "Creating archive for notarizing" -rm -f Lethean.zip -/usr/bin/ditto -c -k --keepParent ./Lethean.app ./Lethean.zip - -tmpfile="tmptmptmp" -xcrun altool --notarize-app --primary-bundle-id "org.lethean.desktop" -u "hello@lt.hn" -p "@keychain:Developer-altool" --file ./Lethean.zip > $tmpfile 2>&1 -NOTARIZE_RES=$? -NOTARIZE_OUTPUT=$( cat $tmpfile ) -rm $tmpfile -echo "NOTARIZE_OUTPUT=$NOTARIZE_OUTPUT" -if [ $NOTARIZE_RES -ne 0 ]; then - echo "Notarization failed" - exit 1 -fi - -GUID=$(echo "$NOTARIZE_OUTPUT" | egrep -Ewo '[[:xdigit:]]{8}(-[[:xdigit:]]{4}){3}-[[:xdigit:]]{12}') -if [ ${#GUID} -ne 36 ]; then - echo "Couldn't get correct GUID from the response, got only \"$GUID\"" - exit 1 -fi - - -success=0 - -# check notarization status -for i in {1..10}; do - xcrun altool --notarization-info $GUID -u "hello@lt.hn" -p "@keychain:Developer-altool" > $tmpfile 2>&1 - NOTARIZE_OUTPUT=$( cat $tmpfile ) - rm $tmpfile - NOTARIZATION_LOG_URL=$(echo "$NOTARIZE_OUTPUT" | sed -n "s/.*LogFileURL\: \([[:graph:]]*\).*/\1/p") - if [ ${#NOTARIZATION_LOG_URL} -ge 30 ]; then - success=1 - curl -L $NOTARIZATION_LOG_URL - break - fi - sleep 60 -done - -if [ $success -ne 1 ]; then - echo "Build notarization failed" - exit 1 -fi - -echo "Notarization done" diff --git a/utils/build/testnet_windows_gui.bat b/utils/build/testnet_windows_gui.bat index f9979b0b1..6049295e5 100644 --- a/utils/build/testnet_windows_gui.bat +++ b/utils/build/testnet_windows_gui.bat @@ -4,17 +4,12 @@ call utils\build\extras\win\configure_local_paths.cmd SET LOCAL_BOOST_LIB_PATH=%LOCAL_BOOST_PATH%\lib64-msvc-14.2 SET QT_MSVC_PATH=%QT_PREFIX_PATH%\msvc2019_64 -SET ACHIVE_NAME_PREFIX=lethean-win-gui-x64- +SET ACHIVE_NAME_PREFIX=lethean-gui-bundle-win-testnet-x64 SET MY_PATH=%~dp0 SET SOURCES_PATH=%MY_PATH:~0,-13% -IF NOT [%build_prefix%] == [] ( - SET ACHIVE_NAME_PREFIX=%ACHIVE_NAME_PREFIX%%build_prefix%- -) - SET TESTNET_DEF=-D TESTNET=TRUE SET TESTNET_LABEL=testnet -SET ACHIVE_NAME_PREFIX=%ACHIVE_NAME_PREFIX%testnet- SET PARAM=%~1 @@ -55,16 +50,6 @@ IF %ERRORLEVEL% NEQ 0 ( goto error ) -msbuild src/daemon.vcxproj /p:SubSystem="CONSOLE,5.02" /p:Configuration=Release /t:Build -IF %ERRORLEVEL% NEQ 0 ( - goto error -) - -msbuild src/simplewallet.vcxproj /p:SubSystem="CONSOLE,5.02" /p:Configuration=Release /t:Build -IF %ERRORLEVEL% NEQ 0 ( - goto error -) - msbuild src/Lethean.vcxproj /p:SubSystem="WINDOWS,5.02" /p:Configuration=Release /t:Build IF %ERRORLEVEL% NEQ 0 ( @@ -76,16 +61,10 @@ IF %ERRORLEVEL% NEQ 0 ( echo "sources are built successfully" - - :skip_build cd %SOURCES_PATH%/build -set cmd=src\Release\simplewallet.exe --version -FOR /F "tokens=3" %%a IN ('%cmd%') DO set version=%%a -echo '%version%' - -set build_zip_filename=%ACHIVE_NAME_PREFIX%%version%.zip +set build_zip_filename=%ACHIVE_NAME_PREFIX%.zip set build_zip_path=%SOURCES_PATH%\%build_zip_filename% del /F /Q %build_zip_path% @@ -99,12 +78,15 @@ cd src\release mkdir bunch -copy /Y Lethean.exe bunch +copy /Y lethean-gui-server.exe bunch copy /Y letheand.exe bunch copy /Y simplewallet.exe bunch copy /Y *.pdb bunch -%QT_MSVC_PATH%\bin\windeployqt.exe bunch\Lethean.exe +copy /Y %OPENSSL_ROOT_DIR%\bin\libcrypto-1_1-x64.dll bunch +copy /Y %OPENSSL_ROOT_DIR%\bin\libssl-1_1-x64.dll bunch + +%QT_MSVC_PATH%\bin\windeployqt.exe bunch\lethean-gui-server.exe cd bunch @@ -113,16 +95,6 @@ IF %ERRORLEVEL% NEQ 0 ( goto error ) - -@echo "Add html" - -cd %SOURCES_PATH%\src\gui\qt-daemon\layout -zip -x html/package.json html/gulpfile.js html/less/* -r %build_zip_path% html -IF %ERRORLEVEL% NEQ 0 ( - goto error -) - - @echo "Add runtime stuff" @@ -138,36 +110,9 @@ IF %ERRORLEVEL% NEQ 0 ( goto error ) - -@echo "---------------------------------------------------------------" -@echo "-------------------Building installer--------------------------" -@echo "---------------------------------------------------------------" - -mkdir installer_src - - -unzip -o %build_zip_path% -d installer_src -IF %ERRORLEVEL% NEQ 0 ( - goto error -) - - -"%INNOSETUP_PATH%" /dBinariesPath=../../../../build/installer_src /DMyAppVersion=%version% /o%SOURCES_PATH% /f%ACHIVE_NAME_PREFIX%%version%-installer ..\utils\build\extras\win\setup_64.iss -IF %ERRORLEVEL% NEQ 0 ( - goto error -) - - @echo "---------------------------------------------------------------" @echo "---------------------------------------------------------------" -set installer_file=%ACHIVE_NAME_PREFIX%%version%-installer.exe -set installer_path=%SOURCES_PATH%\%installer_file% - -call :sha256 %installer_path% installer_checksum - -call :sha256 %build_zip_path% build_zip_checksum - goto success :error