diff options
Diffstat (limited to '')
138 files changed, 3941 insertions, 1352 deletions
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 08b978bc..4a84d584 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -77,7 +77,7 @@ jobs: - name: Install Qt6 uses: jurplel/install-qt-action@v3 with: - version: '6.6.1' + version: '6.5.3' modules: 'qt5compat' cache: 'true' if: matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-11' || matrix.os == 'macos-12' @@ -212,11 +212,11 @@ jobs: - name: Notarize Release Build (macOS) run: | - xcrun altool --notarize-app \ - -f ${{github.workspace}}/build/GpgFrontend-${{env.sha_short}}-x86_64.zip \ - --primary-bundle-id ${{secrets.GPGFRONTEND_XOCDE_APPID}} \ - -u ${{secrets.APPLE_DEVELOPER_ID}} \ - -p ${{secrets.APPLE_DEVELOPER_ID_SECRET}} + xcrun notarytool submit \ + --apple-id ${{secrets.APPLE_DEVELOPER_ID}} \ + --team-id ${{secrets.APPLE_DEVELOPER_TEAM_ID}} + --password ${{secrets.APPLE_DEVELOPER_ID_SECRET}} \ + ${{github.workspace}}/build/GpgFrontend-${{env.sha_short}}-x86_64.zip if: matrix.os == 'macos-11' || matrix.os == 'macos-12' - name: Package App Image (Linux) diff --git a/CMakeLists.txt b/CMakeLists.txt index eae20641..cebfa67b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -220,7 +220,7 @@ endif () set(BUILD_VERSION ${PROJECT_VERSION}_${CMAKE_SYSTEM}_${CMAKE_SYSTEM_PROCESSOR}_${CMAKE_BUILD_TYPE}) set(GIT_VERSION ${GIT_BRANCH_NAME}_${GIT_COMMIT_HASH}) -string(TIMESTAMP BUILD_TIMESTAMP "%Y-%m-%d %H:%M:%S") +string(TIMESTAMP BUILD_TIMESTAMP UTC) # Convert BUILD_VERSION and GIT_VERSION to lowercase string(TOLOWER "${BUILD_VERSION}" BUILD_VERSION) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9b6a96c7..0bfdb274 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -61,7 +61,7 @@ if(GPGFRONTEND_QT5_BUILD) else() # Introduce Qt # Support Qt version: 6.x - find_package(Qt6 6 COMPONENTS Core Widgets PrintSupport Network Core5Compat LinguistTools REQUIRED) + find_package(Qt6 6 COMPONENTS Core Widgets PrintSupport Network LinguistTools REQUIRED) endif() @@ -140,6 +140,7 @@ if (BASIC_ENV_CONFIG) configure_file(${CMAKE_SOURCE_DIR}/src/GpgFrontend.h.in ${CMAKE_SOURCE_DIR}/src/GpgFrontend.h @ONLY) configure_file(${CMAKE_SOURCE_DIR}/src/GpgFrontendBuildInfo.h.in ${CMAKE_SOURCE_DIR}/src/GpgFrontendBuildInfo.h @ONLY) configure_file(${CMAKE_SOURCE_DIR}/src/GpgFrontendBuildInstallInfo.h.in ${CMAKE_SOURCE_DIR}/src/GpgFrontendBuildInstallInfo.h @ONLY) + configure_file(${CMAKE_SOURCE_DIR}/src/module/sdk/GFSDKBuildInfo.h.in ${CMAKE_SOURCE_DIR}/src/module/sdk/GFSDKBuildInfo.h @ONLY) if (APPLE) configure_file(${CMAKE_SOURCE_DIR}/resource/plist/ExportOptions.plist.in ${CMAKE_BINARY_DIR}/ExportOptions.plist @ONLY) endif () @@ -365,14 +366,20 @@ if (BUILD_APPLICATION) elseif (LINUX AND NOT LINUX_INSTALL_SOFTWARE) add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES}) add_custom_command(TARGET ${AppName} POST_BUILD - COMMAND /bin/mkdir -p ./AppDir/usr/bin && /bin/mv -f ./${AppName} ./AppDir/usr/bin/ - WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - COMMENT "Copying Binary into App Image") + COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/bin" + COMMAND ${CMAKE_COMMAND} -E rename "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/bin/${AppName}" + COMMENT "Copying Binary into App Image" + ) add_custom_command(TARGET ${AppName} POST_BUILD - COMMAND /bin/mkdir -p ./AppDir/usr/lib - WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - COMMENT "Complement to build the required architecture") - # app bundle packing using xcode + COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/lib" + COMMENT "Complement to build the required architecture" + ) + add_custom_command(TARGET ${AppName} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/lib/mods" + COMMAND ${CMAKE_COMMAND} -E rename "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mods" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/lib/mods" + COMMENT "Copying Mods into App Image" + ) + # app bundle packing using xcode elseif (APPLE AND XCODE_BUILD) # standard app bundle packing add_executable(${AppName} MACOSX_BUNDLE ${ICON_RESOURCE} ${BASE_SOURCE} ${RESOURCE_FILES}) @@ -453,7 +460,7 @@ endif () # link options for GpgFrontend if (BUILD_APPLICATION) - target_link_libraries(${AppName} gpgfrontend_ui gpgfrontend_module gpgfrontend_test) + target_link_libraries(${AppName} gpgfrontend_ui gpgfrontend_test) if (MINGW) message(STATUS "Link Application Library For MINGW") target_link_libraries(${AppName} crypto) @@ -535,11 +542,7 @@ if (LINUX AND LINUX_INSTALL_SOFTWARE) gpgfrontend_core gpgfrontend_ui gpgfrontend_test - gpgfrontend_pinentry - gpgfrontend_module_sdk - gpgfrontend_module - gpgfrontend_integrated_module_version_checking - gpgfrontend_integrated_module_gnupg_info_gathering) + gpgfrontend_pinentry) message(STATUS "GpgFrontend Install Libraries: ${GPGFRONTEND_INSTALL_LIBRARIES}") install(TARGETS ${AppName} ${GPGFRONTEND_INSTALL_LIBRARIES} diff --git a/src/app.cpp b/src/app.cpp index a5539a37..9aa72894 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -29,7 +29,7 @@ #include "GpgFrontendContext.h" #include "core/GpgConstants.h" #include "core/GpgCoreInit.h" -#include "module/GpgFrontendModuleInit.h" +#include "core/module/ModuleInit.h" #include "ui/GpgFrontendUIInit.h" // main diff --git a/src/cmd.cpp b/src/cmd.cpp index cef0a984..d41b6de0 100644 --- a/src/cmd.cpp +++ b/src/cmd.cpp @@ -28,13 +28,13 @@ #include "cmd.h" +#include "core/utils/BuildInfoUtils.h" #include "main.h" // std #include <iostream> // GpgFrontend -#include "GpgFrontendBuildInfo.h" #include "GpgFrontendContext.h" #include "test/GpgFrontendTest.h" @@ -42,19 +42,19 @@ namespace GpgFrontend { auto PrintVersion() -> int { QTextStream stream(stdout); - stream << PROJECT_NAME << " " - << "v" << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_PATCH - << '\n'; + stream << PROJECT_NAME << " " << GetProjectVersion() << '\n'; stream << "Copyright (©) 2021 Saturneric <[email protected]>" << '\n' << QCoreApplication::tr( "This is free software; see the source for copying conditions.") << '\n' << '\n'; - stream << QCoreApplication::tr("Build DateTime: ") << BUILD_TIMESTAMP << '\n' - << QCoreApplication::tr("Build Version: ") << BUILD_VERSION << '\n' - << QCoreApplication::tr("Source Code Version: ") << GIT_VERSION - << '\n'; + stream << QCoreApplication::tr("Build DateTime: ") + << QLocale().toString(GetProjectBuildTimestamp()) << '\n' + << QCoreApplication::tr("Build Version: ") << GetProjectBuildVersion() + << '\n' + << QCoreApplication::tr("Source Code Version: ") + << GetProjectBuildGitVersion() << '\n'; stream << Qt::endl; return 0; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index cc1f6742..cedbe69a 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -129,7 +129,6 @@ if (MINGW) target_link_libraries(gpgfrontend_core PUBLIC wsock32) elseif (APPLE) message(STATUS "Link GPG Static Library For macOS") - target_link_libraries(gpgfrontend_core PUBLIC dl) if (XCODE_BUILD) set_target_properties(gpgfrontend_core PROPERTIES diff --git a/src/core/GpgConstants.h b/src/core/GpgConstants.h index c2125650..d339e4f6 100644 --- a/src/core/GpgConstants.h +++ b/src/core/GpgConstants.h @@ -51,4 +51,10 @@ constexpr const char* PGP_PUBLIC_KEY_BEGIN = constexpr const char* PGP_PRIVATE_KEY_BEGIN = "-----BEGIN PGP PRIVATE KEY BLOCK-----"; ///< +// MODULE ID +const QString kGnuPGInfoGatheringModuleID = + "com.bktus.gpgfrontend.module.gnupg_info_gathering"; +const QString kVersionCheckingModuleID = + "com.bktus.gpgfrontend.module.version_checking"; + } // namespace GpgFrontend diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp index 137a118b..42991564 100644 --- a/src/core/GpgCoreInit.cpp +++ b/src/core/GpgCoreInit.cpp @@ -176,7 +176,7 @@ auto InitGpgME(const QString& gpgconf_path, const QString& gnupg_path) -> bool { GF_CORE_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version); // conditional check: only support gpg 2.1.x now - if (!(CompareSoftwareVersion(gnupg_version, "2.1.0") >= 0 && find_gpgconf && + if (!(GFCompareSoftwareVersion(gnupg_version, "2.1.0") >= 0 && find_gpgconf && find_openpgp && find_cms)) { GF_CORE_LOG_ERROR("gpgme env check failed, abort"); return false; @@ -276,7 +276,6 @@ void InitGpgFrontendCore(CoreInitArgs args) { // initialize global register table Module::UpsertRTValue("core", "env.state.gpgme", 0); Module::UpsertRTValue("core", "env.state.ctx", 0); - Module::UpsertRTValue("core", "env.state.gnupg", 0); Module::UpsertRTValue("core", "env.state.basic", 0); Module::UpsertRTValue("core", "env.state.all", 0); @@ -409,60 +408,22 @@ void InitGpgFrontendCore(CoreInitArgs args) { QCoreApplication::tr("Gpg Key Detabase initiation failed")); }; } + GF_CORE_LOG_DEBUG( - "basic env checking finished, " - "including gpgme, ctx, and key infos"); + "basic env checking finished, including gpgme, ctx, and key infos"); + Module::UpsertRTValue("core", "env.state.basic", 1); CoreSignalStation::GetInstance()->SignalGoodGnupgEnv(); - // if gnupg-info-gathering module activated - if (args.gather_external_gnupg_info && - Module::IsModuleAcivate("com.bktus.gpgfrontend.module." - "integrated.gnupg-info-gathering")) { - GF_CORE_LOG_DEBUG( - "module gnupg-info-gathering is activated, " - "loading external gnupg info..."); - - // gather external gnupg info - Module::TriggerEvent( - "GPGFRONTEND_CORE_INITLIZED", - [](const Module::EventIdentifier& /*e*/, - const Module::Event::ListenerIdentifier& l_id, - DataObjectPtr o) { - GF_CORE_LOG_DEBUG( - "received event GPGFRONTEND_CORE_INITLIZED callback " - "from module: {}", - l_id); - - if (l_id == - "com.bktus.gpgfrontend.module.integrated.gnupg-info-" - "gathering") { - GF_CORE_LOG_DEBUG( - "received callback from gnupg-info-gathering "); - - // try to restart all components - auto settings = - GlobalSettingStation::GetInstance().GetSettings(); - auto restart_all_gnupg_components_on_start = - settings.value("gnupg/restart_gpg_agent_on_start", false) - .toBool(); - - if (restart_all_gnupg_components_on_start) { - GpgAdvancedOperator::RestartGpgComponents(); - } - Module::UpsertRTValue("core", "env.state.gnupg", 1); + // try to restart all components + auto restart_all_gnupg_components_on_start = + settings.value("gnupg/restart_gpg_agent_on_start", false).toBool(); - // announce that all checkings were finished - GF_CORE_LOG_INFO( - "all env checking finished, including gpgme, " - "ctx and gnupg"); - Module::UpsertRTValue("core", "env.state.all", 1); - } - }); - } else { - GF_CORE_LOG_DEBUG("gnupg-info-gathering is not activated"); - Module::UpsertRTValue("core", "env.state.all", 1); + if (restart_all_gnupg_components_on_start) { + GpgAdvancedOperator::RestartGpgComponents(); } + + Module::UpsertRTValue("core", "env.state.all", 1); return 0; }, "core_init_task"); diff --git a/src/core/GpgCoreInit.h b/src/core/GpgCoreInit.h index 15f0254d..ecd6afea 100644 --- a/src/core/GpgCoreInit.h +++ b/src/core/GpgCoreInit.h @@ -28,7 +28,7 @@ #pragma once -#include "GpgConstants.h" +#include "core/GpgFrontendCoreExport.h" namespace GpgFrontend { diff --git a/src/core/GpgFrontendCore.h b/src/core/GpgFrontendCore.h index 14b1f878..f07824cf 100644 --- a/src/core/GpgFrontendCore.h +++ b/src/core/GpgFrontendCore.h @@ -30,23 +30,3 @@ // Qt #include <QtCore> - -// std -#include <cstdint> -#include <vector> - -// spdlog library configuration -#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE -#include <spdlog/spdlog.h> - -// logger fmt -#include "log/QtLoggerFmt.h" - -// gpgme library -#include <gpgme.h> - -// logbal includes or macroes -#include "GpgFrontend.h" - -// dll export macroes -#include "GpgFrontendCoreExport.h" diff --git a/src/core/function/CoreSignalStation.h b/src/core/function/CoreSignalStation.h index e0a11fa3..8827c803 100644 --- a/src/core/function/CoreSignalStation.h +++ b/src/core/function/CoreSignalStation.h @@ -28,7 +28,7 @@ #pragma once -#include "core/GpgFrontendCore.h" +#include "core/GpgFrontendCoreExport.h" namespace GpgFrontend { diff --git a/src/core/function/SecureMemoryAllocator.h b/src/core/function/SecureMemoryAllocator.h index e9f1c1c3..e86d54d6 100644 --- a/src/core/function/SecureMemoryAllocator.h +++ b/src/core/function/SecureMemoryAllocator.h @@ -28,9 +28,7 @@ #pragma once -#include <cstdint> -#include <memory> - +#include "core/GpgFrontendCoreExport.h" #include "core/utils/LogUtils.h" namespace GpgFrontend { diff --git a/src/core/function/basic/GpgFunctionObject.h b/src/core/function/basic/GpgFunctionObject.h index 1ea352b6..422af4a1 100644 --- a/src/core/function/basic/GpgFunctionObject.h +++ b/src/core/function/basic/GpgFunctionObject.h @@ -29,7 +29,6 @@ #pragma once #include <mutex> -#include <stdexcept> #include "core/GpgFrontendCoreExport.h" #include "core/function/basic/ChannelObject.h" diff --git a/src/core/function/gpg/GpgAdvancedOperator.cpp b/src/core/function/gpg/GpgAdvancedOperator.cpp index 3fc831ed..a99429ce 100644 --- a/src/core/function/gpg/GpgAdvancedOperator.cpp +++ b/src/core/function/gpg/GpgAdvancedOperator.cpp @@ -139,14 +139,17 @@ void GpgFrontend::GpgAdvancedOperator::ResetConfigures(OperationCallback cb) { } void GpgFrontend::GpgAdvancedOperator::StartGpgAgent(OperationCallback cb) { + if (!Module::IsModuleActivate(kGnuPGInfoGatheringModuleID)) { + cb(-1, TransferParams()); + return; + } + const auto gpg_agent_path = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering", - "gnupg.gpg_agent_path", QString{}); + kGnuPGInfoGatheringModuleID, "gnupg.gpg_agent_path", QString{}); GF_CORE_LOG_DEBUG("got gnupg agent path from rt: {}", gpg_agent_path); const auto home_path = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering", - "gnupg.home_path", QString{}); + kGnuPGInfoGatheringModuleID, "gnupg.home_path", QString{}); GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path); if (gpg_agent_path.isEmpty()) { @@ -164,14 +167,17 @@ void GpgFrontend::GpgAdvancedOperator::StartGpgAgent(OperationCallback cb) { } void GpgFrontend::GpgAdvancedOperator::StartDirmngr(OperationCallback cb) { + if (!Module::IsModuleActivate(kGnuPGInfoGatheringModuleID)) { + cb(-1, TransferParams()); + return; + } + const auto dirmngr_path = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering", - "gnupg.dirmngr_path", QString{}); + kGnuPGInfoGatheringModuleID, "gnupg.dirmngr_path", QString{}); GF_CORE_LOG_DEBUG("got gnupg dirmngr path from rt: {}", dirmngr_path); const auto home_path = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering", - "gnupg.home_path", QString{}); + kGnuPGInfoGatheringModuleID, "gnupg.home_path", QString{}); GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path); if (dirmngr_path.isEmpty()) { @@ -189,14 +195,17 @@ void GpgFrontend::GpgAdvancedOperator::StartDirmngr(OperationCallback cb) { } void GpgFrontend::GpgAdvancedOperator::StartKeyBoxd(OperationCallback cb) { + if (!Module::IsModuleActivate(kGnuPGInfoGatheringModuleID)) { + cb(-1, TransferParams()); + return; + } + const auto keyboxd_path = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering", - "gnupg.keyboxd_path", QString{}); + kGnuPGInfoGatheringModuleID, "gnupg.keyboxd_path", QString{}); GF_CORE_LOG_DEBUG("got gnupg keyboxd path from rt: {}", keyboxd_path); const auto home_path = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering", - "gnupg.home_path", QString{}); + kGnuPGInfoGatheringModuleID, "gnupg.home_path", QString{}); GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path); if (keyboxd_path.isEmpty()) { diff --git a/src/core/function/gpg/GpgContext.h b/src/core/function/gpg/GpgContext.h index d473a341..2a8f6fdd 100644 --- a/src/core/function/gpg/GpgContext.h +++ b/src/core/function/gpg/GpgContext.h @@ -28,6 +28,8 @@ #pragma once +#include <gpgme.h> + #include "core/function/SecureMemoryAllocator.h" #include "core/function/basic/GpgFunctionObject.h" diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp index e0ecb3ce..14d58a10 100644 --- a/src/core/function/gpg/GpgKeyOpera.cpp +++ b/src/core/function/gpg/GpgKeyOpera.cpp @@ -502,7 +502,7 @@ auto GpgKeyOpera::ModifyTOFUPolicy(const GpgKey& key, "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"}); GF_CORE_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version); - if (CompareSoftwareVersion(gnupg_version, "2.1.10") < 0) { + if (GFCompareSoftwareVersion(gnupg_version, "2.1.10") < 0) { GF_CORE_LOG_ERROR("operator not support"); return GPG_ERR_NOT_SUPPORTED; } diff --git a/src/ui/struct/CacheObject.cpp b/src/core/model/CacheObject.cpp index bd3b9818..37dedd92 100644 --- a/src/ui/struct/CacheObject.cpp +++ b/src/core/model/CacheObject.cpp @@ -30,7 +30,7 @@ #include "core/function/CacheManager.h" -namespace GpgFrontend::UI { +namespace GpgFrontend { CacheObject::CacheObject(QString cache_name) : cache_name_(std::move(cache_name)) { @@ -42,4 +42,4 @@ CacheObject::~CacheObject() { CacheManager::GetInstance().SaveDurableCache(cache_name_, *this); } -} // namespace GpgFrontend::UI
\ No newline at end of file +} // namespace GpgFrontend
\ No newline at end of file diff --git a/src/ui/struct/CacheObject.h b/src/core/model/CacheObject.h index ae8aa056..3cfa8083 100644 --- a/src/ui/struct/CacheObject.h +++ b/src/core/model/CacheObject.h @@ -28,9 +28,11 @@ #pragma once -namespace GpgFrontend::UI { +#include "core/GpgFrontendCoreExport.h" -class CacheObject : public QJsonDocument { +namespace GpgFrontend { + +class GPGFRONTEND_CORE_EXPORT CacheObject : public QJsonDocument { public: /** * @brief Construct a new Cache Object object @@ -49,4 +51,4 @@ class CacheObject : public QJsonDocument { QString cache_name_; ///< }; -} // namespace GpgFrontend::UI
\ No newline at end of file +} // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/model/GpgData.h b/src/core/model/GpgData.h index 358ebd19..eb1d7621 100644 --- a/src/core/model/GpgData.h +++ b/src/core/model/GpgData.h @@ -28,6 +28,8 @@ #pragma once +#include <gpgme.h> + #include "core/GpgFrontendCoreExport.h" #include "core/model/GFBuffer.h" #include "core/typedef/CoreTypedef.h" diff --git a/src/core/model/GpgGenKeyInfo.h b/src/core/model/GpgGenKeyInfo.h index 166c6b0f..65a7d03e 100644 --- a/src/core/model/GpgGenKeyInfo.h +++ b/src/core/model/GpgGenKeyInfo.h @@ -28,6 +28,8 @@ #pragma once +#include "core/GpgFrontendCoreExport.h" + namespace GpgFrontend { class GPGFRONTEND_CORE_EXPORT GenKeyInfo { diff --git a/src/core/model/GpgGenerateKeyResult.h b/src/core/model/GpgGenerateKeyResult.h index f312d415..dfd92ae1 100644 --- a/src/core/model/GpgGenerateKeyResult.h +++ b/src/core/model/GpgGenerateKeyResult.h @@ -28,6 +28,8 @@ #pragma once +#include <gpgme.h> + #include "core/GpgFrontendCore.h" #include "core/GpgFrontendCoreExport.h" diff --git a/src/core/model/GpgImportInformation.h b/src/core/model/GpgImportInformation.h index 5f85a338..cbe5a265 100644 --- a/src/core/model/GpgImportInformation.h +++ b/src/core/model/GpgImportInformation.h @@ -28,6 +28,10 @@ #pragma once +#include <gpgme.h> + +#include "core/GpgFrontendCoreExport.h" + namespace GpgFrontend { /** diff --git a/src/core/model/GpgPassphraseContext.cpp b/src/core/model/GpgPassphraseContext.cpp index 5df3f5a8..0156c04d 100644 --- a/src/core/model/GpgPassphraseContext.cpp +++ b/src/core/model/GpgPassphraseContext.cpp @@ -28,6 +28,7 @@ #include "GpgPassphraseContext.h" + namespace GpgFrontend { GpgPassphraseContext::GpgPassphraseContext(const QString& uids_info, diff --git a/src/core/model/GpgPassphraseContext.h b/src/core/model/GpgPassphraseContext.h index 2bc1ac75..1db36f62 100644 --- a/src/core/model/GpgPassphraseContext.h +++ b/src/core/model/GpgPassphraseContext.h @@ -30,6 +30,8 @@ #pragma once +#include "core/GpgFrontendCoreExport.h" + namespace GpgFrontend { class GPGFRONTEND_CORE_EXPORT GpgPassphraseContext : public QObject { diff --git a/src/core/model/GpgSubKey.h b/src/core/model/GpgSubKey.h index 83d75e2d..8257eab8 100644 --- a/src/core/model/GpgSubKey.h +++ b/src/core/model/GpgSubKey.h @@ -28,6 +28,10 @@ #pragma once +#include <gpgme.h> + +#include "core/GpgFrontendCoreExport.h" + namespace GpgFrontend { /** diff --git a/src/core/model/GpgTOFUInfo.h b/src/core/model/GpgTOFUInfo.h index ec4c49b7..5e8d83d4 100644 --- a/src/core/model/GpgTOFUInfo.h +++ b/src/core/model/GpgTOFUInfo.h @@ -28,6 +28,10 @@ #pragma once +#include <gpgme.h> + +#include "core/GpgFrontendCoreExport.h" + namespace GpgFrontend { /** * @brief diff --git a/src/ui/struct/SettingsObject.cpp b/src/core/model/SettingsObject.cpp index cc5e85bf..09824f12 100644 --- a/src/ui/struct/SettingsObject.cpp +++ b/src/core/model/SettingsObject.cpp @@ -30,25 +30,25 @@ #include "core/function/DataObjectOperator.h" -namespace GpgFrontend::UI { +namespace GpgFrontend { SettingsObject::SettingsObject(QString settings_name) : settings_name_(std::move(settings_name)) { try { - GF_UI_LOG_DEBUG("loading settings from: {}", this->settings_name_); + GF_CORE_LOG_DEBUG("loading settings from: {}", this->settings_name_); auto json_optional = DataObjectOperator::GetInstance().GetDataObject(settings_name_); if (json_optional.has_value() && json_optional->isObject()) { - GF_UI_LOG_DEBUG("settings object: {} loaded.", settings_name_); + GF_CORE_LOG_DEBUG("settings object: {} loaded.", settings_name_); QJsonObject::operator=(json_optional.value().object()); } else { - GF_UI_LOG_DEBUG("settings object: {} not found.", settings_name_); + GF_CORE_LOG_DEBUG("settings object: {} not found.", settings_name_); QJsonObject::operator=({}); } } catch (std::exception& e) { - GF_UI_LOG_ERROR("load setting object error: {}", e.what()); + GF_CORE_LOG_ERROR("load setting object error: {}", e.what()); } } @@ -66,4 +66,4 @@ void SettingsObject::Store(const QJsonObject& json) { auto* parent = (static_cast<QJsonObject*>(this)); *parent = json; } -} // namespace GpgFrontend::UI
\ No newline at end of file +} // namespace GpgFrontend
\ No newline at end of file diff --git a/src/ui/struct/SettingsObject.h b/src/core/model/SettingsObject.h index a9e5819f..4b52f31d 100644 --- a/src/ui/struct/SettingsObject.h +++ b/src/core/model/SettingsObject.h @@ -28,14 +28,16 @@ #pragma once -namespace GpgFrontend::UI { +#include "core/GpgFrontendCoreExport.h" + +namespace GpgFrontend { /** * @brief The SettingsObject class * This class is used to store data for the application securely. * */ -class SettingsObject : public QJsonObject { +class GPGFRONTEND_CORE_EXPORT SettingsObject : public QJsonObject { public: /** * @brief Construct a new Settings Object object @@ -66,4 +68,4 @@ class SettingsObject : public QJsonObject { private: QString settings_name_; ///< }; -} // namespace GpgFrontend::UI +} // namespace GpgFrontend diff --git a/src/core/module/Event.cpp b/src/core/module/Event.cpp index fab26453..0285ae6c 100644 --- a/src/core/module/Event.cpp +++ b/src/core/module/Event.cpp @@ -28,6 +28,8 @@ #include "Event.h" +#include "core/utils/CommonUtils.h" + namespace GpgFrontend::Module { class Event::Impl { @@ -67,7 +69,11 @@ class Event::Impl { auto GetIdentifier() -> EventIdentifier { return event_identifier_; } - void AddParameter(const QString& key, const ParameterValue& value) { + auto GetTriggerIdentifier() -> EventTriggerIdentifier { + return trigger_uuid_; + } + + void AddParameter(const QString& key, const QString& value) { data_[key] = value; } @@ -95,9 +101,37 @@ class Event::Impl { } } + auto ToModuleEvent() -> GFModuleEvent* { + auto* event = + static_cast<GFModuleEvent*>(SecureMalloc(sizeof(GFModuleEvent))); + + event->id = GFStrDup(event_identifier_); + event->triggger_id = GFStrDup(trigger_uuid_); + + GFModuleEventParam* l_param = nullptr; + GFModuleEventParam* p_param; + + int index = 0; + for (const auto& data : data_) { + p_param = static_cast<GFModuleEventParam*>( + SecureMalloc(sizeof(GFModuleEventParam))); + if (index++ == 0) event->params = p_param; + + p_param->name = GFStrDup(data.first); + p_param->value = GFStrDup(data.second); + p_param->next = nullptr; + + l_param->next = p_param; + l_param = p_param; + } + + return event; + } + private: EventIdentifier event_identifier_; - std::map<QString, ParameterValue> data_; + EventTriggerIdentifier trigger_uuid_ = QUuid::createUuid().toString(); + std::map<QString, QString> data_; EventCallback callback_; QThread* callback_thread_ = nullptr; ///< }; @@ -128,7 +162,11 @@ auto Event::Event::GetIdentifier() -> EventIdentifier { return p_->GetIdentifier(); } -void Event::AddParameter(const QString& key, const ParameterValue& value) { +auto Event::Event::GetTriggerIdentifier() -> EventTriggerIdentifier { + return p_->GetTriggerIdentifier(); +} + +void Event::AddParameter(const QString& key, const QString& value) { p_->AddParameter(key, value); } @@ -136,4 +174,6 @@ void Event::ExecuteCallback(ListenerIdentifier l_id, DataObjectPtr d_o) { p_->ExecuteCallback(std::move(l_id), d_o); } +auto Event::ToModuleEvent() -> GFModuleEvent* { return p_->ToModuleEvent(); } + } // namespace GpgFrontend::Module
\ No newline at end of file diff --git a/src/core/module/Event.h b/src/core/module/Event.h index 92268216..8983d560 100644 --- a/src/core/module/Event.h +++ b/src/core/module/Event.h @@ -34,6 +34,7 @@ #include "core/GpgFrontendCore.h" #include "core/model/DataObject.h" +#include "module/sdk/GFSDKModule.h" namespace GpgFrontend::Module { @@ -41,6 +42,7 @@ class Event; using EventRefrernce = std::shared_ptr<Event>; using EventIdentifier = QString; +using EventTriggerIdentifier = QString; using Evnets = std::vector<Event>; class GPGFRONTEND_CORE_EXPORT Event { @@ -52,7 +54,7 @@ class GPGFRONTEND_CORE_EXPORT Event { std::function<void(EventIdentifier, ListenerIdentifier, DataObjectPtr)>; struct ParameterInitializer { QString key; - ParameterValue value; + QString value; }; explicit Event(const QString&, @@ -75,10 +77,14 @@ class GPGFRONTEND_CORE_EXPORT Event { auto GetIdentifier() -> EventIdentifier; - void AddParameter(const QString& key, const ParameterValue& value); + auto GetTriggerIdentifier() -> EventTriggerIdentifier; + + void AddParameter(const QString& key, const QString& value); void ExecuteCallback(ListenerIdentifier, DataObjectPtr); + auto ToModuleEvent() -> GFModuleEvent*; + private: class Impl; SecureUniquePtr<Impl> p_; diff --git a/src/core/module/GlobalModuleContext.cpp b/src/core/module/GlobalModuleContext.cpp index 9bc4f06b..1744ba72 100644 --- a/src/core/module/GlobalModuleContext.cpp +++ b/src/core/module/GlobalModuleContext.cpp @@ -31,6 +31,7 @@ #include <set> #include <unordered_map> #include <unordered_set> +#include <utility> #include "core/module/Event.h" #include "core/module/Module.h" @@ -49,6 +50,18 @@ class GlobalModuleContext::Impl { acquired_channel_.insert(kGpgFrontendNonAsciiChannel); } + auto SearchModule(ModuleIdentifier module_id) -> ModulePtr { + // Search for the module in the register table. + auto module_info_opt = search_module_register_table(module_id); + if (!module_info_opt.has_value()) { + GF_CORE_LOG_ERROR("cannot find module id {} at register table", + module_id); + return nullptr; + } + + return module_info_opt.value()->module; + } + auto GetChannel(ModuleRawPtr module) -> int { // Search for the module in the register table. auto module_info_opt = @@ -97,7 +110,7 @@ class GlobalModuleContext::Impl { return false; } - if (!module->Register()) { + if (module->Register() != 0) { GF_CORE_LOG_ERROR("register module {} failed", module->GetModuleIdentifier()); return false; @@ -158,6 +171,15 @@ class GlobalModuleContext::Impl { auto ListenEvent(ModuleIdentifier module_id, EventIdentifier event) -> bool { GF_CORE_LOG_DEBUG("module: {} is attempting to listen to event {}", module_id, event); + + // module -> event + auto module_info_opt = search_module_register_table(module_id); + if (!module_info_opt.has_value()) { + GF_CORE_LOG_ERROR("cannot find module id {} at register table", + module_id); + return false; + } + // Check if the event exists, if not, create it. auto met_it = module_events_table_.find(event); if (met_it == module_events_table_.end()) { @@ -166,6 +188,8 @@ class GlobalModuleContext::Impl { GF_CORE_LOG_DEBUG("new event {} of module system created", event); } + module_info_opt.value()->listening_event_ids.push_back(event); + auto& listeners_set = met_it->second; // Add the listener (module) to the event. auto listener_it = listeners_set.find(module_id); @@ -176,7 +200,7 @@ class GlobalModuleContext::Impl { } auto DeactivateModule(ModuleIdentifier module_id) -> bool { - // Search for the module in the register table. + // search for the module in the register table. auto module_info_opt = search_module_register_table(module_id); if (!module_info_opt.has_value()) { GF_CORE_LOG_ERROR("cannot find module id {} at register table", @@ -185,8 +209,16 @@ class GlobalModuleContext::Impl { } auto module_info = module_info_opt.value(); - // Activate the module if it is not already deactive. - if (!module_info->activate && module_info->module->Deactive()) { + // activate the module if it is not already deactive. + if (module_info->activate && (module_info->module->Deactive() == 0)) { + for (const auto& event_ids : module_info->listening_event_ids) { + auto& modules = module_events_table_[event_ids]; + if (auto it = modules.find(module_id); it != modules.end()) { + modules.erase(it); + } + } + + module_info->listening_event_ids.clear(); module_info->activate = false; } @@ -222,6 +254,9 @@ class GlobalModuleContext::Impl { GF_CORE_LOG_DEBUG("event {}'s current listeners size: {}", event->GetIdentifier(), listeners_set.size()); + // register trigger id index table + module_on_triggering_events_table_[event->GetTriggerIdentifier()] = event; + // Iterate through each listener and execute the corresponding module for (const auto& listener_module_id : listeners_set) { // Search for the module's information in the registration table @@ -272,16 +307,43 @@ class GlobalModuleContext::Impl { return true; } - auto IsModuleActivated(const ModuleIdentifier& m_id) const -> bool { + auto SearchEvent(const EventTriggerIdentifier& trigger_id) + -> std::optional<EventRefrernce> { + if (module_on_triggering_events_table_.find(trigger_id) != + module_on_triggering_events_table_.end()) { + return module_on_triggering_events_table_[trigger_id]; + } + return {}; + } + + [[nodiscard]] auto IsModuleActivated(const ModuleIdentifier& m_id) const + -> bool { auto m = search_module_register_table(m_id); return m.has_value() && m->get()->activate; } + auto ListAllRegisteredModuleID() -> QList<ModuleIdentifier> { + QList<ModuleIdentifier> module_ids; + for (const auto& module : module_register_table_) { + module_ids.append(module.first); + } + module_ids.sort(); + return module_ids; + } + + auto GetModuleListening(const ModuleIdentifier& module_id) + -> QList<EventIdentifier> { + auto module_info = search_module_register_table(module_id); + if (!module_info.has_value()) return {}; + return module_info->get()->listening_event_ids; + } + private: struct ModuleRegisterInfo { int channel; ModulePtr module; bool activate; + QList<QString> listening_event_ids; }; using ModuleRegisterInfoPtr = std::shared_ptr<ModuleRegisterInfo>; @@ -290,6 +352,8 @@ class GlobalModuleContext::Impl { module_register_table_; std::map<EventIdentifier, std::unordered_set<ModuleIdentifier>> module_events_table_; + std::map<EventTriggerIdentifier, EventRefrernce> + module_on_triggering_events_table_; std::set<int> acquired_channel_; TaskRunnerPtr default_task_runner_; @@ -307,7 +371,8 @@ class GlobalModuleContext::Impl { } // Function to search for a module in the register table. - auto search_module_register_table(const ModuleIdentifier& identifier) const + [[nodiscard]] auto search_module_register_table( + const ModuleIdentifier& identifier) const -> std::optional<ModuleRegisterInfoPtr> { auto mrt_it = module_register_table_.find(identifier); if (mrt_it == module_register_table_.end()) { @@ -323,6 +388,11 @@ GlobalModuleContext::GlobalModuleContext() GlobalModuleContext::~GlobalModuleContext() = default; +auto GlobalModuleContext::SearchModule(ModuleIdentifier module_id) + -> ModulePtr { + return p_->SearchModule(std::move(module_id)); +} + // Function to get the task runner associated with a module. auto GlobalModuleContext::GetTaskRunner(ModuleRawPtr module) -> std::optional<TaskRunnerPtr> { @@ -342,7 +412,7 @@ auto GlobalModuleContext::GetGlobalTaskRunner() } auto GlobalModuleContext::RegisterModule(ModulePtr module) -> bool { - return p_->RegisterModule(std::move(module)); + return p_->RegisterModule(module); } auto GlobalModuleContext::ActiveModule(ModuleIdentifier module_id) -> bool { @@ -359,7 +429,12 @@ auto GlobalModuleContext::DeactivateModule(ModuleIdentifier module_id) -> bool { } auto GlobalModuleContext::TriggerEvent(EventRefrernce event) -> bool { - return p_->TriggerEvent(std::move(event)); + return p_->TriggerEvent(event); +} + +auto GlobalModuleContext::SearchEvent(EventTriggerIdentifier trigger_id) + -> std::optional<EventRefrernce> { + return p_->SearchEvent(trigger_id); } auto GlobalModuleContext::GetChannel(ModuleRawPtr module) -> int { @@ -371,7 +446,16 @@ auto GlobalModuleContext::GetDefaultChannel(ModuleRawPtr channel) -> int { } auto GlobalModuleContext::IsModuleActivated(ModuleIdentifier m_id) -> bool { - return p_->IsModuleActivated(std::move(m_id)); + return p_->IsModuleActivated(m_id); +} + +auto GlobalModuleContext::ListAllRegisteredModuleID() + -> QList<ModuleIdentifier> { + return p_->ListAllRegisteredModuleID(); } +auto GlobalModuleContext::GetModuleListening(ModuleIdentifier module_id) + -> QList<EventIdentifier> { + return p_->GetModuleListening(module_id); +} } // namespace GpgFrontend::Module diff --git a/src/core/module/GlobalModuleContext.h b/src/core/module/GlobalModuleContext.h index 1c971bb5..ae4300af 100644 --- a/src/core/module/GlobalModuleContext.h +++ b/src/core/module/GlobalModuleContext.h @@ -58,6 +58,8 @@ class GPGFRONTEND_CORE_EXPORT GlobalModuleContext : public QObject { ~GlobalModuleContext() override; + auto SearchModule(ModuleIdentifier) -> ModulePtr; + auto GetChannel(ModuleRawPtr) -> int; static auto GetDefaultChannel(ModuleRawPtr) -> int; @@ -78,8 +80,14 @@ class GPGFRONTEND_CORE_EXPORT GlobalModuleContext : public QObject { auto TriggerEvent(EventRefrernce) -> bool; + auto SearchEvent(EventTriggerIdentifier) -> std::optional<EventRefrernce>; + + auto GetModuleListening(ModuleIdentifier) -> QList<EventIdentifier>; + auto IsModuleActivated(ModuleIdentifier) -> bool; + auto ListAllRegisteredModuleID() -> QList<ModuleIdentifier>; + private: class Impl; SecureUniquePtr<Impl> p_; diff --git a/src/core/module/GlobalRegisterTable.cpp b/src/core/module/GlobalRegisterTable.cpp index c16eba37..006118b3 100644 --- a/src/core/module/GlobalRegisterTable.cpp +++ b/src/core/module/GlobalRegisterTable.cpp @@ -31,10 +31,10 @@ #include <any> #include <optional> #include <shared_mutex> -#include <sstream> -#include <unordered_map> +#include <utility> #include <vector> +#include "GlobalRegisterTableTreeModel.h" #include "function/SecureMemoryAllocator.h" #include "utils/MemoryUtils.h" @@ -43,33 +43,45 @@ namespace GpgFrontend::Module { class GlobalRegisterTable::Impl { public: struct RTNode { - std::optional<std::any> value = std::nullopt; - std::unordered_map<QString, SecureUniquePtr<RTNode>> children; + QString name; + QString type = "NODE"; int version = 0; - const std::type_info* type = nullptr; + const std::type_info* value_type = nullptr; + std::optional<std::any> value = std::nullopt; + QMap<QString, QSharedPointer<RTNode>> children; + QWeakPointer<RTNode> parent; + + explicit RTNode(QString name, const QSharedPointer<RTNode>& parent) + : name(std::move(name)), parent(parent) {} }; - explicit Impl(GlobalRegisterTable* parent) : parent_(parent) {} + using RTNodePtr = QSharedPointer<RTNode>; + + explicit Impl(GlobalRegisterTable* parent) + : parent_(parent), + root_node_(SecureCreateQSharedObject<RTNode>("", nullptr)) {} auto PublishKV(const Namespace& n, const Key& k, std::any v) -> bool { - QStringList const segments = k.split('.'); + QStringList const segments = (n + "." + k).split('.'); int version = 0; { std::unique_lock lock(lock_); - auto& root_rt_node = - global_register_table_.emplace(n, SecureCreateUniqueObject<RTNode>()) - .first->second; - RTNode* current = root_rt_node.get(); + auto current = root_node_; for (const QString& segment : segments) { - current = current->children - .emplace(segment, SecureCreateUniqueObject<RTNode>()) - .first->second.get(); + auto it = current->children.find(segment); + if (it == current->children.end()) { + it = current->children.insert( + segment, SecureCreateQSharedObject<RTNode>(segment, current)); + } + current = it.value(); } + current->name = segments.back(); + current->type = "LEAF"; current->value = v; - current->type = &v.type(); + current->value_type = &v.type(); version = ++current->version; } @@ -78,19 +90,17 @@ class GlobalRegisterTable::Impl { } auto LookupKV(const Namespace& n, const Key& k) -> std::optional<std::any> { - QStringList const segments = k.split('.'); + QStringList const segments = (n + "." + k).split('.'); std::optional<std::any> rtn = std::nullopt; { std::shared_lock const lock(lock_); - auto it = global_register_table_.find(n); - if (it == global_register_table_.end()) return std::nullopt; - RTNode* current = it->second.get(); + auto current = root_node_; for (const QString& segment : segments) { auto it = current->children.find(segment); if (it == current->children.end()) return std::nullopt; - current = it->second.get(); + current = it.value(); } rtn = current->value; } @@ -98,24 +108,20 @@ class GlobalRegisterTable::Impl { } auto ListChildKeys(const Namespace& n, const Key& k) -> std::vector<Key> { - QStringList const segments = k.split('.'); + QStringList const segments = (n + "." + k).split('.'); std::vector<Key> rtn; { std::shared_lock lock(lock_); - auto it = global_register_table_.find(n); - if (it == global_register_table_.end()) return {}; - RTNode* current = it->second.get(); + auto current = root_node_; for (const QString& segment : segments) { auto it = current->children.find(segment); if (it == current->children.end()) return {}; - current = it->second.get(); + current = it.value(); } - for (auto& it : current->children) { - rtn.emplace_back(it.first); - } + for (auto& key : current->children.keys()) rtn.emplace_back(key); } return rtn; } @@ -132,12 +138,149 @@ class GlobalRegisterTable::Impl { }) == nullptr; } + auto RootRTNode() -> RTNode* { return root_node_.get(); } + private: - using Table = std::map<Namespace, SecureUniquePtr<RTNode>>; std::shared_mutex lock_; GlobalRegisterTable* parent_; - Table global_register_table_; + RTNodePtr root_node_; +}; + +class GlobalRegisterTableTreeModel::Impl { + public: + using RTNode = GlobalRegisterTable::Impl::RTNode; + + Impl(GlobalRegisterTableTreeModel* parent, GlobalRegisterTable::Impl* grt) + : parent_(parent), root_node_(grt->RootRTNode()) {} + + [[nodiscard]] auto RowCount(const QModelIndex& parent) const -> int { + auto* parent_node = !parent.isValid() + ? root_node_.get() + : static_cast<RTNode*>(parent.internalPointer()); + return parent_node->children.size(); + } + + [[nodiscard]] auto ColumnCount(const QModelIndex& parent) const -> int { + return 4; + } + + [[nodiscard]] auto Data(const QModelIndex& index, int role) const + -> QVariant { + if (!index.isValid()) return {}; + + if (role == Qt::DisplayRole) { + auto* node = static_cast<RTNode*>(index.internalPointer()); + switch (index.column()) { + case 0: + return node->name; + case 1: + return node->type; + case 2: + return QString(node->value && node->value.has_value() + ? node->value->type().name() + : ""); + case 3: + return Any2QVariant(node->value); + default: + return {}; + } + } + return {}; + } + + static auto Any2QVariant(std::optional<std::any> op) -> QVariant { + if (!op) return "<EMPTY>"; + + auto& o = op.value(); + if (o.type() == typeid(QString)) { + return QVariant::fromValue(std::any_cast<QString>(o)); + } + if (o.type() == typeid(std::string)) { + return QVariant::fromValue( + QString::fromStdString(std::any_cast<std::string>(o))); + } + if (o.type() == typeid(int)) { + return QVariant::fromValue(std::any_cast<int>(o)); + } + if (o.type() == typeid(long)) { + return QVariant::fromValue( + static_cast<qlonglong>(std::any_cast<long>(o))); + } + if (o.type() == typeid(long long)) { + return QVariant::fromValue(std::any_cast<long long>(o)); + } + if (o.type() == typeid(unsigned)) { + return QVariant::fromValue(std::any_cast<unsigned>(o)); + } + if (o.type() == typeid(unsigned long)) { + return QVariant::fromValue( + static_cast<qulonglong>(std::any_cast<unsigned long>(o))); + } + if (o.type() == typeid(unsigned long long)) { + return QVariant::fromValue(std::any_cast<unsigned long long>(o)); + } + if (o.type() == typeid(float)) { + return QVariant::fromValue(std::any_cast<float>(o)); + } + if (o.type() == typeid(double)) { + return QVariant::fromValue(std::any_cast<double>(o)); + } + if (o.type() == typeid(bool)) { + return QVariant::fromValue(std::any_cast<bool>(o)); + } + return "<UNSUPPORTED>"; + } + + [[nodiscard]] auto Index(int row, int column, const QModelIndex& parent) const + -> QModelIndex { + if (!parent_->hasIndex(row, column, parent)) return {}; + + auto* parent_node = !parent.isValid() + ? root_node_.get() + : static_cast<RTNode*>(parent.internalPointer()); + auto key = parent_node->children.keys().at(row); + auto child_node = parent_node->children.value(key); + return parent_->createIndex(row, column, child_node.get()); + } + + [[nodiscard]] auto Parent(const QModelIndex& index) const -> QModelIndex { + if (!index.isValid()) return {}; + + auto* child_node = static_cast<RTNode*>(index.internalPointer()); + auto parent_node = child_node->parent.lock(); + + if (!parent_node || parent_node == root_node_) return {}; + + int row = + parent_node->parent.lock()->children.keys().indexOf(parent_node->name); + return parent_->createIndex(row, 0, parent_node.data()); + } + + [[nodiscard]] static auto HeaderData(int section, Qt::Orientation orientation, + int role) -> QVariant { + if (role != Qt::DisplayRole) return QVariant(); + + if (orientation == Qt::Horizontal) { + switch (section) { + case 0: + return QString("Key"); + case 1: + return QString("Type"); + case 2: + return QString("Value Type"); + case 3: + return QString("Value"); + default: + return {}; + } + } + return {}; + } + + private: + GlobalRegisterTableTreeModel* parent_; + GlobalRegisterTable::Impl::RTNodePtr root_node_; }; GlobalRegisterTable::GlobalRegisterTable() @@ -164,4 +307,39 @@ auto GlobalRegisterTable::ListChildKeys(Namespace n, Key k) return p_->ListChildKeys(n, k); } +GlobalRegisterTableTreeModel::GlobalRegisterTableTreeModel( + GlobalRegisterTable* grt) + : p_(SecureCreateUniqueObject<Impl>(this, grt->p_.get())) {} + +auto GlobalRegisterTableTreeModel::rowCount(const QModelIndex& parent) const + -> int { + return p_->RowCount(parent); +} + +auto GlobalRegisterTableTreeModel::columnCount(const QModelIndex& parent) const + -> int { + return p_->ColumnCount(parent); +} + +auto GlobalRegisterTableTreeModel::data(const QModelIndex& index, + int role) const -> QVariant { + return p_->Data(index, role); +} + +auto GlobalRegisterTableTreeModel::index(int row, int column, + const QModelIndex& parent) const + -> QModelIndex { + return p_->Index(row, column, parent); +} + +auto GlobalRegisterTableTreeModel::parent(const QModelIndex& index) const + -> QModelIndex { + return p_->Parent(index); +} + +auto GlobalRegisterTableTreeModel::headerData(int section, + Qt::Orientation orientation, + int role) const -> QVariant { + return p_->HeaderData(section, orientation, role); +} } // namespace GpgFrontend::Module
\ No newline at end of file diff --git a/src/core/module/GlobalRegisterTable.h b/src/core/module/GlobalRegisterTable.h index db68c888..1d3e43da 100644 --- a/src/core/module/GlobalRegisterTable.h +++ b/src/core/module/GlobalRegisterTable.h @@ -32,7 +32,7 @@ #include <functional> #include <optional> -#include "function/SecureMemoryAllocator.h" +#include "core/function/SecureMemoryAllocator.h" namespace GpgFrontend::Module { @@ -43,6 +43,8 @@ using LPCallback = std::function<void(Namespace, Key, int, std::any)>; class GlobalRegisterTable : public QObject { Q_OBJECT public: + friend class GlobalRegisterTableTreeModel; + GlobalRegisterTable(); ~GlobalRegisterTable() override; diff --git a/src/core/module/GlobalRegisterTableTreeModel.h b/src/core/module/GlobalRegisterTableTreeModel.h new file mode 100644 index 00000000..fe4242a2 --- /dev/null +++ b/src/core/module/GlobalRegisterTableTreeModel.h @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include "core/module/GlobalRegisterTable.h" + +namespace GpgFrontend::Module { +class GPGFRONTEND_CORE_EXPORT GlobalRegisterTableTreeModel + : public QAbstractItemModel { + public: + explicit GlobalRegisterTableTreeModel(GlobalRegisterTable *grt); + + [[nodiscard]] auto rowCount(const QModelIndex &parent) const -> int override; + + [[nodiscard]] auto columnCount(const QModelIndex &parent) const + -> int override; + + [[nodiscard]] auto data(const QModelIndex &index, int role) const + -> QVariant override; + + [[nodiscard]] auto index(int row, int column, const QModelIndex &parent) const + -> QModelIndex override; + + [[nodiscard]] auto parent(const QModelIndex &index) const + -> QModelIndex override; + + [[nodiscard]] auto headerData(int section, Qt::Orientation orientation, + int role) const -> QVariant override; + + private: + class Impl; + SecureUniquePtr<Impl> p_; +}; + +}; // namespace GpgFrontend::Module
\ No newline at end of file diff --git a/src/core/module/Module.cpp b/src/core/module/Module.cpp index 9076dc2c..39f4f4a9 100644 --- a/src/core/module/Module.cpp +++ b/src/core/module/Module.cpp @@ -29,6 +29,10 @@ #include "Module.h" #include "core/module/GlobalModuleContext.h" +#include "core/utils/CommonUtils.h" +#include "core/utils/IOUtils.h" +#include "module/sdk/GFSDKModule.h" +#include "utils/BuildInfoUtils.h" namespace GpgFrontend::Module { @@ -43,7 +47,127 @@ class Module::Impl { : m_ptr_(m_ptr), identifier_(std::move(id)), version_(std::move(version)), - meta_data_(std::move(meta_data)) {} + meta_data_(std::move(meta_data)), + good_(true) {} + + Impl(ModuleRawPtr m_ptr, QLibrary& module_library) + : m_ptr_(m_ptr), + module_hash_(CalculateBinaryChacksum(module_library.fileName())), + module_library_path_(module_library.fileName()), + good_(false) { + for (auto& required_symbol : module_required_symbols_) { + *required_symbol.pointer = + reinterpret_cast<void*>(module_library.resolve(required_symbol.name)); + if (*required_symbol.pointer == nullptr) { + GF_CORE_LOG_WARN( + "illegal module: {}, reason: cannot load symbol: {}, abort...", + module_library.fileName(), required_symbol.name); + return; + } + } + + identifier_ = GFUnStrDup(get_id_api_()); + version_ = GFUnStrDup(get_version_api_()); + gf_sdk_ver_ = GFUnStrDup(get_sdk_ver_api_()); + qt_env_ver_ = GFUnStrDup(get_qt_ver_api_()); + + if (!module_identifier_regex_exp_.match(identifier_).hasMatch()) { + GF_CORE_LOG_WARN( + "illegal module: {}, reasson invalid module id, abort...", + identifier_); + return; + } + + if (!module_version_regex_exp_.match(version_).hasMatch()) { + GF_CORE_LOG_WARN( + "illegal module: {}, reasson invalid version: {}, abort...", + identifier_, version_); + return; + } + + if (!module_version_regex_exp_.match(gf_sdk_ver_).hasMatch()) { + GF_CORE_LOG_WARN( + "illegal module: {}, reasson invalid sdk version: {}, abort...", + identifier_, gf_sdk_ver_); + return; + } + + if (GFCompareSoftwareVersion(gf_sdk_ver_, GetProjectVersion()) > 0) { + GF_CORE_LOG_WARN( + "uncompatible module: {}, sdk version: {} greater than " + "current sdk version: {}, abort...", + identifier_, gf_sdk_ver_, GetProjectVersion()); + return; + } + + auto qt_env_ver_regex_match = module_version_regex_exp_.match(qt_env_ver_); + if (!qt_env_ver_regex_match.hasMatch()) { + GF_CORE_LOG_WARN( + "illegal module: {}, reasson invalid qt env version: {}, abort...", + identifier_, qt_env_ver_); + return; + } + + auto qt_env_ver_major = qt_env_ver_regex_match.captured(1); + auto qt_env_ver_minor = qt_env_ver_regex_match.captured(2); + + if (qt_env_ver_major != QString::number(QT_VERSION_MAJOR) + "." || + qt_env_ver_minor != QString::number(QT_VERSION_MINOR) + ".") { + GF_CORE_LOG_WARN( + "uncompatible module: {}, qt version: {} is not binary uncompatible " + "with application's qt env version: {}, abort...", + identifier_, qt_env_ver_, QString::fromUtf8(QT_VERSION_STR)); + return; + } + + GF_CORE_LOG_INFO( + "module loaded, id: {}, verison: {}, " + "sdk version: {}, qt env version: {}, hash: {}, path: {}", + identifier_, version_, gf_sdk_ver_, qt_env_ver_, module_hash_, + module_library_path_); + + ::GFModuleMetaData* p_meta_data = get_metadata_api_(); + ::GFModuleMetaData* l_meta_data; + + while (p_meta_data != nullptr) { + meta_data_[QString::fromUtf8(p_meta_data->key)] = + QString::fromUtf8(p_meta_data->value); + l_meta_data = p_meta_data; + p_meta_data = p_meta_data->next; + SecureFree(l_meta_data); + } + + good_ = true; + } + + [[nodiscard]] auto IsGood() const -> bool { return good_; } + + auto Register() -> int { + if (good_ && register_api_ != nullptr) return register_api_(); + return -1; + } + + auto Active() -> int { + if (good_ && activate_api_ != nullptr) return activate_api_(); + return -1; + } + + auto Exec(const EventRefrernce& event) -> int { + if (good_ && execute_api_ != nullptr) { + return execute_api_(event->ToModuleEvent()); + } + return -1; + } + + auto Deactive() -> int { + if (good_ && deactivate_api_ != nullptr) return deactivate_api_(); + return -1; + } + + auto UnRegister() -> int { + if (good_ && unregister_api_ != nullptr) return unregister_api_(); + return -1; + } auto GetChannel() -> int { return get_gpc()->GetChannel(m_ptr_); } @@ -63,14 +187,77 @@ class Module::Impl { return identifier_; } + [[nodiscard]] auto GetModuleVersion() const -> ModuleVersion { + return version_; + } + + [[nodiscard]] auto GetModuleSDKVersion() const -> QString { + return gf_sdk_ver_; + } + + [[nodiscard]] auto GetModuleQtEnvVersion() const -> QString { + return qt_env_ver_; + } + + [[nodiscard]] auto GetModuleMetaData() const -> ModuleMetaData { + return meta_data_; + } + + [[nodiscard]] auto GetModulePath() const -> QString { + return module_library_path_; + } + + [[nodiscard]] auto GetModuleHash() const -> QString { return module_hash_; } + void SetGPC(GlobalModuleContext* gpc) { gpc_ = gpc; } private: GlobalModuleContext* gpc_{}; Module* m_ptr_; - const ModuleIdentifier identifier_; - const ModuleVersion version_; - const ModuleMetaData meta_data_; + ModuleIdentifier identifier_; + ModuleVersion version_; + ModuleMetaData meta_data_; + QString module_hash_; + QString module_library_path_; + QString gf_sdk_ver_; + QString qt_env_ver_; + + QRegularExpression module_identifier_regex_exp_ = QRegularExpression( + R"(^([A-Za-z]{1}[A-Za-z\d_]*\.)+[A-Za-z][A-Za-z\d_]*$)"); + QRegularExpression module_version_regex_exp_ = + QRegularExpression(R"(^(\d+\.)?(\d+\.)?(\*|\d+)$)"); + + bool good_; + + GFModuleAPIGetModuleGFSDKVersion get_sdk_ver_api_; + GFModuleAPIGetModuleQtEnvVersion get_qt_ver_api_; + + GFModuleAPIGetModuleID get_id_api_; + GFModuleAPIGetModuleVersion get_version_api_; + GFModuleAPIGetModuleMetaData get_metadata_api_; + GFModuleAPIRegisterModule register_api_; + GFModuleAPIActivateModule activate_api_; + GFModuleAPIExecuteModule execute_api_; + GFModuleAPIDeactivateModule deactivate_api_; + GFModuleAPIUnregisterModule unregister_api_; + + struct Symbol { + const char* name; + void** pointer; + }; + + QList<Symbol> module_required_symbols_ = { + {"GFGetModuleGFSDKVersion", reinterpret_cast<void**>(&get_sdk_ver_api_)}, + {"GFGetModuleQtEnvVersion", reinterpret_cast<void**>(&get_qt_ver_api_)}, + {"GFGetModuleID", reinterpret_cast<void**>(&get_id_api_)}, + {"GFGetModuleVersion", reinterpret_cast<void**>(&get_version_api_)}, + {"GFGetModuleMetaData", reinterpret_cast<void**>(&get_metadata_api_)}, + {"GFRegisterModule", reinterpret_cast<void**>(®ister_api_)}, + {"GFActiveModule", reinterpret_cast<void**>(&activate_api_)}, + {"GFExecuteModule", reinterpret_cast<void**>(&execute_api_)}, + {"GFDeactiveModule", reinterpret_cast<void**>(&deactivate_api_)}, + {"GFUnregisterModule", reinterpret_cast<void**>(&unregister_api_)}, + }; auto get_gpc() -> GlobalModuleContext* { if (gpc_ == nullptr) { @@ -84,8 +271,25 @@ Module::Module(ModuleIdentifier id, ModuleVersion version, const ModuleMetaData& meta_data) : p_(SecureCreateUniqueObject<Impl>(this, id, version, meta_data)) {} +Module::Module(QLibrary& module_library) + : p_(SecureCreateUniqueObject<Impl>(this, module_library)) {} + Module::~Module() = default; +auto Module::IsGood() -> bool { return p_->IsGood(); } + +auto Module::Register() -> int { return p_->Register(); } + +auto Module::Active() -> int { return p_->Active(); } + +auto Module::Exec(EventRefrernce event) -> int { + return p_->Exec(std::move(event)); +} + +auto Module::Deactive() -> int { return p_->Deactive(); } + +auto Module::UnRegister() -> int { return p_->UnRegister(); } + auto Module::getChannel() -> int { return p_->GetChannel(); } auto Module::getDefaultChannel() -> int { return p_->GetDefaultChannel(); } @@ -102,5 +306,29 @@ auto Module::GetModuleIdentifier() const -> ModuleIdentifier { return p_->GetModuleIdentifier(); } +[[nodiscard]] auto Module::GetModuleVersion() const -> ModuleVersion { + return p_->GetModuleVersion(); +} + +[[nodiscard]] auto Module::GetModuleMetaData() const -> ModuleMetaData { + return p_->GetModuleMetaData(); +} + +[[nodiscard]] auto Module::GetModulePath() const -> QString { + return p_->GetModulePath(); +} + +[[nodiscard]] auto Module::GetModuleHash() const -> QString { + return p_->GetModuleHash(); +} + +[[nodiscard]] auto Module::GetModuleSDKVersion() const -> QString { + return p_->GetModuleSDKVersion(); +} + +[[nodiscard]] auto Module::GetModuleQtEnvVersion() const -> QString { + return p_->GetModuleQtEnvVersion(); +} + void Module::SetGPC(GlobalModuleContext* gpc) { p_->SetGPC(gpc); } } // namespace GpgFrontend::Module
\ No newline at end of file diff --git a/src/core/module/Module.h b/src/core/module/Module.h index 2a5b54e7..615d09b9 100644 --- a/src/core/module/Module.h +++ b/src/core/module/Module.h @@ -39,7 +39,7 @@ class ModuleManager; using ModuleIdentifier = QString; using ModuleVersion = QString; -using ModuleMetaData = std::map<QString, QString>; +using ModuleMetaData = QMap<QString, QString>; using ModulePtr = std::shared_ptr<Module>; using TaskRunnerPtr = std::shared_ptr<Thread::TaskRunner>; @@ -47,21 +47,39 @@ using TaskRunnerPtr = std::shared_ptr<Thread::TaskRunner>; class GPGFRONTEND_CORE_EXPORT Module : public QObject { Q_OBJECT public: - Module(ModuleIdentifier, ModuleVersion, const ModuleMetaData&); + Module(ModuleIdentifier, ModuleVersion, const ModuleMetaData &); + + explicit Module(QLibrary &module_library); ~Module(); - virtual auto Register() -> bool = 0; + auto IsGood() -> bool; + + virtual auto Register() -> int; + + virtual auto Active() -> int; - virtual auto Active() -> bool = 0; + virtual auto Exec(EventRefrernce) -> int; - virtual auto Exec(EventRefrernce) -> int = 0; + virtual auto Deactive() -> int; - virtual auto Deactive() -> bool = 0; + virtual auto UnRegister() -> int; [[nodiscard]] auto GetModuleIdentifier() const -> ModuleIdentifier; - void SetGPC(GlobalModuleContext*); + [[nodiscard]] auto GetModuleVersion() const -> ModuleVersion; + + [[nodiscard]] auto GetModuleMetaData() const -> ModuleMetaData; + + [[nodiscard]] auto GetModulePath() const -> QString; + + [[nodiscard]] auto GetModuleHash() const -> QString; + + [[nodiscard]] auto GetModuleSDKVersion() const -> QString; + + [[nodiscard]] auto GetModuleQtEnvVersion() const -> QString; + + void SetGPC(GlobalModuleContext *); protected: auto getChannel() -> int; diff --git a/src/module/GpgFrontendModuleInit.cpp b/src/core/module/ModuleInit.cpp index 6f88b9ec..8932c97c 100644 --- a/src/module/GpgFrontendModuleInit.cpp +++ b/src/core/module/ModuleInit.cpp @@ -26,18 +26,15 @@ * */ -#include "GpgFrontendModuleInit.h" +#include "ModuleInit.h" -#include <core/module/ModuleManager.h> +#include <QCoreApplication> +#include <QDir> +#include "core/module/ModuleManager.h" #include "core/thread/Task.h" #include "core/thread/TaskRunnerGetter.h" -// integrated modules -#include "integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h" -#include "integrated/version_checking_module/VersionCheckingModule.h" -#include "spdlog/common.h" - namespace GpgFrontend::Module { void LoadGpgFrontendModules(ModuleInitArgs) { @@ -45,17 +42,29 @@ void LoadGpgFrontendModules(ModuleInitArgs) { Thread::TaskRunnerGetter::GetInstance().GetTaskRunner()->PostTask( new Thread::Task( [](const DataObjectPtr&) -> int { - MODULE_LOG_INFO("loading integrated module..."); + auto exec_binary_path = QCoreApplication::applicationDirPath(); + auto mods_path = exec_binary_path + "/mods"; + if (!qEnvironmentVariable("APPIMAGE").isEmpty()) { + mods_path = qEnvironmentVariable("APPDIR") + "/usr/lib/mods"; + } - // VersionCheckingModule - RegisterAndActivateModule< - Integrated::VersionCheckingModule::VersionCheckingModule>(); + GF_CORE_LOG_DEBUG("try loading modules at path: {} ...", mods_path); + if (!QDir(mods_path).exists()) { + GF_CORE_LOG_WARN( + "module directory at path {} not found, abort...", mods_path); + return -1; + } - // VersionCheckingModule - RegisterAndActivateModule<Integrated::GnuPGInfoGatheringModule:: - GnuPGInfoGatheringModule>(); + for (const auto& module_library_name : + QDir(mods_path).entryList(QStringList() << "*.so" + << "*.dll" + << "*.dylib", + QDir::Files)) { + ModuleManager::GetInstance().LoadModule(mods_path + "/" + + module_library_name); + } - MODULE_LOG_INFO("load integrated module done."); + GF_CORE_LOG_DEBUG("load modules done."); return 0; }, "modules_system_init_task")); diff --git a/src/module/GpgFrontendModuleInit.h b/src/core/module/ModuleInit.h index a3a8bbd3..e7e86f0f 100644 --- a/src/module/GpgFrontendModuleInit.h +++ b/src/core/module/ModuleInit.h @@ -28,7 +28,9 @@ #pragma once -#include "module/GpgFrontendModule.h" +#include <spdlog/spdlog.h> + +#include "core/GpgFrontendCoreExport.h" namespace GpgFrontend::Module { @@ -40,12 +42,12 @@ struct ModuleInitArgs { * @brief init the module library * */ -void GPGFRONTEND_MODULE_EXPORT LoadGpgFrontendModules(ModuleInitArgs args); +void GPGFRONTEND_CORE_EXPORT LoadGpgFrontendModules(ModuleInitArgs args); /** * @brief shutdown the module library * */ -void GPGFRONTEND_MODULE_EXPORT ShutdownGpgFrontendModules(); +void GPGFRONTEND_CORE_EXPORT ShutdownGpgFrontendModules(); }; // namespace GpgFrontend::Module diff --git a/src/core/module/ModuleManager.cpp b/src/core/module/ModuleManager.cpp index 83e7c1ff..e00c8c8c 100644 --- a/src/core/module/ModuleManager.cpp +++ b/src/core/module/ModuleManager.cpp @@ -29,16 +29,19 @@ #include "ModuleManager.h" #include <memory> +#include <utility> #include "GpgConstants.h" +#include "core/function/SecureMemoryAllocator.h" +#include "core/function/basic/GpgFunctionObject.h" +#include "core/model/SettingsObject.h" #include "core/module/GlobalModuleContext.h" #include "core/module/GlobalRegisterTable.h" #include "core/module/Module.h" +#include "core/struct/settings_object/ModuleSO.h" #include "core/thread/Task.h" -#include "function/SecureMemoryAllocator.h" -#include "function/basic/GpgFunctionObject.h" -#include "thread/TaskRunnerGetter.h" -#include "utils/MemoryUtils.h" +#include "core/thread/TaskRunnerGetter.h" +#include "core/utils/MemoryUtils.h" namespace GpgFrontend::Module { @@ -50,13 +53,76 @@ class ModuleManager::Impl { ~Impl() = default; + auto LoadAndRegisterModule(const QString& module_library_path) -> void { + Thread::TaskRunnerGetter::GetInstance() + .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default) + ->PostTask(new Thread::Task( + [=](GpgFrontend::DataObjectPtr) -> int { + QLibrary module_library(module_library_path); + if (!module_library.load()) { + GF_CORE_LOG_WARN( + "module manager failed to load module, " + "reason: broken library: {} ", + module_library.fileName()); + return -1; + } + + auto module = SecureCreateSharedObject<Module>(module_library); + if (!module->IsGood()) { + GF_CORE_LOG_WARN( + "module manager failed to load module, " + "reason: illegal module: {}", + module_library.fileName()); + return -1; + } + + module->SetGPC(gmc_.get()); + if (!gmc_->RegisterModule(module)) return -1; + + SettingsObject so( + QString("module.%1.so").arg(module->GetModuleIdentifier())); + ModuleSO module_so(so); + + // if user has set auto active enable + if (module_so.module_id == module->GetModuleIdentifier() && + module_so.module_hash == module->GetModuleHash() && + module_so.auto_activate) { + if (gmc_->ActiveModule(module->GetModuleIdentifier())) { + return -1; + } + } + + return 0; + }, + __func__, nullptr)); + } + + auto SearchModule(ModuleIdentifier module_id) -> ModulePtr { + return gmc_->SearchModule(std::move(module_id)); + } + + auto ListAllRegisteredModuleID() -> QList<ModuleIdentifier> { + return gmc_->ListAllRegisteredModuleID(); + } + void RegisterModule(const ModulePtr& module) { Thread::TaskRunnerGetter::GetInstance() .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default) ->PostTask(new Thread::Task( [=](GpgFrontend::DataObjectPtr) -> int { module->SetGPC(gmc_.get()); - gmc_->RegisterModule(module); + return gmc_->RegisterModule(module) ? 0 : -1; + }, + __func__, nullptr)); + } + + void ListenEvent(const ModuleIdentifier& module_id, + const EventIdentifier& event_id) { + Thread::TaskRunnerGetter::GetInstance() + .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default) + ->PostTask(new Thread::Task( + [=](const GpgFrontend::DataObjectPtr&) -> int { + gmc_->ListenEvent(module_id, event_id); return 0; }, __func__, nullptr)); @@ -73,6 +139,16 @@ class ModuleManager::Impl { __func__, nullptr)); } + auto SearchEvent(EventTriggerIdentifier trigger_id) + -> std::optional<EventRefrernce> { + return gmc_->SearchEvent(std::move(trigger_id)); + } + + auto GetModuleListening(ModuleIdentifier module_id) + -> QList<EventIdentifier> { + return gmc_->GetModuleListening(std::move(module_id)); + } + void ActiveModule(const ModuleIdentifier& identifier) { Thread::TaskRunnerGetter::GetInstance() .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default) @@ -84,6 +160,17 @@ class ModuleManager::Impl { __func__, nullptr)); } + void DeactiveModule(const ModuleIdentifier& identifier) { + Thread::TaskRunnerGetter::GetInstance() + .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default) + ->PostTask(new Thread::Task( + [=](const GpgFrontend::DataObjectPtr&) -> int { + gmc_->DeactivateModule(identifier); + return 0; + }, + __func__, nullptr)); + } + auto GetTaskRunner(ModuleIdentifier module_id) -> std::optional<TaskRunnerPtr> { return gmc_->GetTaskRunner(std::move(module_id)); @@ -109,13 +196,16 @@ class ModuleManager::Impl { return gmc_->IsModuleActivated(id); } + auto GRT() -> GlobalRegisterTable* { return grt_.get(); } + private: static ModuleMangerPtr global_module_manager; SecureUniquePtr<GlobalModuleContext> gmc_; SecureUniquePtr<GlobalRegisterTable> grt_; + QList<QLibrary> module_libraries_; }; -auto IsModuleAcivate(ModuleIdentifier id) -> bool { +auto IsModuleActivate(ModuleIdentifier id) -> bool { return ModuleManager::GetInstance().IsModuleActivated(id); } @@ -141,18 +231,45 @@ ModuleManager::ModuleManager(int channel) ModuleManager::~ModuleManager() = default; +void ModuleManager::LoadModule(QString module_library_path) { + return p_->LoadAndRegisterModule(module_library_path); +} + +auto ModuleManager::SearchModule(ModuleIdentifier module_id) -> ModulePtr { + return p_->SearchModule(std::move(module_id)); +} + void ModuleManager::RegisterModule(ModulePtr module) { return p_->RegisterModule(module); } +void ModuleManager::ListenEvent(ModuleIdentifier module, + EventIdentifier event) { + return p_->ListenEvent(module, event); +} + +auto ModuleManager::GetModuleListening(ModuleIdentifier module_id) + -> QList<EventIdentifier> { + return p_->GetModuleListening(module_id); +} + void ModuleManager::TriggerEvent(EventRefrernce event) { return p_->TriggerEvent(event); } +auto ModuleManager::SearchEvent(EventTriggerIdentifier trigger_id) + -> std::optional<EventRefrernce> { + return p_->SearchEvent(std::move(trigger_id)); +} + void ModuleManager::ActiveModule(ModuleIdentifier id) { return p_->ActiveModule(id); } +void ModuleManager::DeactiveModule(ModuleIdentifier id) { + return p_->DeactiveModule(id); +} + auto ModuleManager::GetTaskRunner(ModuleIdentifier id) -> std::optional<TaskRunnerPtr> { return p_->GetTaskRunner(std::move(id)); @@ -181,4 +298,10 @@ auto ModuleManager::IsModuleActivated(ModuleIdentifier id) -> bool { return p_->IsModuleActivated(id); } +auto ModuleManager::ListAllRegisteredModuleID() -> QList<ModuleIdentifier> { + return p_->ListAllRegisteredModuleID(); +}; + +auto ModuleManager::GRT() -> GlobalRegisterTable* { return p_->GRT(); } + } // namespace GpgFrontend::Module
\ No newline at end of file diff --git a/src/core/module/ModuleManager.h b/src/core/module/ModuleManager.h index 93b89e95..fa8d2264 100644 --- a/src/core/module/ModuleManager.h +++ b/src/core/module/ModuleManager.h @@ -48,6 +48,7 @@ class Event; class Module; class GlobalModuleContext; class ModuleManager; +class GlobalRegisterTable; using EventRefrernce = std::shared_ptr<Event>; using ModuleIdentifier = QString; @@ -65,12 +66,24 @@ class GPGFRONTEND_CORE_EXPORT ModuleManager virtual ~ModuleManager() override; + auto LoadModule(QString) -> void; + + auto SearchModule(ModuleIdentifier) -> ModulePtr; + + auto ListAllRegisteredModuleID() -> QList<ModuleIdentifier>; + void RegisterModule(ModulePtr); auto IsModuleActivated(ModuleIdentifier) -> bool; + void ListenEvent(ModuleIdentifier, EventIdentifier); + void TriggerEvent(EventRefrernce); + auto SearchEvent(EventTriggerIdentifier) -> std::optional<EventRefrernce>; + + auto GetModuleListening(ModuleIdentifier) -> QList<EventIdentifier>; + void ActiveModule(ModuleIdentifier); void DeactiveModule(ModuleIdentifier); @@ -85,6 +98,8 @@ class GPGFRONTEND_CORE_EXPORT ModuleManager auto ListRTChildKeys(const QString&, const QString&) -> std::vector<Key>; + auto GRT() -> GlobalRegisterTable*; + private: class Impl; SecureUniquePtr<Impl> p_; @@ -118,7 +133,7 @@ void TriggerEvent(const EventIdentifier& event_id, Args&&... args, * @return true * @return false */ -auto GPGFRONTEND_CORE_EXPORT IsModuleAcivate(ModuleIdentifier) -> bool; +auto GPGFRONTEND_CORE_EXPORT IsModuleActivate(ModuleIdentifier) -> bool; /** * @brief diff --git a/src/core/struct/settings_object/ModuleSO.h b/src/core/struct/settings_object/ModuleSO.h new file mode 100644 index 00000000..a161885c --- /dev/null +++ b/src/core/struct/settings_object/ModuleSO.h @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +namespace GpgFrontend { + +struct ModuleSO { + QString module_id; + QString module_version; + QString module_hash; + bool auto_activate; + + ModuleSO() = default; + + explicit ModuleSO(const QJsonObject& j) { + if (const auto v = j["module_id"]; v.isString()) { + module_id = v.toString(); + } + + if (const auto v = j["module_version"]; v.isString()) { + module_version = v.toString(); + } + + if (const auto v = j["module_hash"]; v.isString()) { + module_hash = v.toString(); + } + + if (const auto v = j["auto_activate"]; v.isBool()) { + auto_activate = v.toBool(); + } + } + + [[nodiscard]] auto ToJson() const -> QJsonObject { + QJsonObject j; + j["module_id"] = module_id; + j["module_version"] = module_version; + j["module_hash"] = module_hash; + j["auto_activate"] = auto_activate; + return j; + } +}; +} // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/typedef/GpgTypedef.h b/src/core/typedef/GpgTypedef.h index cf0887bf..599c5c59 100644 --- a/src/core/typedef/GpgTypedef.h +++ b/src/core/typedef/GpgTypedef.h @@ -28,7 +28,7 @@ #pragma once -#include <tuple> +#include <gpgme.h> #include "core/model/DataObject.h" diff --git a/src/core/utils/AsyncUtils.cpp b/src/core/utils/AsyncUtils.cpp index 9ce94247..3c007fb6 100644 --- a/src/core/utils/AsyncUtils.cpp +++ b/src/core/utils/AsyncUtils.cpp @@ -45,7 +45,7 @@ auto RunGpgOperaAsync(const GpgOperaRunnable& runnable, GF_CORE_LOG_DEBUG("got gnupg version from rt: {}, operation: {}", gnupg_version, operation); - if (CompareSoftwareVersion(gnupg_version, minial_version) < 0) { + if (GFCompareSoftwareVersion(gnupg_version, minial_version) < 0) { GF_CORE_LOG_ERROR("operaton {} not support for gnupg version: {}", operation, gnupg_version); callback(GPG_ERR_NOT_SUPPORTED, TransferParams()); @@ -85,7 +85,7 @@ auto RunGpgOperaSync(const GpgOperaRunnable& runnable, const QString& operation, GF_CORE_LOG_DEBUG("got gnupg version from rt: {}, operation: {}", gnupg_version, operation); - if (CompareSoftwareVersion(gnupg_version, minial_version) < 0) { + if (GFCompareSoftwareVersion(gnupg_version, minial_version) < 0) { GF_CORE_LOG_ERROR("operaton {} not support for gnupg version: {}", operation, gnupg_version); return {GPG_ERR_NOT_SUPPORTED, TransferParams()}; diff --git a/src/core/utils/BuildInfoUtils.cpp b/src/core/utils/BuildInfoUtils.cpp new file mode 100644 index 00000000..a7d914ef --- /dev/null +++ b/src/core/utils/BuildInfoUtils.cpp @@ -0,0 +1,26 @@ + +#include "BuildInfoUtils.h" + +#include "GpgFrontendBuildInfo.h" + +namespace GpgFrontend { + +auto GetProjectVersion() -> QString { + return QString("v") + VERSION_MAJOR + "." + VERSION_MINOR + "." + + VERSION_PATCH; +} + +auto GetProjectBuildVersion() -> QString { return BUILD_VERSION; } + +auto GetProjectBuildTimestamp() -> QDateTime { + return QDateTime::fromString(BUILD_TIMESTAMP, Qt::ISODate); +} + +auto GetProjectBuildGitBranchName() -> QString { return GIT_BRANCH_NAME; } + +auto GetProjectBuildGitCommitHash() -> QString { return GIT_COMMIT_HASH; } + +auto GetProjectBuildGitVersion() -> QString { return GIT_VERSION; } + +auto GetHttpRequestUserAgent() -> QString { return HTTP_REQUEST_USER_AGENT; } +}; // namespace GpgFrontend
\ No newline at end of file diff --git a/src/module/integrated/version_checking_module/VersionCheckingModule.h b/src/core/utils/BuildInfoUtils.h index 0730feed..07b0bb21 100644 --- a/src/module/integrated/version_checking_module/VersionCheckingModule.h +++ b/src/core/utils/BuildInfoUtils.h @@ -28,34 +28,57 @@ #pragma once -#include "GpgFrontendModuleExport.h" -#include "SoftwareVersion.h" -#include "core/module/Module.h" +#include "core/GpgFrontendCoreExport.h" -namespace GpgFrontend::Module::Integrated::VersionCheckingModule { +namespace GpgFrontend { -class GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT - VersionCheckingModule : public Module { - Q_OBJECT - public: - VersionCheckingModule(); - - ~VersionCheckingModule() override; - - auto Register() -> bool override; +/** + * @brief + * + * @return QString + */ +auto GPGFRONTEND_CORE_EXPORT GetProjectVersion() -> QString; - auto Active() -> bool override; +/** + * @brief + * + * @return QString + */ +auto GPGFRONTEND_CORE_EXPORT GetProjectBuildVersion() -> QString; - auto Exec(EventRefrernce) -> int override; +/** + * @brief + * + * @return QString + */ +auto GPGFRONTEND_CORE_EXPORT GetProjectBuildTimestamp() -> QDateTime; - auto Deactive() -> bool override; +/** + * @brief + * + * @return QString + */ +auto GPGFRONTEND_CORE_EXPORT GetProjectBuildGitBranchName() -> QString; - signals: +/** + * @brief + * + * @return QString + */ +auto GPGFRONTEND_CORE_EXPORT GetProjectBuildGitCommitHash() -> QString; - void SignalVersionCheckDone(SoftwareVersion); +/** + * @brief + * + * @return QString + */ +auto GPGFRONTEND_CORE_EXPORT GetProjectBuildGitVersion() -> QString; - public slots: +/** + * @brief + * + * @return QString + */ +auto GPGFRONTEND_CORE_EXPORT GetHttpRequestUserAgent() -> QString; - void SlotVersionCheckDone(SoftwareVersion); -}; -} // namespace GpgFrontend::Module::Integrated::VersionCheckingModule +} // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/utils/CacheUtils.h b/src/core/utils/CacheUtils.h index 48b9ac4b..eae45353 100644 --- a/src/core/utils/CacheUtils.h +++ b/src/core/utils/CacheUtils.h @@ -28,6 +28,8 @@ #pragma once +#include "core/GpgFrontendCoreExport.h" + namespace GpgFrontend { /** diff --git a/src/core/utils/CommonUtils.cpp b/src/core/utils/CommonUtils.cpp index 0b182241..d1704312 100644 --- a/src/core/utils/CommonUtils.cpp +++ b/src/core/utils/CommonUtils.cpp @@ -43,7 +43,7 @@ auto BeautifyFingerprint(QString fingerprint) -> QString { return out.readAll(); } -auto CompareSoftwareVersion(const QString& a, const QString& b) -> int { +auto GFCompareSoftwareVersion(const QString& a, const QString& b) -> int { auto remove_prefix = [](const QString& version) { return version.startsWith('v') ? version.mid(1) : version; }; @@ -71,4 +71,25 @@ auto CompareSoftwareVersion(const QString& a, const QString& b) -> int { return 0; } + +auto GFStrDup(const QString& str) -> char* { + auto utf8_str = str.toUtf8(); + auto* c_str = + static_cast<char*>(SecureMalloc((utf8_str.size() + 1) * sizeof(char))); + + memcpy(c_str, utf8_str.constData(), utf8_str.size()); + c_str[utf8_str.size()] = '\0'; + return c_str; +} + +auto GPGFRONTEND_CORE_EXPORT GFUnStrDup(char* str) -> QString { + auto qt_str = QString::fromUtf8(str); + SecureFree(static_cast<void*>(const_cast<char*>(str))); + return qt_str; +} + +auto GPGFRONTEND_CORE_EXPORT GFUnStrDup(const char* str) -> QString { + return GFUnStrDup(const_cast<char*>(str)); +} + } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/utils/CommonUtils.h b/src/core/utils/CommonUtils.h index a45c6056..6ef38fad 100644 --- a/src/core/utils/CommonUtils.h +++ b/src/core/utils/CommonUtils.h @@ -48,7 +48,21 @@ auto GPGFRONTEND_CORE_EXPORT BeautifyFingerprint(QString fingerprint) * @param b * @return int */ -auto GPGFRONTEND_CORE_EXPORT CompareSoftwareVersion(const QString& a, - const QString& b) -> int; +auto GPGFRONTEND_CORE_EXPORT GFCompareSoftwareVersion(const QString& a, + const QString& b) -> int; + +/** + * @brief + * + * @return char* + */ +auto GPGFRONTEND_CORE_EXPORT GFStrDup(const QString&) -> char*; + +/** + * @brief + * + * @return QString + */ +auto GPGFRONTEND_CORE_EXPORT GFUnStrDup(const char*) -> QString; } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/utils/FilesystemUtils.h b/src/core/utils/FilesystemUtils.h index 0b58bbb7..0bc90ac5 100644 --- a/src/core/utils/FilesystemUtils.h +++ b/src/core/utils/FilesystemUtils.h @@ -28,6 +28,8 @@ #pragma once +#include "core/GpgFrontendCoreExport.h" + namespace GpgFrontend { /** @@ -54,8 +56,8 @@ auto GPGFRONTEND_CORE_EXPORT GetOnlyFileNameWithPath(const QString& path) * @param filename_pattern The pattern of the file name, e.g. "*.txt" * @return int64_t */ -auto GPGFRONTEND_CORE_EXPORT GetFileSizeByPath( - const QString& path, const QString& filename_pattern) +auto GPGFRONTEND_CORE_EXPORT GetFileSizeByPath(const QString& path, + const QString& filename_pattern) -> int64_t; /** @@ -72,7 +74,7 @@ auto GPGFRONTEND_CORE_EXPORT GetHumanFriendlyFileSize(int64_t size) -> QString; * @param path * @param filename_pattern */ -void GPGFRONTEND_CORE_EXPORT DeleteAllFilesByPattern( - const QString& path, const QString& filename_pattern); +void GPGFRONTEND_CORE_EXPORT +DeleteAllFilesByPattern(const QString& path, const QString& filename_pattern); } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/utils/IOUtils.cpp b/src/core/utils/IOUtils.cpp index 1002badd..79b879f9 100644 --- a/src/core/utils/IOUtils.cpp +++ b/src/core/utils/IOUtils.cpp @@ -180,4 +180,42 @@ auto GetFullExtension(const QString& path) -> QString { return filename.mid(dot_index); } +auto CalculateBinaryChacksum(const QString& path) -> QString { + // check file info and access rights + QFileInfo info(path); + if (!info.exists() || !info.isFile() || !info.isReadable()) { + GF_CORE_LOG_ERROR("get info for file {} error, exists: {}", info.filePath(), + info.exists()); + return {}; + } + + // open and read file + QFile f(info.filePath()); + if (!f.open(QIODevice::ReadOnly)) { + GF_CORE_LOG_ERROR("open {} to calculate checksum error: {}", + path.toStdString(), f.errorString().toStdString()); + return {}; + } + + QCryptographicHash hash_sha(QCryptographicHash::Sha256); + + // read data by chunks + const qint64 buffer_size = 8192; // Define a suitable buffer size + while (!f.atEnd()) { + QByteArray buffer = f.read(buffer_size); + if (buffer.isEmpty()) { + GF_CORE_LOG_ERROR("error reading file {} during checksum calculation", + path.toStdString()); + return {}; + } + hash_sha.addData(buffer); + } + + // close the file + f.close(); + + // return the SHA-256 hash of the file + return hash_sha.result().toHex(); +} + } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/utils/IOUtils.h b/src/core/utils/IOUtils.h index 2c48f38c..3e18394d 100644 --- a/src/core/utils/IOUtils.h +++ b/src/core/utils/IOUtils.h @@ -85,6 +85,15 @@ auto GPGFRONTEND_CORE_EXPORT CalculateHash(const QString &file_path) -> QString; * @brief * * @param path + * @return QString + */ +auto GPGFRONTEND_CORE_EXPORT CalculateBinaryChacksum(const QString &path) + -> QString; + +/** + * @brief + * + * @param path * @param out_buffer * @return true * @return false diff --git a/src/core/utils/LocalizedUtils.h b/src/core/utils/LocalizedUtils.h index b93b500c..10ada833 100644 --- a/src/core/utils/LocalizedUtils.h +++ b/src/core/utils/LocalizedUtils.h @@ -28,6 +28,8 @@ #pragma once +#include "core/GpgFrontendCoreExport.h" + namespace GpgFrontend { auto GPGFRONTEND_CORE_EXPORT GetLocalizedDateByTimestamp(time_t) -> QString; diff --git a/src/core/utils/LogUtils.h b/src/core/utils/LogUtils.h index a1a5685a..e8dc6f3b 100644 --- a/src/core/utils/LogUtils.h +++ b/src/core/utils/LogUtils.h @@ -28,6 +28,49 @@ #pragma once +// spdlog library configuration +#undef SPDLOG_ACTIVE_LEVEL +#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE +#include <spdlog/spdlog.h> + +// logger fmt +#include "core/GpgFrontendCoreExport.h" + +template <> +struct fmt::formatter<QString> { + // Parses format specifications. + constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + // Formats the QString qstr and writes it to the output. + template <typename FormatContext> + auto format(const QString& qstr, FormatContext& ctx) const + -> decltype(ctx.out()) { + // Convert QString to UTF-8 QString (to handle Unicode characters + // correctly) + QByteArray utf8_array = qstr.toUtf8(); + return fmt::format_to(ctx.out(), "{}", utf8_array.constData()); + } +}; + +template <> +struct fmt::formatter<QByteArray> { + // Parses format specifications. + constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + // Formats the QString qstr and writes it to the output. + template <typename FormatContext> + auto format(const QByteArray& qarray, FormatContext& ctx) const + -> decltype(ctx.out()) { + // Convert QString to UTF-8 QString (to handle Unicode characters + // correctly) + return fmt::format_to(ctx.out(), "{}", qarray.constData()); + } +}; + namespace GpgFrontend { /** @@ -50,7 +93,7 @@ auto GPGFRONTEND_CORE_EXPORT GetCoreLogger() -> std::shared_ptr<spdlog::logger>; * * @return std::shared_ptr<spdlog::logger> */ -auto GPGFRONTEND_CORE_EXPORT GetLogger(const QString &) +auto GPGFRONTEND_CORE_EXPORT GetLogger(const QString&) -> std::shared_ptr<spdlog::logger>; /** @@ -65,7 +108,7 @@ void GPGFRONTEND_CORE_EXPORT SetDefaultLogLevel(spdlog::level::level_enum); * * @return auto */ -void GPGFRONTEND_CORE_EXPORT RegisterAsyncLogger(const QString &, +void GPGFRONTEND_CORE_EXPORT RegisterAsyncLogger(const QString&, spdlog::level::level_enum); /** @@ -73,7 +116,7 @@ void GPGFRONTEND_CORE_EXPORT RegisterAsyncLogger(const QString &, * * @return auto */ -void GPGFRONTEND_CORE_EXPORT RegisterSyncLogger(const QString &, +void GPGFRONTEND_CORE_EXPORT RegisterSyncLogger(const QString&, spdlog::level::level_enum); } // namespace GpgFrontend diff --git a/src/init.cpp b/src/init.cpp index 76c1fd4c..e5936d31 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -31,9 +31,9 @@ #include "core/GpgCoreInit.h" #include "core/function/GlobalSettingStation.h" #include "core/function/gpg/GpgAdvancedOperator.h" +#include "core/module/ModuleInit.h" #include "core/thread/TaskRunnerGetter.h" #include "core/utils/LogUtils.h" -#include "module/GpgFrontendModuleInit.h" #include "ui/GpgFrontendUIInit.h" // main diff --git a/src/module/CMakeLists.txt b/src/module/CMakeLists.txt index a741f0af..8d894b00 100644 --- a/src/module/CMakeLists.txt +++ b/src/module/CMakeLists.txt @@ -30,15 +30,16 @@ set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) aux_source_directory(sdk MODULE_SDK_SOURCE) add_library(gpgfrontend_module_sdk SHARED ${MODULE_SDK_SOURCE}) -set(_export_file_sdk "${CMAKE_CURRENT_SOURCE_DIR}/sdk/GpgFrontendModuleSDKExport.h") +set(_export_file_sdk "${CMAKE_CURRENT_SOURCE_DIR}/sdk/GFSDKExport.h") generate_export_header(gpgfrontend_module_sdk EXPORT_FILE_NAME "${_export_file_sdk}") -target_include_directories(gpgfrontend_module_sdk PUBLIC - sdk +target_include_directories(gpgfrontend_module_sdk PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/gpgfrontend_module_sdk_autogen/include ${CMAKE_SOURCE_DIR}/third_party/spdlog/include) +target_include_directories(gpgfrontend_module_sdk PUBLIC sdk) + # link module system -target_link_libraries(gpgfrontend_module_sdk PUBLIC gpgfrontend_core) +target_link_libraries(gpgfrontend_module_sdk PRIVATE gpgfrontend_core) if (XCODE_BUILD) set_target_properties(gpgfrontend_module_sdk @@ -50,51 +51,14 @@ if (XCODE_BUILD) XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}") endif () -# tracking integrated modules +# tracking modules set(all_integrated_module_libraries "") -file(GLOB children LIST_DIRECTORIES true "integrated/*") +file(GLOB children LIST_DIRECTORIES true "mods/*") foreach(child ${children}) if(IS_DIRECTORY ${child}) get_filename_component(dirName ${child} NAME) - add_subdirectory("integrated/${dirName}") - - string(REPLACE "_module" "" stripped_module ${dirName}) - set(integrated_lib_name "gpgfrontend_integrated_module_${stripped_module}") - list(APPEND all_integrated_module_libraries ${integrated_lib_name}) + add_subdirectory("mods/${dirName}") + + list(APPEND all_integrated_module_libraries ${dirName}) endif() -endforeach() - -aux_source_directory(. MODULE_SOURCE) -add_library(gpgfrontend_module SHARED ${MODULE_SOURCE}) - -set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendModuleExport.h") -generate_export_header(gpgfrontend_module EXPORT_FILE_NAME "${_export_file}") - -# set up pch -target_precompile_headers(gpgfrontend_module PUBLIC GpgFrontendModule.h) - -# add ui generator include path -target_include_directories(gpgfrontend_module PUBLIC - ${CMAKE_CURRENT_BINARY_DIR}/gpgfrontend_module_autogen/include - ${CMAKE_SOURCE_DIR}/third_party/spdlog/include) - -# link gpgfrontend_module_sdk -target_link_libraries(gpgfrontend_module PRIVATE gpgfrontend_module_sdk) - -if (XCODE_BUILD) - set_target_properties(gpgfrontend_module - PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} - XCODE_ATTRIBUTE_SKIP_INSTALL "Yes" - XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}") -endif () - - -# link all integrated modules -message(STATUS "All Module Libraries: ${all_integrated_module_libraries}") -target_link_libraries(gpgfrontend_module PRIVATE ${all_integrated_module_libraries}) - -# using std c++ 17 -target_compile_features(gpgfrontend_module PUBLIC cxx_std_17)
\ No newline at end of file +endforeach()
\ No newline at end of file diff --git a/src/module/GpgFrontendModuleExport.h b/src/module/GpgFrontendModuleExport.h deleted file mode 100644 index 33ecbd3b..00000000 --- a/src/module/GpgFrontendModuleExport.h +++ /dev/null @@ -1,42 +0,0 @@ - -#ifndef GPGFRONTEND_MODULE_EXPORT_H -#define GPGFRONTEND_MODULE_EXPORT_H - -#ifdef GPGFRONTEND_MODULE_STATIC_DEFINE -# define GPGFRONTEND_MODULE_EXPORT -# define GPGFRONTEND_MODULE_NO_EXPORT -#else -# ifndef GPGFRONTEND_MODULE_EXPORT -# ifdef gpgfrontend_module_EXPORTS - /* We are building this library */ -# define GPGFRONTEND_MODULE_EXPORT __attribute__((visibility("default"))) -# else - /* We are using this library */ -# define GPGFRONTEND_MODULE_EXPORT __attribute__((visibility("default"))) -# endif -# endif - -# ifndef GPGFRONTEND_MODULE_NO_EXPORT -# define GPGFRONTEND_MODULE_NO_EXPORT __attribute__((visibility("hidden"))) -# endif -#endif - -#ifndef GPGFRONTEND_MODULE_DEPRECATED -# define GPGFRONTEND_MODULE_DEPRECATED __attribute__ ((__deprecated__)) -#endif - -#ifndef GPGFRONTEND_MODULE_DEPRECATED_EXPORT -# define GPGFRONTEND_MODULE_DEPRECATED_EXPORT GPGFRONTEND_MODULE_EXPORT GPGFRONTEND_MODULE_DEPRECATED -#endif - -#ifndef GPGFRONTEND_MODULE_DEPRECATED_NO_EXPORT -# define GPGFRONTEND_MODULE_DEPRECATED_NO_EXPORT GPGFRONTEND_MODULE_NO_EXPORT GPGFRONTEND_MODULE_DEPRECATED -#endif - -#if 0 /* DEFINE_NO_DEPRECATED */ -# ifndef GPGFRONTEND_MODULE_NO_DEPRECATED -# define GPGFRONTEND_MODULE_NO_DEPRECATED -# endif -#endif - -#endif /* GPGFRONTEND_MODULE_EXPORT_H */ diff --git a/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp b/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp deleted file mode 100644 index a1e5cd5a..00000000 --- a/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/** - * Copyright (C) 2021 Saturneric <[email protected]> - * - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GpgFrontend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from - * the gpg4usb project, which is under GPL-3.0-or-later. - * - * All the source code of GpgFrontend was modified and released by - * Saturneric <[email protected]> starting on May 12, 2021. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "GnuPGInfoGatheringModule.h" - -#include <vector> - -#include "GpgInfo.h" -#include "Log.h" -#include "core/function/gpg/GpgCommandExecutor.h" -#include "core/module/ModuleManager.h" - -namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule { - -auto CheckBinaryChacksum(QString path) -> std::optional<QString> { - // check file info and access rights - QFileInfo info(path); - if (!info.exists() || !info.isFile() || !info.isReadable()) { - MODULE_LOG_ERROR("get info for file {} error, exists: {}", info.filePath(), - info.exists()); - return {}; - } - - // open and read file - QFile f(info.filePath()); - if (!f.open(QIODevice::ReadOnly)) { - MODULE_LOG_ERROR("open {} to calculate check sum error: {}", path, - f.errorString()); - return {}; - } - - // read all data from file - auto buffer = f.readAll(); - f.close(); - - auto hash_sha = QCryptographicHash(QCryptographicHash::Sha256); - // md5 - hash_sha.addData(buffer); - return QString(hash_sha.result().toHex()).left(6); -} - -GnuPGInfoGatheringModule::GnuPGInfoGatheringModule() - : Module( - "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering", - "1.0.0", - ModuleMetaData{{"description", "try to gathering gnupg informations"}, - {"author", "saturneric"}}) {} - -GnuPGInfoGatheringModule::~GnuPGInfoGatheringModule() = default; - -auto GnuPGInfoGatheringModule::Register() -> bool { - MODULE_LOG_DEBUG("gnupg info gathering module registering"); - listenEvent("GPGFRONTEND_CORE_INITLIZED"); - return true; -} - -auto GnuPGInfoGatheringModule::Active() -> bool { - MODULE_LOG_DEBUG("gnupg info gathering module activating"); - return true; -} - -auto GnuPGInfoGatheringModule::Exec(EventRefrernce event) -> int { - MODULE_LOG_DEBUG("gnupg info gathering module executing, event id: {}", - event->GetIdentifier()); - - const auto gpgme_version = RetrieveRTValueTypedOrDefault<>( - "core", "gpgme.version", QString{"0.0.0"}); - MODULE_LOG_DEBUG("got gpgme version from rt: {}", gpgme_version); - - const auto gpgconf_path = RetrieveRTValueTypedOrDefault<>( - "core", "gpgme.ctx.gpgconf_path", QString{}); - MODULE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path); - - MODULE_LOG_DEBUG("start to load extra info at module gnupginfogathering..."); - - // get all components - GpgCommandExecutor::ExecuteSync( - {gpgconf_path, QStringList{"--list-components"}, - [this, gpgme_version, gpgconf_path](int exit_code, const QString &p_out, - const QString &p_err) { - MODULE_LOG_DEBUG( - "gpgconf components exit_code: {} process stdout size: {}", - exit_code, p_out.size()); - - if (exit_code != 0) { - MODULE_LOG_ERROR( - "gpgconf execute error, process stderr: {}, " - "process stdout: {}", - p_err, p_out); - return; - } - - std::vector<GpgComponentInfo> component_infos; - GpgComponentInfo c_i_gpgme; - c_i_gpgme.name = "gpgme"; - c_i_gpgme.desc = "GPG Made Easy"; - c_i_gpgme.version = gpgme_version; - c_i_gpgme.path = tr("Embedded In"); - c_i_gpgme.binary_checksum = "/"; - - GpgComponentInfo c_i_gpgconf; - c_i_gpgconf.name = "gpgconf"; - c_i_gpgconf.desc = "GPG Configure"; - c_i_gpgconf.version = "/"; - c_i_gpgconf.path = gpgconf_path; - auto gpgconf_binary_checksum = CheckBinaryChacksum(gpgconf_path); - c_i_gpgconf.binary_checksum = (gpgconf_binary_checksum.has_value() - ? gpgconf_binary_checksum.value() - : QString("/")); - - component_infos.push_back(c_i_gpgme); - component_infos.push_back(c_i_gpgconf); - - auto const jsonlized_gpgme_component_info = c_i_gpgme.Json(); - auto const jsonlized_gpgconf_component_info = c_i_gpgconf.Json(); - UpsertRTValue(GetModuleIdentifier(), "gnupg.components.gpgme", - QJsonDocument(jsonlized_gpgme_component_info).toJson()); - UpsertRTValue( - GetModuleIdentifier(), "gnupg.components.gpgconf", - QJsonDocument(jsonlized_gpgconf_component_info).toJson()); - - auto line_split_list = p_out.split("\n"); - - for (const auto &line : line_split_list) { - auto info_split_list = line.split(":"); - - if (info_split_list.size() != 3) continue; - - auto component_name = info_split_list[0].trimmed(); - auto component_desc = info_split_list[1].trimmed(); - auto component_path = info_split_list[2].trimmed(); - -#ifdef WINDOWS - // replace some special substrings on windows platform - component_path.replace("%3a", ":"); -#endif - - auto binary_checksum = CheckBinaryChacksum(component_path); - - MODULE_LOG_DEBUG( - "gnupg component name: {} desc: {} checksum: {} path: {} ", - component_name, component_desc, - binary_checksum.has_value() ? binary_checksum.value() : "/", - component_path); - - QString version = "/"; - - if (component_name == "gpg") { - version = RetrieveRTValueTypedOrDefault<>( - "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"}); - } - if (component_name == "gpg-agent") { - UpsertRTValue(GetModuleIdentifier(), "gnupg.gpg_agent_path", - QString(component_path)); - } - if (component_name == "dirmngr") { - UpsertRTValue(GetModuleIdentifier(), "gnupg.dirmngr_path", - QString(component_path)); - } - if (component_name == "keyboxd") { - UpsertRTValue(GetModuleIdentifier(), "gnupg.keyboxd_path", - QString(component_path)); - } - - { - GpgComponentInfo c_i; - c_i.name = component_name; - c_i.desc = component_desc; - c_i.version = version; - c_i.path = component_path; - c_i.binary_checksum = - (binary_checksum.has_value() ? binary_checksum.value() - : QString("/")); - - auto const jsonlized_component_info = c_i.Json(); - UpsertRTValue(GetModuleIdentifier(), - QString("gnupg.components.%1").arg(component_name), - QJsonDocument(jsonlized_component_info).toJson()); - - component_infos.push_back(c_i); - } - } - }, - getTaskRunner()}); - - GpgCommandExecutor::ExecuteContexts exec_contexts; -#ifdef QT5_BUILD - exec_contexts.push_back(GpgCommandExecutor::ExecuteContext{ -#else - exec_contexts.emplace_back(GpgCommandExecutor::ExecuteContext{ -#endif - gpgconf_path, QStringList{"--list-dirs"}, - [this](int exit_code, const QString &p_out, const QString &p_err) { - if (exit_code != 0) return; - - auto line_split_list = p_out.split("\n"); - - for (const auto &line : line_split_list) { - auto info_split_list = line.split(":"); - MODULE_LOG_DEBUG("gpgconf direcrotries info line: {} info size: {}", - line, info_split_list.size()); - - if (info_split_list.size() != 2) continue; - - auto configuration_name = info_split_list[0].trimmed(); - auto configuration_value = info_split_list[1].trimmed(); - -#ifdef WINDOWS - // replace some special substrings on windows platform - configuration_value.replace("%3a", ":"); -#endif - - // record gnupg home path - if (configuration_name == "homedir") { - UpsertRTValue(GetModuleIdentifier(), "gnupg.home_path", - configuration_value); - } - - UpsertRTValue(GetModuleIdentifier(), - QString("gnupg.dirs.%1").arg(configuration_name), - configuration_value); - } - }, - getTaskRunner()}); - - auto components = ListRTChildKeys(GetModuleIdentifier(), "gnupg.components"); - - for (const auto &component : components) { - auto component_info_json = RetrieveRTValueTypedOrDefault( - GetModuleIdentifier(), QString("gnupg.components.%1").arg(component), - QByteArray{}); - - auto jsonlized_component_info = - QJsonDocument::fromJson(component_info_json); - assert(jsonlized_component_info.isObject()); - - auto component_info = GpgComponentInfo(jsonlized_component_info.object()); - MODULE_LOG_DEBUG("gpgconf check options ready, component: {}", - component_info.name); - - if (component_info.name == "gpgme" || component_info.name == "gpgconf") { - continue; - } - -#ifdef QT5_BUILD - exec_contexts.push_back(GpgCommandExecutor::ExecuteContext{ -#else - exec_contexts.emplace_back(GpgCommandExecutor::ExecuteContext{ -#endif - gpgconf_path, QStringList{"--list-options", component_info.name}, - [this, component_info](int exit_code, const QString &p_out, - const QString &p_err) { - MODULE_LOG_DEBUG( - "gpgconf {} avaliable options exit_code: {} process stdout " - "size: {} ", - component_info.name, exit_code, p_out.size()); - - if (exit_code != 0) { - MODULE_LOG_ERROR( - "gpgconf {} avaliable options execute error, process stderr: " - "{} , process stdout:", - component_info.name, p_err, p_out); - return; - } - - std::vector<GpgOptionsInfo> options_infos; - - auto line_split_list = p_out.split("\n"); - - for (const auto &line : line_split_list) { - auto info_split_list = line.split(":"); - - MODULE_LOG_DEBUG( - "component {} avaliable options line: {} info size: {}", - component_info.name, line, info_split_list.size()); - - if (info_split_list.size() < 10) continue; - - // The format of each line is: - // name:flags:level:description:type:alt-type:argname:default:argdef:value - - auto option_name = info_split_list[0].trimmed(); - auto option_flags = info_split_list[1].trimmed(); - auto option_level = info_split_list[2].trimmed(); - auto option_desc = info_split_list[3].trimmed(); - auto option_type = info_split_list[4].trimmed(); - auto option_alt_type = info_split_list[5].trimmed(); - auto option_argname = info_split_list[6].trimmed(); - auto option_default = info_split_list[7].trimmed(); - auto option_argdef = info_split_list[8].trimmed(); - auto option_value = info_split_list[9].trimmed(); - - GpgOptionsInfo info; - info.name = option_name; - info.flags = option_flags; - info.level = option_level; - info.description = option_desc; - info.type = option_type; - info.alt_type = option_alt_type; - info.argname = option_argname; - info.default_value = option_default; - info.argdef = option_argdef; - info.value = option_value; - - auto const jsonlized_option_info = info.Json(); - UpsertRTValue(GetModuleIdentifier(), - QString("gnupg.components.%1.options.%2") - .arg(component_info.name) - .arg(option_name), - QJsonDocument(jsonlized_option_info).toJson()); - options_infos.push_back(info); - } - }, - getTaskRunner()}); - } - - GpgCommandExecutor::ExecuteConcurrentlySync(exec_contexts); - UpsertRTValue(GetModuleIdentifier(), "gnupg.gathering_done", true); - event->ExecuteCallback(GetModuleIdentifier(), TransferParams(true)); - - MODULE_LOG_DEBUG("gnupg external info gathering done"); - return 0; -} - -auto GnuPGInfoGatheringModule::Deactive() -> bool { return true; } - -} // namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule diff --git a/src/module/integrated/gnupg_info_gathering_module/GpgFrontendModuleExport.h b/src/module/integrated/gnupg_info_gathering_module/GpgFrontendModuleExport.h deleted file mode 100644 index 3a5ba68b..00000000 --- a/src/module/integrated/gnupg_info_gathering_module/GpgFrontendModuleExport.h +++ /dev/null @@ -1,42 +0,0 @@ - -#ifndef GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT_H -#define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT_H - -#ifdef GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_STATIC_DEFINE -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_NO_EXPORT -#else -# ifndef GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT -# ifdef gpgfrontend_integrated_module_gnupg_info_gathering_EXPORTS - /* We are building this library */ -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT __attribute__((visibility("default"))) -# else - /* We are using this library */ -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT __attribute__((visibility("default"))) -# endif -# endif - -# ifndef GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_NO_EXPORT -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_NO_EXPORT __attribute__((visibility("hidden"))) -# endif -#endif - -#ifndef GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_DEPRECATED -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_DEPRECATED __attribute__ ((__deprecated__)) -#endif - -#ifndef GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_DEPRECATED_EXPORT -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_DEPRECATED_EXPORT GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_DEPRECATED -#endif - -#ifndef GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_DEPRECATED_NO_EXPORT -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_DEPRECATED_NO_EXPORT GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_NO_EXPORT GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_DEPRECATED -#endif - -#if 0 /* DEFINE_NO_DEPRECATED */ -# ifndef GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_NO_DEPRECATED -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_NO_DEPRECATED -# endif -#endif - -#endif /* GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT_H */ diff --git a/src/module/integrated/version_checking_module/GpgFrontendModuleExport.h b/src/module/integrated/version_checking_module/GpgFrontendModuleExport.h deleted file mode 100644 index 0ac60b2f..00000000 --- a/src/module/integrated/version_checking_module/GpgFrontendModuleExport.h +++ /dev/null @@ -1,42 +0,0 @@ - -#ifndef GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT_H -#define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT_H - -#ifdef GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_STATIC_DEFINE -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_NO_EXPORT -#else -# ifndef GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT -# ifdef gpgfrontend_integrated_module_version_checking_EXPORTS - /* We are building this library */ -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT __attribute__((visibility("default"))) -# else - /* We are using this library */ -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT __attribute__((visibility("default"))) -# endif -# endif - -# ifndef GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_NO_EXPORT -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_NO_EXPORT __attribute__((visibility("hidden"))) -# endif -#endif - -#ifndef GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_DEPRECATED -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_DEPRECATED __attribute__ ((__deprecated__)) -#endif - -#ifndef GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_DEPRECATED_EXPORT -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_DEPRECATED_EXPORT GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_DEPRECATED -#endif - -#ifndef GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_DEPRECATED_NO_EXPORT -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_DEPRECATED_NO_EXPORT GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_NO_EXPORT GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_DEPRECATED -#endif - -#if 0 /* DEFINE_NO_DEPRECATED */ -# ifndef GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_NO_DEPRECATED -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_NO_DEPRECATED -# endif -#endif - -#endif /* GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT_H */ diff --git a/src/module/integrated/version_checking_module/SoftwareVersion.cpp b/src/module/integrated/version_checking_module/SoftwareVersion.cpp deleted file mode 100644 index 7d41b1c5..00000000 --- a/src/module/integrated/version_checking_module/SoftwareVersion.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright (C) 2021 Saturneric <[email protected]> - * - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GpgFrontend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from - * the gpg4usb project, which is under GPL-3.0-or-later. - * - * All the source code of GpgFrontend was modified and released by - * Saturneric <[email protected]> starting on May 12, 2021. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "SoftwareVersion.h" - -#include "core/utils/CommonUtils.h" -#include "module/sdk/Log.h" - -namespace GpgFrontend::Module::Integrated::VersionCheckingModule { - -auto VersionCheckingModule::SoftwareVersion::NeedUpgrade() const -> bool { - MODULE_LOG_DEBUG("compair version current {} latest {}, result {}", - current_version, latest_version, - CompareSoftwareVersion(current_version, latest_version)); - - MODULE_LOG_DEBUG("load done: {}, pre-release: {}, draft: {}", loading_done, - latest_prerelease_version_from_remote, - latest_draft_from_remote); - return loading_done && !latest_prerelease_version_from_remote && - !latest_draft_from_remote && - CompareSoftwareVersion(current_version, latest_version) < 0; -} - -auto VersionCheckingModule::SoftwareVersion::VersionWithdrawn() const -> bool { - return loading_done && !current_version_publish_in_remote && - current_version_is_a_prerelease && !current_version_is_drafted; -} - -auto VersionCheckingModule::SoftwareVersion::CurrentVersionReleased() const - -> bool { - return loading_done && current_version_publish_in_remote; -} -} // namespace GpgFrontend::Module::Integrated::VersionCheckingModule
\ No newline at end of file diff --git a/src/module/integrated/version_checking_module/VersionCheckingModule.cpp b/src/module/integrated/version_checking_module/VersionCheckingModule.cpp deleted file mode 100644 index 9b62a9c8..00000000 --- a/src/module/integrated/version_checking_module/VersionCheckingModule.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright (C) 2021 Saturneric <[email protected]> - * - * This file is part of GpgFrontend. - * - * GpgFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GpgFrontend is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from - * the gpg4usb project, which is under GPL-3.0-or-later. - * - * All the source code of GpgFrontend was modified and released by - * Saturneric <[email protected]> starting on May 12, 2021. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "VersionCheckingModule.h" - -#include "Log.h" -#include "SoftwareVersion.h" -#include "VersionCheckTask.h" -#include "core/module/Module.h" -#include "core/module/ModuleManager.h" - -namespace GpgFrontend::Module::Integrated::VersionCheckingModule { - -VersionCheckingModule::VersionCheckingModule() - : Module("com.bktus.gpgfrontend.module.integrated.version-checking", - "1.0.0", - ModuleMetaData{{"description", "try to check gpgfrontend version"}, - {"author", "saturneric"}}) {} - -VersionCheckingModule::~VersionCheckingModule() = default; - -auto VersionCheckingModule::Register() -> bool { - MODULE_LOG_INFO("version checking module registering"); - listenEvent("APPLICATION_LOADED"); - listenEvent("CHECK_APPLICATION_VERSION"); - return true; -} - -auto VersionCheckingModule::Active() -> bool { - MODULE_LOG_INFO("version checking module activating"); - return true; -} - -auto VersionCheckingModule::Exec(EventRefrernce event) -> int { - MODULE_LOG_INFO("version checking module executing, event id: {}", - event->GetIdentifier()); - - auto* task = new VersionCheckTask(); - connect(task, &VersionCheckTask::SignalUpgradeVersion, this, - &VersionCheckingModule::SignalVersionCheckDone); - connect(this, &VersionCheckingModule::SignalVersionCheckDone, this, - [this, event](SoftwareVersion version) { - SlotVersionCheckDone(std::move(version)); - event->ExecuteCallback(GetModuleIdentifier(), - TransferParams(version.loading_done)); - }); - getTaskRunner()->PostTask(task); - return 0; -} - -auto VersionCheckingModule::Deactive() -> bool { return true; } - -void VersionCheckingModule::SlotVersionCheckDone(SoftwareVersion version) { - MODULE_LOG_DEBUG("registering software information info to rt"); - UpsertRTValue(GetModuleIdentifier(), "version.current_version", - version.current_version); - UpsertRTValue(GetModuleIdentifier(), "version.latest_version", - version.latest_version); - UpsertRTValue(GetModuleIdentifier(), "version.current_version_is_drafted", - version.current_version_is_drafted); - UpsertRTValue(GetModuleIdentifier(), - "version.current_version_is_a_prerelease", - version.current_version_is_a_prerelease); - UpsertRTValue(GetModuleIdentifier(), - "version.current_version_publish_in_remote", - version.current_version_publish_in_remote); - UpsertRTValue(GetModuleIdentifier(), - "version.latest_prerelease_version_from_remote", - version.latest_prerelease_version_from_remote); - UpsertRTValue(GetModuleIdentifier(), "version.need_upgrade", - version.NeedUpgrade()); - UpsertRTValue(GetModuleIdentifier(), "version.current_version_released", - version.CurrentVersionReleased()); - UpsertRTValue(GetModuleIdentifier(), "version.current_a_withdrawn_version", - version.VersionWithdrawn()); - UpsertRTValue(GetModuleIdentifier(), "version.loading_done", - version.loading_done); - MODULE_LOG_DEBUG("register software information to rt done"); -} -} // namespace GpgFrontend::Module::Integrated::VersionCheckingModule diff --git a/src/module/integrated/gnupg_info_gathering_module/CMakeLists.txt b/src/module/mods/gpg_info/CMakeLists.txt index 48dbd0de..6759456c 100644 --- a/src/module/integrated/gnupg_info_gathering_module/CMakeLists.txt +++ b/src/module/mods/gpg_info/CMakeLists.txt @@ -23,17 +23,26 @@ # # SPDX-License-Identifier: GPL-3.0-or-later -# com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering +# com.bktus.gpgfrontend.module.integrated.gnupg_info_gathering aux_source_directory(. INTEGRATED_MODULE_SOURCE) # define libgpgfrontend_module -add_library(gpgfrontend_integrated_module_gnupg_info_gathering SHARED ${INTEGRATED_MODULE_SOURCE}) -set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendModuleExport.h") -generate_export_header(gpgfrontend_integrated_module_gnupg_info_gathering EXPORT_FILE_NAME "${_export_file}") +add_library(mod_gpg_info SHARED ${INTEGRATED_MODULE_SOURCE}) +set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GFModuleExport.h") +generate_export_header(mod_gpg_info + BASE_NAME "GF_MODULE" + EXPORT_FILE_NAME "${_export_file}") + +target_include_directories(mod_gpg_info PRIVATE + ${CMAKE_SOURCE_DIR}/third_party/spdlog/include) + +# set output directory +set_target_properties(mod_gpg_info PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mods) if (XCODE_BUILD) - set_target_properties(gpgfrontend_integrated_module_gnupg_info_gathering + set_target_properties(mod_gpg_info PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} @@ -43,11 +52,16 @@ if (XCODE_BUILD) endif () # link sdk -target_link_libraries(gpgfrontend_integrated_module_gnupg_info_gathering PRIVATE - gpgfrontend_module_sdk) +target_link_libraries(mod_gpg_info PRIVATE + gpgfrontend_module_sdk) + +# link qt +target_link_libraries(mod_gpg_info PRIVATE + Qt6::Core) + # property -set_property(TARGET gpgfrontend_integrated_module_gnupg_info_gathering PROPERTY AUTOMOC ON) +set_property(TARGET mod_gpg_info PROPERTY AUTOMOC ON) # using std c++ 17 -target_compile_features(gpgfrontend_integrated_module_gnupg_info_gathering PRIVATE cxx_std_17)
\ No newline at end of file +target_compile_features(mod_gpg_info PRIVATE cxx_std_17)
\ No newline at end of file diff --git a/src/module/mods/gpg_info/GFModuleExport.h b/src/module/mods/gpg_info/GFModuleExport.h new file mode 100644 index 00000000..a1fc1053 --- /dev/null +++ b/src/module/mods/gpg_info/GFModuleExport.h @@ -0,0 +1,42 @@ + +#ifndef GF_MODULE_EXPORT_H +#define GF_MODULE_EXPORT_H + +#ifdef GF_MODULE_STATIC_DEFINE +# define GF_MODULE_EXPORT +# define GF_MODULE_NO_EXPORT +#else +# ifndef GF_MODULE_EXPORT +# ifdef mod_gpg_info_EXPORTS + /* We are building this library */ +# define GF_MODULE_EXPORT __attribute__((visibility("default"))) +# else + /* We are using this library */ +# define GF_MODULE_EXPORT __attribute__((visibility("default"))) +# endif +# endif + +# ifndef GF_MODULE_NO_EXPORT +# define GF_MODULE_NO_EXPORT __attribute__((visibility("hidden"))) +# endif +#endif + +#ifndef GF_MODULE_DEPRECATED +# define GF_MODULE_DEPRECATED __attribute__ ((__deprecated__)) +#endif + +#ifndef GF_MODULE_DEPRECATED_EXPORT +# define GF_MODULE_DEPRECATED_EXPORT GF_MODULE_EXPORT GF_MODULE_DEPRECATED +#endif + +#ifndef GF_MODULE_DEPRECATED_NO_EXPORT +# define GF_MODULE_DEPRECATED_NO_EXPORT GF_MODULE_NO_EXPORT GF_MODULE_DEPRECATED +#endif + +#if 0 /* DEFINE_NO_DEPRECATED */ +# ifndef GF_MODULE_NO_DEPRECATED +# define GF_MODULE_NO_DEPRECATED +# endif +#endif + +#endif /* GF_MODULE_EXPORT_H */ diff --git a/src/module/mods/gpg_info/GnuPGInfoGatheringModule.cpp b/src/module/mods/gpg_info/GnuPGInfoGatheringModule.cpp new file mode 100644 index 00000000..3965c661 --- /dev/null +++ b/src/module/mods/gpg_info/GnuPGInfoGatheringModule.cpp @@ -0,0 +1,510 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GnuPGInfoGatheringModule.h" + +#include <GFSDKBasic.h> +#include <GFSDKBuildInfo.h> +#include <GFSDKLog.h> +#include <spdlog/spdlog.h> + +#include <QCryptographicHash> +#include <QFileInfo> +#include <QJsonDocument> +#include <QString> + +#include "GpgInfo.h" + +template <> +struct fmt::formatter<QString> { + // Parses format specifications. + constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + // Formats the QString qstr and writes it to the output. + template <typename FormatContext> + auto format(const QString &qstr, FormatContext &ctx) const + -> decltype(ctx.out()) { + // Convert QString to UTF-8 QString (to handle Unicode characters + // correctly) + QByteArray utf8_array = qstr.toUtf8(); + return fmt::format_to(ctx.out(), "{}", utf8_array.constData()); + } +}; + +template <> +struct fmt::formatter<QByteArray> { + // Parses format specifications. + constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + // Formats the QString qstr and writes it to the output. + template <typename FormatContext> + auto format(const QByteArray &qarray, FormatContext &ctx) const + -> decltype(ctx.out()) { + // Convert QString to UTF-8 QString (to handle Unicode characters + // correctly) + return fmt::format_to(ctx.out(), "{}", qarray.constData()); + } +}; + +extern auto CalculateBinaryChacksum(const QString &path) + -> std::optional<QString>; + +extern void GetGpgComponentInfos(void *, int, const char *, const char *); + +extern void GetGpgDirectoryInfos(void *, int, const char *, const char *); + +extern void GetGpgOptionInfos(void *, int, const char *, const char *); + +using Context = struct { + QString gpgme_version; + QString gpgconf_path; + GpgComponentInfo component_info; +}; + +auto GFGetModuleGFSDKVersion() -> const char * { + return GFModuleStrDup(GF_SDK_VERSION_STR); +} + +auto GFGetModuleQtEnvVersion() -> const char * { + return GFModuleStrDup(QT_VERSION_STR); +} + +auto GFGetModuleID() -> const char * { + return GFModuleStrDup("com.bktus.gpgfrontend.module.gnupg_info_gathering"); +} + +auto GFGetModuleVersion() -> const char * { return GFModuleStrDup("1.0.0"); } + +auto GFGetModuleMetaData() -> GFModuleMetaData * { + auto *p_meta = static_cast<GFModuleMetaData *>( + GFAllocateMemory(sizeof(GFModuleMetaData))); + auto *h_meta = p_meta; + + p_meta->key = "Name"; + p_meta->value = "GatherGnupgInfo"; + p_meta->next = static_cast<GFModuleMetaData *>( + GFAllocateMemory(sizeof(GFModuleMetaData))); + p_meta = p_meta->next; + + p_meta->key = "Description"; + p_meta->value = "Try gathering gnupg informations"; + p_meta->next = static_cast<GFModuleMetaData *>( + GFAllocateMemory(sizeof(GFModuleMetaData))); + p_meta = p_meta->next; + + p_meta->key = "Author"; + p_meta->value = "Saturneric"; + p_meta->next = nullptr; + return h_meta; +} + +auto GFRegisterModule() -> int { + GFModuleLogDebug("gnupg info gathering module registering"); + return 0; +} + +auto GFActiveModule() -> int { + GFModuleLogDebug("gnupg info gathering module activating"); + GFModuleListenEvent(GFGetModuleID(), + GFModuleStrDup("REQUEST_GATHERING_GNUPG_INFO")); + return 0; +} + +auto GFExecuteModule(GFModuleEvent *event) -> int { + GFModuleLogDebug( + fmt::format("gnupg info gathering module executing, event id: {}", + event->id) + .c_str()); + + GFModuleLogDebug("start to load extra info at module gnupginfogathering..."); + + const auto *const gpgme_version = GFModuleRetrieveRTValueOrDefault( + GFModuleStrDup("core"), GFModuleStrDup("gpgme.version"), + GFModuleStrDup("0.0.0")); + GFModuleLogDebug( + fmt::format("got gpgme version from rt: {}", gpgme_version).c_str()); + + const auto *const gpgconf_path = GFModuleRetrieveRTValueOrDefault( + GFModuleStrDup("core"), GFModuleStrDup("gpgme.ctx.gpgconf_path"), + GFModuleStrDup("")); + GFModuleLogDebug( + fmt::format("got gpgconf path from rt: {}", gpgconf_path).c_str()); + + auto context = Context{gpgme_version, gpgconf_path}; + + // get all components + const char *argv[] = {GFModuleStrDup("--list-components")}; + GFExecuteCommandSync(gpgconf_path, 1, argv, GetGpgComponentInfos, &context); + GFModuleLogDebug("load gnupg component info done."); + + QList<GFCommandExecuteContext> exec_contexts; + + const char **argv_0 = + static_cast<const char **>(GFAllocateMemory(sizeof(const char *))); + argv_0[0] = GFModuleStrDup("--list-dirs"); + + exec_contexts.push_back( + {gpgconf_path, 1, argv_0, GetGpgDirectoryInfos, nullptr}); + + char **components_c_array; + int ret = GFModuleListRTChildKeys( + GFGetModuleID(), GFModuleStrDup("gnupg.components"), &components_c_array); + if (components_c_array == nullptr || ret == 0) return -1; + + QStringList components; + auto *p_a = components_c_array; + for (int i = 0; i < ret; i++) components.append(QString::fromUtf8(p_a[i])); + + for (const auto &component : components) { + const auto *component_info_json = GFModuleRetrieveRTValueOrDefault( + GFGetModuleID(), + GFModuleStrDup(QString("gnupg.components.%1").arg(component).toUtf8()), + nullptr); + + if (component_info_json == nullptr) continue; + + auto jsonlized_component_info = + QJsonDocument::fromJson(component_info_json); + assert(jsonlized_component_info.isObject()); + + auto component_info = GpgComponentInfo(jsonlized_component_info.object()); + GFModuleLogDebug(fmt::format("gpgconf check options ready, component: {}", + component_info.name) + .c_str()); + + if (component_info.name == "gpgme" || component_info.name == "gpgconf") { + continue; + } + + auto *context = new Context{gpgme_version, gpgconf_path, component_info}; + const char **argv_0 = + static_cast<const char **>(GFAllocateMemory(sizeof(const char *) * 2)); + argv_0[0] = GFModuleStrDup("--list-options"), + argv_0[1] = GFModuleStrDup(component_info.name.toUtf8()); + exec_contexts.push_back( + {gpgconf_path, 2, argv_0, GetGpgOptionInfos, context}); + } + + GFExecuteCommandBatchSync(static_cast<int32_t>(exec_contexts.size()), + exec_contexts.constData()); + + GFModuleUpsertRTValueBool(GFGetModuleID(), + GFModuleStrDup("gnupg.gathering_done"), 1); + + char **event_argv = + static_cast<char **>(GFAllocateMemory(sizeof(char **) * 1)); + event_argv[0] = GFModuleStrDup("0"); + + GFModuleTriggerModuleEventCallback(event, GFGetModuleID(), 1, event_argv); + + GFModuleLogDebug("gnupg external info gathering done"); + return 0; +} + +auto GFDeactiveModule() -> int { return 0; } + +auto GFUnregisterModule() -> int { + GFModuleLogDebug("gnupg info gathering module unregistering"); + return 0; +} + +auto CalculateBinaryChacksum(const QString &path) -> std::optional<QString> { + // check file info and access rights + QFileInfo info(path); + if (!info.exists() || !info.isFile() || !info.isReadable()) { + GFModuleLogError(fmt::format("get info for file {} error, exists: {}", + info.filePath(), info.exists()) + .c_str()); + return {}; + } + + // open and read file + QFile f(info.filePath()); + if (!f.open(QIODevice::ReadOnly)) { + GFModuleLogError(fmt::format("open {} to calculate checksum error: {}", + path.toStdString(), + f.errorString().toStdString()) + .c_str()); + return {}; + } + + QCryptographicHash hash_sha(QCryptographicHash::Sha256); + + // read data by chunks + const qint64 buffer_size = 8192; // Define a suitable buffer size + while (!f.atEnd()) { + QByteArray buffer = f.read(buffer_size); + if (buffer.isEmpty()) { + GFModuleLogError( + fmt::format("error reading file {} during checksum calculation", + path.toStdString()) + .c_str()); + return {}; + } + hash_sha.addData(buffer); + } + + // close the file + f.close(); + + // return the first 6 characters of the SHA-256 hash of the file + return QString(hash_sha.result().toHex()).left(6); +} + +void GetGpgComponentInfos(void *data, int exit_code, const char *out, + const char *err) { + auto *context = reinterpret_cast<Context *>(data); + auto p_out = QString::fromUtf8(out); + auto p_err = QString::fromUtf8(err); + + GFModuleLogDebug( + fmt::format("gpgconf components exit_code: {} process stdout size: {}", + exit_code, p_out.size()) + .c_str()); + + if (exit_code != 0) { + GFModuleLogError(fmt::format("gpgconf execute error, process stderr: {}, " + "process stdout: {}", + p_err, p_out) + .c_str()); + return; + } + + std::vector<GpgComponentInfo> component_infos; + GpgComponentInfo c_i_gpgme; + c_i_gpgme.name = "gpgme"; + c_i_gpgme.desc = "GPG Made Easy"; + c_i_gpgme.version = context->gpgme_version; + c_i_gpgme.path = "Embedded In"; + c_i_gpgme.binary_checksum = "/"; + + GpgComponentInfo c_i_gpgconf; + c_i_gpgconf.name = "gpgconf"; + c_i_gpgconf.desc = "GPG Configure"; + c_i_gpgconf.version = "/"; + c_i_gpgconf.path = context->gpgconf_path; + auto gpgconf_binary_checksum = CalculateBinaryChacksum(context->gpgconf_path); + c_i_gpgconf.binary_checksum = + (gpgconf_binary_checksum.has_value() ? gpgconf_binary_checksum.value() + : QString("/")); + + component_infos.push_back(c_i_gpgme); + component_infos.push_back(c_i_gpgconf); + + auto const jsonlized_gpgme_component_info = c_i_gpgme.Json(); + auto const jsonlized_gpgconf_component_info = c_i_gpgconf.Json(); + GFModuleUpsertRTValue( + GFGetModuleID(), GFModuleStrDup("gnupg.components.gpgme"), + GFModuleStrDup(QJsonDocument(jsonlized_gpgme_component_info).toJson())); + GFModuleUpsertRTValue( + GFGetModuleID(), GFModuleStrDup("gnupg.components.gpgconf"), + GFModuleStrDup(QJsonDocument(jsonlized_gpgconf_component_info).toJson())); + + auto line_split_list = p_out.split("\n"); + + for (const auto &line : line_split_list) { + auto info_split_list = line.split(":"); + + if (info_split_list.size() != 3) continue; + + auto component_name = info_split_list[0].trimmed(); + auto component_desc = info_split_list[1].trimmed(); + auto component_path = info_split_list[2].trimmed(); + +#ifdef WINDOWS + // replace some special substrings on windows platform + component_path.replace("%3a", ":"); +#endif + + auto binary_checksum = CalculateBinaryChacksum(component_path); + + GFModuleLogDebug( + fmt::format("gnupg component name: {} desc: {} checksum: {} path: {} ", + component_name, component_desc, + binary_checksum.has_value() ? binary_checksum.value() : "/", + component_path) + .c_str()); + + QString version = "/"; + + if (component_name == "gpg") { + version = GFModuleRetrieveRTValueOrDefault( + GFModuleStrDup("core"), GFModuleStrDup("gpgme.ctx.gnupg_version"), + GFModuleStrDup("2.0.0")); + } + if (component_name == "gpg-agent") { + GFModuleUpsertRTValue(GFGetModuleID(), + GFModuleStrDup("gnupg.gpg_agent_path"), + GFModuleStrDup(QString(component_path).toUtf8())); + } + if (component_name == "dirmngr") { + GFModuleUpsertRTValue(GFGetModuleID(), + GFModuleStrDup("gnupg.dirmngr_path"), + GFModuleStrDup(QString(component_path).toUtf8())); + } + if (component_name == "keyboxd") { + GFModuleUpsertRTValue(GFGetModuleID(), + GFModuleStrDup("gnupg.keyboxd_path"), + GFModuleStrDup(QString(component_path).toUtf8())); + } + + { + GpgComponentInfo c_i; + c_i.name = component_name; + c_i.desc = component_desc; + c_i.version = version; + c_i.path = component_path; + c_i.binary_checksum = + (binary_checksum.has_value() ? binary_checksum.value() + : QString("/")); + + auto const jsonlized_component_info = c_i.Json(); + GFModuleUpsertRTValue( + GFGetModuleID(), + GFModuleStrDup( + QString("gnupg.components.%1").arg(component_name).toUtf8()), + GFModuleStrDup(QJsonDocument(jsonlized_component_info).toJson())); + + component_infos.push_back(c_i); + } + + GFModuleLogDebug("load gnupg component info actually done."); + } +} + +void GetGpgDirectoryInfos(void *, int exit_code, const char *out, + const char *err) { + if (exit_code != 0) return; + + auto p_out = QString::fromUtf8(out); + auto p_err = QString::fromUtf8(err); + auto line_split_list = p_out.split("\n"); + + for (const auto &line : line_split_list) { + auto info_split_list = line.split(":"); + GFModuleLogDebug( + fmt::format("gpgconf direcrotries info line: {} info size: {}", line, + info_split_list.size()) + .c_str()); + + if (info_split_list.size() != 2) continue; + + auto configuration_name = info_split_list[0].trimmed(); + auto configuration_value = info_split_list[1].trimmed(); + +#ifdef WINDOWS + // replace some special substrings on windows platform + configuration_value.replace("%3a", ":"); +#endif + + // record gnupg home path + if (configuration_name == "homedir") { + GFModuleUpsertRTValue(GFGetModuleID(), GFModuleStrDup("gnupg.home_path"), + GFModuleStrDup(configuration_value.toUtf8())); + } + + GFModuleUpsertRTValue( + GFGetModuleID(), + GFModuleStrDup( + QString("gnupg.dirs.%1").arg(configuration_name).toUtf8()), + GFModuleStrDup(configuration_value.toUtf8())); + } +} + +void GetGpgOptionInfos(void *data, int exit_code, const char *out, + const char *err) { + if (exit_code != 0) return; + + auto p_out = QString::fromUtf8(out); + auto p_err = QString::fromUtf8(err); + auto *context = reinterpret_cast<Context *>(data); + auto component_name = context->component_info.name; + + GFModuleLogDebug( + fmt::format("gpgconf {} avaliable options exit_code: {} process stdout " + "size: {} ", + component_name, exit_code, p_out.size()) + .c_str()); + + std::vector<GpgOptionsInfo> options_infos; + + auto line_split_list = p_out.split("\n"); + + for (const auto &line : line_split_list) { + auto info_split_list = line.split(":"); + + GFModuleLogDebug( + fmt::format("component {} avaliable options line: {} info size: {}", + component_name, line, info_split_list.size()) + .c_str()); + + if (info_split_list.size() < 10) continue; + + // The format of each line is: + // name:flags:level:description:type:alt-type:argname:default:argdef:value + + auto option_name = info_split_list[0].trimmed(); + auto option_flags = info_split_list[1].trimmed(); + auto option_level = info_split_list[2].trimmed(); + auto option_desc = info_split_list[3].trimmed(); + auto option_type = info_split_list[4].trimmed(); + auto option_alt_type = info_split_list[5].trimmed(); + auto option_argname = info_split_list[6].trimmed(); + auto option_default = info_split_list[7].trimmed(); + auto option_argdef = info_split_list[8].trimmed(); + auto option_value = info_split_list[9].trimmed(); + + GpgOptionsInfo info; + info.name = option_name; + info.flags = option_flags; + info.level = option_level; + info.description = option_desc; + info.type = option_type; + info.alt_type = option_alt_type; + info.argname = option_argname; + info.default_value = option_default; + info.argdef = option_argdef; + info.value = option_value; + + auto const jsonlized_option_info = info.Json(); + GFModuleUpsertRTValue( + GFGetModuleID(), + GFModuleStrDup(QString("gnupg.components.%1.options.%2") + .arg(component_name) + .arg(option_name) + .toUtf8()), + GFModuleStrDup(QJsonDocument(jsonlized_option_info).toJson())); + options_infos.push_back(info); + } + + GFFreeMemory(context); +} diff --git a/src/module/mods/gpg_info/GnuPGInfoGatheringModule.h b/src/module/mods/gpg_info/GnuPGInfoGatheringModule.h new file mode 100644 index 00000000..35ee4ac3 --- /dev/null +++ b/src/module/mods/gpg_info/GnuPGInfoGatheringModule.h @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include <GFSDKModule.h> + +#include "GFModuleExport.h" + +extern "C" { + +auto GF_MODULE_EXPORT GFGetModuleGFSDKVersion() -> const char *; + +auto GF_MODULE_EXPORT GFGetModuleQtEnvVersion() -> const char *; + +auto GF_MODULE_EXPORT GFGetModuleID() -> const char *; + +auto GF_MODULE_EXPORT GFGetModuleVersion() -> const char *; + +auto GF_MODULE_EXPORT GFGetModuleMetaData() -> GFModuleMetaData *; + +auto GF_MODULE_EXPORT GFRegisterModule() -> int; + +auto GF_MODULE_EXPORT GFActiveModule() -> int; + +auto GF_MODULE_EXPORT GFExecuteModule(GFModuleEvent *) -> int; + +auto GF_MODULE_EXPORT GFDeactiveModule() -> int; + +auto GF_MODULE_EXPORT GFUnregisterModule() -> int; +}; diff --git a/src/module/integrated/gnupg_info_gathering_module/GpgInfo.cpp b/src/module/mods/gpg_info/GpgInfo.cpp index 2015bc0a..680f4a8a 100644 --- a/src/module/integrated/gnupg_info_gathering_module/GpgInfo.cpp +++ b/src/module/mods/gpg_info/GpgInfo.cpp @@ -26,9 +26,7 @@ * */ -#include "module/integrated/gnupg_info_gathering_module/GpgInfo.h" - -namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule { +#include "GpgInfo.h" GpgOptionsInfo::GpgOptionsInfo(const QJsonObject &j) { if (const auto v = j["name"]; v.isString()) name = v.toString(); @@ -38,8 +36,9 @@ GpgOptionsInfo::GpgOptionsInfo(const QJsonObject &j) { if (const auto v = j["type"]; v.isString()) type = v.toString(); if (const auto v = j["alt_type"]; v.isString()) alt_type = v.toString(); if (const auto v = j["argname"]; v.isString()) argname = v.toString(); - if (const auto v = j["default_value"]; v.isString()) + if (const auto v = j["default_value"]; v.isString()) { default_value = v.toString(); + } if (const auto v = j["argdef"]; v.isString()) argdef = v.toString(); if (const auto v = j["value"]; v.isString()) value = v.toString(); } @@ -74,7 +73,7 @@ GpgComponentInfo::GpgComponentInfo(const QJsonObject &j) { if (const auto v = j["desc"]; v.isString()) desc = v.toString(); if (const auto v = j["version"]; v.isString()) version = v.toString(); if (const auto v = j["path"]; v.isString()) path = v.toString(); - if (const auto v = j["binary_checksum"]; v.isString()) + if (const auto v = j["binary_checksum"]; v.isString()) { binary_checksum = v.toString(); + } } -} // namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule diff --git a/src/module/integrated/gnupg_info_gathering_module/GpgInfo.h b/src/module/mods/gpg_info/GpgInfo.h index fb12b811..1aacc207 100644 --- a/src/module/integrated/gnupg_info_gathering_module/GpgInfo.h +++ b/src/module/mods/gpg_info/GpgInfo.h @@ -28,7 +28,10 @@ #pragma once -namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule { +#include <QJsonObject> +#include <QString> +#include <map> + /** * @brief Use to record some info about gnupg * @@ -83,5 +86,3 @@ struct GpgOptionsInfo { [[nodiscard]] auto Json() const -> QJsonObject; }; - -} // namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule diff --git a/src/core/log/QtLoggerFmt.h b/src/module/mods/gpg_info/QtLoggerFmt.h index e7ac2c82..23997465 100644 --- a/src/core/log/QtLoggerFmt.h +++ b/src/module/mods/gpg_info/QtLoggerFmt.h @@ -28,6 +28,10 @@ #pragma once +#include <spdlog/spdlog.h> + +#include <QString> + template <> struct fmt::formatter<QString> { // Parses format specifications. diff --git a/src/module/integrated/version_checking_module/CMakeLists.txt b/src/module/mods/ver_check/CMakeLists.txt index 76459b0e..b011410f 100644 --- a/src/module/integrated/version_checking_module/CMakeLists.txt +++ b/src/module/mods/ver_check/CMakeLists.txt @@ -23,17 +23,26 @@ # # SPDX-License-Identifier: GPL-3.0-or-later -# com.bktus.gpgfrontend.module.integrated.version-checking +# com.bktus.gpgfrontend.module.integrated.version_checking aux_source_directory(. INTEGRATED_MODULE_SOURCE) # define libgpgfrontend_module -add_library(gpgfrontend_integrated_module_version_checking SHARED ${INTEGRATED_MODULE_SOURCE}) -set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendModuleExport.h") -generate_export_header(gpgfrontend_integrated_module_version_checking EXPORT_FILE_NAME "${_export_file}") +add_library(mod_ver_check SHARED ${INTEGRATED_MODULE_SOURCE}) +set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GFModuleExport.h") +generate_export_header(mod_ver_check + BASE_NAME "GF_MODULE" + EXPORT_FILE_NAME "${_export_file}") + +target_include_directories(mod_ver_check PRIVATE + ${CMAKE_SOURCE_DIR}/third_party/spdlog/include) + +# set output directory +set_target_properties(mod_ver_check PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mods) if (XCODE_BUILD) - set_target_properties(gpgfrontend_integrated_module_version_checking + set_target_properties(mod_ver_check PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} @@ -43,19 +52,19 @@ if (XCODE_BUILD) endif () # link sdk -target_link_libraries(gpgfrontend_integrated_module_version_checking PRIVATE - gpgfrontend_module_sdk) +target_link_libraries(mod_ver_check PRIVATE + gpgfrontend_module_sdk) if(GPGFRONTEND_QT5_BUILD) # link Qt - target_link_libraries(gpgfrontend_integrated_module_version_checking PUBLIC Qt5::Network) + target_link_libraries(mod_ver_check PUBLIC Qt5::Core Qt5::Network) else() # link Qt - target_link_libraries(gpgfrontend_integrated_module_version_checking PUBLIC Qt6::Network) + target_link_libraries(mod_ver_check PUBLIC Qt6::Core Qt6::Network) endif() # property -set_property(TARGET gpgfrontend_integrated_module_version_checking PROPERTY AUTOMOC ON) +set_property(TARGET mod_ver_check PROPERTY AUTOMOC ON) # using std c++ 17 -target_compile_features(gpgfrontend_integrated_module_version_checking PRIVATE cxx_std_17)
\ No newline at end of file +target_compile_features(mod_ver_check PRIVATE cxx_std_17)
\ No newline at end of file diff --git a/src/module/mods/ver_check/GFModuleExport.h b/src/module/mods/ver_check/GFModuleExport.h new file mode 100644 index 00000000..ce663b5f --- /dev/null +++ b/src/module/mods/ver_check/GFModuleExport.h @@ -0,0 +1,42 @@ + +#ifndef GF_MODULE_EXPORT_H +#define GF_MODULE_EXPORT_H + +#ifdef GF_MODULE_STATIC_DEFINE +# define GF_MODULE_EXPORT +# define GF_MODULE_NO_EXPORT +#else +# ifndef GF_MODULE_EXPORT +# ifdef mod_ver_check_EXPORTS + /* We are building this library */ +# define GF_MODULE_EXPORT __attribute__((visibility("default"))) +# else + /* We are using this library */ +# define GF_MODULE_EXPORT __attribute__((visibility("default"))) +# endif +# endif + +# ifndef GF_MODULE_NO_EXPORT +# define GF_MODULE_NO_EXPORT __attribute__((visibility("hidden"))) +# endif +#endif + +#ifndef GF_MODULE_DEPRECATED +# define GF_MODULE_DEPRECATED __attribute__ ((__deprecated__)) +#endif + +#ifndef GF_MODULE_DEPRECATED_EXPORT +# define GF_MODULE_DEPRECATED_EXPORT GF_MODULE_EXPORT GF_MODULE_DEPRECATED +#endif + +#ifndef GF_MODULE_DEPRECATED_NO_EXPORT +# define GF_MODULE_DEPRECATED_NO_EXPORT GF_MODULE_NO_EXPORT GF_MODULE_DEPRECATED +#endif + +#if 0 /* DEFINE_NO_DEPRECATED */ +# ifndef GF_MODULE_NO_DEPRECATED +# define GF_MODULE_NO_DEPRECATED +# endif +#endif + +#endif /* GF_MODULE_EXPORT_H */ diff --git a/src/module/mods/ver_check/QtLoggerFmt.h b/src/module/mods/ver_check/QtLoggerFmt.h new file mode 100644 index 00000000..23997465 --- /dev/null +++ b/src/module/mods/ver_check/QtLoggerFmt.h @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include <spdlog/spdlog.h> + +#include <QString> + +template <> +struct fmt::formatter<QString> { + // Parses format specifications. + constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + // Formats the QString qstr and writes it to the output. + template <typename FormatContext> + auto format(const QString& qstr, FormatContext& ctx) const + -> decltype(ctx.out()) { + // Convert QString to UTF-8 QString (to handle Unicode characters + // correctly) + QByteArray utf8_array = qstr.toUtf8(); + return fmt::format_to(ctx.out(), "{}", utf8_array.constData()); + } +}; + +template <> +struct fmt::formatter<QByteArray> { + // Parses format specifications. + constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + // Formats the QString qstr and writes it to the output. + template <typename FormatContext> + auto format(const QByteArray& qarray, FormatContext& ctx) const + -> decltype(ctx.out()) { + // Convert QString to UTF-8 QString (to handle Unicode characters + // correctly) + return fmt::format_to(ctx.out(), "{}", qarray.constData()); + } +}; diff --git a/src/module/mods/ver_check/SoftwareVersion.cpp b/src/module/mods/ver_check/SoftwareVersion.cpp new file mode 100644 index 00000000..cd864195 --- /dev/null +++ b/src/module/mods/ver_check/SoftwareVersion.cpp @@ -0,0 +1,100 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "SoftwareVersion.h" + +#include <GFSDKBasic.h> +#include <GFSDKExtra.h> +#include <GFSDKLog.h> +#include <spdlog/spdlog.h> + +#include <QString> + +template <> +struct fmt::formatter<QString> { + // Parses format specifications. + constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + // Formats the QString qstr and writes it to the output. + template <typename FormatContext> + auto format(const QString& qstr, FormatContext& ctx) const + -> decltype(ctx.out()) { + // Convert QString to UTF-8 QString (to handle Unicode characters + // correctly) + QByteArray utf8_array = qstr.toUtf8(); + return fmt::format_to(ctx.out(), "{}", utf8_array.constData()); + } +}; + +template <> +struct fmt::formatter<QByteArray> { + // Parses format specifications. + constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + // Formats the QString qstr and writes it to the output. + template <typename FormatContext> + auto format(const QByteArray& qarray, FormatContext& ctx) const + -> decltype(ctx.out()) { + // Convert QString to UTF-8 QString (to handle Unicode characters + // correctly) + return fmt::format_to(ctx.out(), "{}", qarray.constData()); + } +}; + +auto SoftwareVersion::NeedUpgrade() const -> bool { + GFModuleLogDebug( + fmt::format( + "compair version current {} latest {}, result {}", current_version, + latest_version, + GFCompareSoftwareVersion(GFModuleStrDup(current_version.toUtf8()), + GFModuleStrDup(latest_version.toUtf8()))) + .c_str()); + + GFModuleLogDebug(fmt::format("load done: {}, pre-release: {}, draft: {}", + loading_done, + latest_prerelease_version_from_remote, + latest_draft_from_remote) + .c_str()); + return loading_done && !latest_prerelease_version_from_remote && + !latest_draft_from_remote && + GFCompareSoftwareVersion(GFModuleStrDup(current_version.toUtf8()), + GFModuleStrDup(latest_version.toUtf8())) < 0; +} + +auto SoftwareVersion::VersionWithdrawn() const -> bool { + return loading_done && !current_version_publish_in_remote && + current_version_is_a_prerelease && !current_version_is_drafted; +} + +auto SoftwareVersion::CurrentVersionReleased() const -> bool { + return loading_done && current_version_publish_in_remote; +}
\ No newline at end of file diff --git a/src/module/integrated/version_checking_module/SoftwareVersion.h b/src/module/mods/ver_check/SoftwareVersion.h index 43f718fa..6b05d413 100644 --- a/src/module/integrated/version_checking_module/SoftwareVersion.h +++ b/src/module/mods/ver_check/SoftwareVersion.h @@ -28,9 +28,8 @@ #pragma once -#include <module/sdk/GpgFrontendModuleSDK.h> +#include <QString> -namespace GpgFrontend::Module::Integrated::VersionCheckingModule { /** * @brief * @@ -53,7 +52,7 @@ struct SoftwareVersion { * @return true * @return false */ - [[nodiscard]] bool InfoValid() const { return loading_done; } + [[nodiscard]] auto InfoValid() const -> bool { return loading_done; } /** * @brief @@ -61,7 +60,7 @@ struct SoftwareVersion { * @return true * @return false */ - [[nodiscard]] bool NeedUpgrade() const; + [[nodiscard]] auto NeedUpgrade() const -> bool; /** * @brief @@ -69,7 +68,7 @@ struct SoftwareVersion { * @return true * @return false */ - [[nodiscard]] bool VersionWithdrawn() const; + [[nodiscard]] auto VersionWithdrawn() const -> bool; /** * @brief @@ -77,9 +76,8 @@ struct SoftwareVersion { * @return true * @return false */ - [[nodiscard]] bool CurrentVersionReleased() const; + [[nodiscard]] auto CurrentVersionReleased() const -> bool; private: - static int version_compare(const QString& a, const QString& b); + static auto version_compare(const QString& a, const QString& b) -> int; }; -} // namespace GpgFrontend::Module::Integrated::VersionCheckingModule diff --git a/src/module/integrated/version_checking_module/VersionCheckTask.cpp b/src/module/mods/ver_check/VersionCheckTask.cpp index e81fc92d..5ea9c48e 100644 --- a/src/module/integrated/version_checking_module/VersionCheckTask.cpp +++ b/src/module/mods/ver_check/VersionCheckTask.cpp @@ -28,31 +28,29 @@ #include "VersionCheckTask.h" +#include <GFSDKBasic.h> +#include <GFSDKExtra.h> +#include <GFSDKLog.h> + #include <QMetaType> #include <QtNetwork> -#include "GpgFrontendBuildInfo.h" - -namespace GpgFrontend::Module::Integrated::VersionCheckingModule { - VersionCheckTask::VersionCheckTask() - : Task("version_check_task"), - network_manager_(new QNetworkAccessManager(this)), - current_version_(QString("v") + VERSION_MAJOR + "." + VERSION_MINOR + - "." + VERSION_PATCH) { - HoldOnLifeCycle(true); + : network_manager_(new QNetworkAccessManager(this)), + current_version_(GFProjectVersion()) { qRegisterMetaType<SoftwareVersion>("SoftwareVersion"); version_.current_version = current_version_; } auto VersionCheckTask::Run() -> int { - MODULE_LOG_DEBUG("current project version: {}", current_version_); + GFModuleLogDebug( + fmt::format("current project version: {}", current_version_).c_str()); QString latest_version_url = "https://api.github.com/repos/saturneric/gpgfrontend/releases/latest"; QNetworkRequest latest_request(latest_version_url); latest_request.setHeader(QNetworkRequest::UserAgentHeader, - HTTP_REQUEST_USER_AGENT); + GFHttpRequestUserAgent()); latest_reply_ = network_manager_->get(latest_request); connect(latest_reply_, &QNetworkReply::finished, this, @@ -65,8 +63,9 @@ void VersionCheckTask::slot_parse_latest_version_info() { version_.latest_version = current_version_; version_.loading_done = false; } else if (latest_reply_->error() != QNetworkReply::NoError) { - MODULE_LOG_ERROR("latest version request error: ", - latest_reply_->errorString()); + GFModuleLogError(fmt::format("latest version request error: ", + latest_reply_->errorString()) + .c_str()); version_.latest_version = current_version_; } else { latest_reply_bytes_ = latest_reply_->readAll(); @@ -79,11 +78,15 @@ void VersionCheckTask::slot_parse_latest_version_info() { auto version_match = re.match(latest_version); if (version_match.hasMatch()) { latest_version = version_match.captured(0); - MODULE_LOG_INFO("latest version from github: {}", latest_version); + GFModuleLogInfo(fmt::format("latest released version from github: {}", + latest_version) + .c_str()); } else { latest_version = current_version_; - MODULE_LOG_WARN("latest version unknown, set to current version: {}", - current_version_); + GFModuleLogWarn( + fmt::format("latest version unknown, set to current version: {}", + current_version_) + .c_str()); } bool prerelease = latest_reply_json["prerelease"].toBool(); @@ -96,8 +99,9 @@ void VersionCheckTask::slot_parse_latest_version_info() { version_.publish_date = publish_date; version_.release_note = release_note; } else { - MODULE_LOG_WARN("cannot parse data got from github: {}", - latest_reply_bytes_); + GFModuleLogWarn(fmt::format("cannot parse data got from github: {}", + latest_reply_bytes_) + .c_str()); } } @@ -109,19 +113,20 @@ void VersionCheckTask::slot_parse_latest_version_info() { QString current_version_url = "https://api.github.com/repos/saturneric/gpgfrontend/releases/tags/" + current_version_; - MODULE_LOG_DEBUG("current version info query url: {}", current_version_url); + GFModuleLogDebug( + fmt::format("current version info query url: {}", current_version_url) + .c_str()); QNetworkRequest current_request(current_version_url); current_request.setHeader(QNetworkRequest::UserAgentHeader, - HTTP_REQUEST_USER_AGENT); + GFHttpRequestUserAgent()); current_reply_ = network_manager_->get(current_request); connect(current_reply_, &QNetworkReply::finished, this, &VersionCheckTask::slot_parse_current_version_info); } catch (...) { - MODULE_LOG_ERROR("current version request create error"); - emit SignalTaskShouldEnd(-1); + GFModuleLogError("current version request create error"); } } @@ -131,8 +136,9 @@ void VersionCheckTask::slot_parse_current_version_info() { version_.loading_done = false; } else if (current_reply_->error() != QNetworkReply::NoError) { - MODULE_LOG_ERROR("current version request network error: {}", - current_reply_->errorString()); + GFModuleLogError(fmt::format("current version request network error: {}", + current_reply_->errorString()) + .c_str()); // loading done version_.loading_done = true; @@ -150,17 +156,16 @@ void VersionCheckTask::slot_parse_current_version_info() { // loading done version_.loading_done = true; } else { - MODULE_LOG_WARN("cannot parse data got from github: {}", - current_reply_bytes_); + GFModuleLogWarn(fmt::format("cannot parse data got from github: {}", + current_reply_bytes_) + .c_str()); } } - MODULE_LOG_DEBUG("current version parse done: {}", - version_.current_version_publish_in_remote); + GFModuleLogDebug(fmt::format("current version parse done: {}", + version_.current_version_publish_in_remote) + .c_str()); if (current_reply_ != nullptr) current_reply_->deleteLater(); emit SignalUpgradeVersion(version_); - emit SignalTaskShouldEnd(0); } - -} // namespace GpgFrontend::Module::Integrated::VersionCheckingModule diff --git a/src/module/integrated/version_checking_module/VersionCheckTask.h b/src/module/mods/ver_check/VersionCheckTask.h index f5091819..df801570 100644 --- a/src/module/integrated/version_checking_module/VersionCheckTask.h +++ b/src/module/mods/ver_check/VersionCheckTask.h @@ -29,20 +29,17 @@ #pragma once #include <core/thread/Task.h> -#include <module/sdk/GpgFrontendModuleSDK.h> #include "SoftwareVersion.h" class QNetworkReply; class QNetworkAccessManager; -namespace GpgFrontend::Module::Integrated::VersionCheckingModule { - /** * @brief * */ -class VersionCheckTask : public Thread::Task { +class VersionCheckTask : public QObject { Q_OBJECT public: /** @@ -51,22 +48,21 @@ class VersionCheckTask : public Thread::Task { */ VersionCheckTask(); - signals: - /** * @brief * - * @param version + * @return int */ - void SignalUpgradeVersion(SoftwareVersion version); + auto Run() -> int; + + signals: - protected: /** * @brief - * + * @param version */ - auto Run() -> int override; + void SignalUpgradeVersion(SoftwareVersion version); private slots: @@ -91,6 +87,3 @@ class VersionCheckTask : public Thread::Task { QString current_version_; SoftwareVersion version_; }; - -} // namespace GpgFrontend::Module::Integrated::VersionCheckingModule - // GpgFrontend::Module::Custom::IntegradedModule::VersionCheckingModule diff --git a/src/module/mods/ver_check/VersionCheckingModule.cpp b/src/module/mods/ver_check/VersionCheckingModule.cpp new file mode 100644 index 00000000..35d3b82e --- /dev/null +++ b/src/module/mods/ver_check/VersionCheckingModule.cpp @@ -0,0 +1,164 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "VersionCheckingModule.h" + +#include <GFSDKBasic.h> +#include <GFSDKBuildInfo.h> +#include <GFSDKExtra.h> +#include <GFSDKLog.h> +#include <spdlog/spdlog.h> + +#include <QMetaType> +#include <QtNetwork> + +#include "SoftwareVersion.h" +#include "VersionCheckTask.h" + +extern void VersionCheckDone(const SoftwareVersion& version); + +auto GFGetModuleGFSDKVersion() -> const char* { + return GFModuleStrDup(GF_SDK_VERSION_STR); +} + +auto GFGetModuleQtEnvVersion() -> const char* { + return GFModuleStrDup(QT_VERSION_STR); +} + +auto GFGetModuleID() -> const char* { + return GFModuleStrDup("com.bktus.gpgfrontend.module.version_checking"); +} + +auto GFGetModuleVersion() -> const char* { return GFModuleStrDup("1.0.0"); } + +auto GFGetModuleMetaData() -> GFModuleMetaData* { + auto* p_meta = static_cast<GFModuleMetaData*>( + GFAllocateMemory(sizeof(GFModuleMetaData))); + auto* h_meta = p_meta; + + p_meta->key = "Name"; + p_meta->value = "VersionChecking"; + p_meta->next = static_cast<GFModuleMetaData*>( + GFAllocateMemory(sizeof(GFModuleMetaData))); + p_meta = p_meta->next; + + p_meta->key = "Description"; + p_meta->value = "Try checking gpgfrontend version"; + p_meta->next = static_cast<GFModuleMetaData*>( + GFAllocateMemory(sizeof(GFModuleMetaData))); + p_meta = p_meta->next; + + p_meta->key = "Author"; + p_meta->value = "Saturneric"; + p_meta->next = nullptr; + + return h_meta; +} + +auto GFRegisterModule() -> int { + GFModuleLogInfo("version checking module registering"); + return 0; +} + +auto GFActiveModule() -> int { + GFModuleLogInfo("version checking module activating"); + + GFModuleListenEvent(GFGetModuleID(), GFModuleStrDup("APPLICATION_LOADED")); + GFModuleListenEvent(GFGetModuleID(), + GFModuleStrDup("CHECK_APPLICATION_VERSION")); + return 0; +} + +auto GFExecuteModule(GFModuleEvent* event) -> int { + GFModuleLogInfo( + fmt::format("version checking module executing, event id: {}", event->id) + .c_str()); + + auto* task = new VersionCheckTask(); + QObject::connect( + task, &VersionCheckTask::SignalUpgradeVersion, QThread::currentThread(), + [event](const SoftwareVersion& version) { + VersionCheckDone(version); + + char** event_argv = + static_cast<char**>(GFAllocateMemory(sizeof(char**) * 1)); + event_argv[0] = GFModuleStrDup("0"); + + GFModuleTriggerModuleEventCallback(event, GFGetModuleID(), 1, + event_argv); + }); + QObject::connect(task, &VersionCheckTask::SignalUpgradeVersion, task, + &QObject::deleteLater); + task->Run(); + + return 0; +} + +auto GFDeactiveModule() -> int { return 0; } + +auto GFUnregisterModule() -> int { return 0; } + +void VersionCheckDone(const SoftwareVersion& version) { + GFModuleLogDebug("filling software information info in rt..."); + + GFModuleUpsertRTValue(GFGetModuleID(), + GFModuleStrDup("version.current_version"), + GFModuleStrDup(version.current_version.toUtf8())); + GFModuleUpsertRTValue(GFGetModuleID(), + GFModuleStrDup("version.latest_version"), + GFModuleStrDup(version.latest_version.toUtf8())); + GFModuleUpsertRTValueBool( + GFGetModuleID(), GFModuleStrDup("version.current_version_is_drafted"), + version.current_version_is_drafted ? 1 : 0); + GFModuleUpsertRTValueBool( + GFGetModuleID(), + GFModuleStrDup("version.current_version_is_a_prerelease"), + version.current_version_is_a_prerelease ? 1 : 0); + GFModuleUpsertRTValueBool( + GFGetModuleID(), + GFModuleStrDup("version.current_version_publish_in_remote"), + version.current_version_publish_in_remote ? 1 : 0); + GFModuleUpsertRTValueBool( + GFGetModuleID(), + GFModuleStrDup("version.latest_prerelease_version_from_remote"), + version.latest_prerelease_version_from_remote ? 1 : 0); + GFModuleUpsertRTValueBool(GFGetModuleID(), + GFModuleStrDup("version.need_upgrade"), + version.NeedUpgrade() ? 1 : 0); + GFModuleUpsertRTValueBool(GFGetModuleID(), + GFModuleStrDup("version.current_version_released"), + version.CurrentVersionReleased() ? 1 : 0); + GFModuleUpsertRTValueBool( + GFGetModuleID(), GFModuleStrDup("version.current_a_withdrawn_version"), + version.VersionWithdrawn() ? 1 : 0); + GFModuleUpsertRTValueBool(GFGetModuleID(), + GFModuleStrDup("version.loading_done"), + version.loading_done ? 1 : 0); + + GFModuleLogDebug("software information filled in rt"); +} diff --git a/src/module/mods/ver_check/VersionCheckingModule.h b/src/module/mods/ver_check/VersionCheckingModule.h new file mode 100644 index 00000000..35ee4ac3 --- /dev/null +++ b/src/module/mods/ver_check/VersionCheckingModule.h @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include <GFSDKModule.h> + +#include "GFModuleExport.h" + +extern "C" { + +auto GF_MODULE_EXPORT GFGetModuleGFSDKVersion() -> const char *; + +auto GF_MODULE_EXPORT GFGetModuleQtEnvVersion() -> const char *; + +auto GF_MODULE_EXPORT GFGetModuleID() -> const char *; + +auto GF_MODULE_EXPORT GFGetModuleVersion() -> const char *; + +auto GF_MODULE_EXPORT GFGetModuleMetaData() -> GFModuleMetaData *; + +auto GF_MODULE_EXPORT GFRegisterModule() -> int; + +auto GF_MODULE_EXPORT GFActiveModule() -> int; + +auto GF_MODULE_EXPORT GFExecuteModule(GFModuleEvent *) -> int; + +auto GF_MODULE_EXPORT GFDeactiveModule() -> int; + +auto GF_MODULE_EXPORT GFUnregisterModule() -> int; +}; diff --git a/src/module/sdk/GFSDK.h b/src/module/sdk/GFSDK.h new file mode 100644 index 00000000..77e019af --- /dev/null +++ b/src/module/sdk/GFSDK.h @@ -0,0 +1,44 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include "GFSDKExport.h" + +extern "C" { + +void GPGFRONTEND_MODULE_SDK_EXPORT GFModuleLogTrace(const char*); + +void GPGFRONTEND_MODULE_SDK_EXPORT GFModuleLogDebug(const char*); + +void GPGFRONTEND_MODULE_SDK_EXPORT GFModuleLogInfo(const char*); + +void GPGFRONTEND_MODULE_SDK_EXPORT GFModuleLogWarn(const char*); + +void GPGFRONTEND_MODULE_SDK_EXPORT GFModuleLogError(const char*); +}
\ No newline at end of file diff --git a/src/module/sdk/GFSDKBasic.cpp b/src/module/sdk/GFSDKBasic.cpp new file mode 100644 index 00000000..ac0b74d2 --- /dev/null +++ b/src/module/sdk/GFSDKBasic.cpp @@ -0,0 +1,99 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GFSDKBasic.h" + +#include "core/function/SecureMemoryAllocator.h" +#include "core/function/gpg/GpgCommandExecutor.h" +#include "core/utils/BuildInfoUtils.h" +#include "core/utils/CommonUtils.h" + +auto GFAllocateMemory(uint32_t size) -> void* { + return GpgFrontend::SecureMemoryAllocator::Allocate(size); +} + +void GFFreeMemory(void* ptr) { + return GpgFrontend::SecureMemoryAllocator::Deallocate(ptr); +} + +auto GFProjectVersion() -> const char* { + return GpgFrontend::GFStrDup(GpgFrontend::GetProjectVersion()); +} + +auto GFQtEnvVersion() -> const char* { + return GpgFrontend::GFStrDup(QT_VERSION_STR); +} + +void GFExecuteCommandSync(const char* cmd, int32_t argc, const char** argv, + GFCommandExeucteCallback cb, void* data) { + QStringList args; + for (int i = 0; i < argc; i++) { + args.append(GpgFrontend::GFUnStrDup(argv[i])); + } + + GpgFrontend::GpgCommandExecutor::ExecuteContext context{ + cmd, args, [=](int exit_code, const QString& out, const QString& err) { + cb(data, exit_code, out.toUtf8(), err.toUtf8()); + }}; + + GpgFrontend::GpgCommandExecutor::ExecuteSync(context); +} + +void GFExecuteCommandBatchSync(int32_t context_size, + const GFCommandExecuteContext* context) { + QList<GpgFrontend::GpgCommandExecutor::ExecuteContext> contexts; + + for (int i = 0; i < context_size; i++) { + const auto& exec_context = context[i]; + + QStringList args; + const char** argv = exec_context.argv; + for (int j = 0; j < exec_context.argc; j++) { + args.append(GpgFrontend::GFUnStrDup(argv[j])); + } + + contexts.append( + {exec_context.cmd, args, + [data = exec_context.data, cb = exec_context.cb]( + int exit_code, const QString& out, const QString& err) { + cb(data, exit_code, out.toUtf8(), err.toUtf8()); + }}); + } + + GpgFrontend::GpgCommandExecutor::ExecuteConcurrentlySync(contexts); +} + +auto GPGFRONTEND_MODULE_SDK_EXPORT GFModuleStrDup(const char* src) -> char* { + auto len = strlen(src); + + char* dst = static_cast<char*>(GFAllocateMemory((len + 1) * sizeof(char))); + memcpy(dst, src, len); + dst[len] = '\0'; + + return dst; +}
\ No newline at end of file diff --git a/src/module/sdk/GFSDKBasic.h b/src/module/sdk/GFSDKBasic.h new file mode 100644 index 00000000..ad6302d0 --- /dev/null +++ b/src/module/sdk/GFSDKBasic.h @@ -0,0 +1,104 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include <stdint.h> + +#include "GFSDKExport.h" + +extern "C" { + +using GFCommandExeucteCallback = void (*)(void* data, int errcode, + const char* out, const char* err); + +using GFCommandExecuteContext = struct { + const char* cmd; + int32_t argc; + const char** argv; + GFCommandExeucteCallback cb; + void* data; +}; + +/** + * @brief + * + * @param size + * @return void* + */ +auto GPGFRONTEND_MODULE_SDK_EXPORT GFAllocateMemory(uint32_t size) -> void*; + +/** + * @brief + * + * @return const char* + */ +auto GPGFRONTEND_MODULE_SDK_EXPORT GFProjectVersion() -> const char*; + +/** + * @brief + * + * @return const char* + */ +auto GPGFRONTEND_MODULE_SDK_EXPORT GFQtEnvVersion() -> const char*; + +/** + * @brief + * + */ +void GPGFRONTEND_MODULE_SDK_EXPORT GFFreeMemory(void*); + +/** + * @brief + * + * @param cmd + * @param argc + * @param argv + * @param cb + * @param data + */ +void GPGFRONTEND_MODULE_SDK_EXPORT +GFExecuteCommandSync(const char* cmd, int32_t argc, const char** argv, + GFCommandExeucteCallback cb, void* data); + +/** + * @brief + * + * @param context_size + * @param context + */ +void GPGFRONTEND_MODULE_SDK_EXPORT GFExecuteCommandBatchSync( + int32_t context_size, const GFCommandExecuteContext* context); + +/** + * @brief + * + * @return char* + */ +auto GPGFRONTEND_MODULE_SDK_EXPORT GFModuleStrDup(const char*) -> char*; +}
\ No newline at end of file diff --git a/src/module/sdk/Basic.h b/src/module/sdk/GFSDKBuildInfo.h index 62a547b3..aea49f03 100644 --- a/src/module/sdk/Basic.h +++ b/src/module/sdk/GFSDKBuildInfo.h @@ -28,9 +28,9 @@ #pragma once -namespace GpgFrontend::Module::SDK { +#define GF_SDK_VERSION_MAJOR "2" +#define GF_SDK_VERSION_MINOR "1" +#define GF_SDK_VERSION_PATCH "2" - - - -}
\ No newline at end of file +#define GF_SDK_VERSION_STR \ + GF_SDK_VERSION_MAJOR "." GF_SDK_VERSION_MINOR "." GF_SDK_VERSION_PATCH diff --git a/src/module/sdk/GpgFrontendModuleSDK.h b/src/module/sdk/GFSDKBuildInfo.h.in index 97769462..508c35d4 100644 --- a/src/module/sdk/GpgFrontendModuleSDK.h +++ b/src/module/sdk/GFSDKBuildInfo.h.in @@ -28,6 +28,9 @@ #pragma once -#include <core/module/GpgFrontendModuleSystem.h> -#include <module/sdk/GpgFrontendModuleSDKExport.h> -#include <module/sdk/Log.h>
\ No newline at end of file +#define GF_SDK_VERSION_MAJOR "@CMAKE_PROJECT_VERSION_MAJOR@" +#define GF_SDK_VERSION_MINOR "@CMAKE_PROJECT_VERSION_MINOR@" +#define GF_SDK_VERSION_PATCH "@CMAKE_PROJECT_VERSION_PATCH@" + +#define GF_SDK_VERSION_STR \ + GF_SDK_VERSION_MAJOR "." GF_SDK_VERSION_MINOR "." GF_SDK_VERSION_PATCH
\ No newline at end of file diff --git a/src/module/sdk/GpgFrontendModuleSDKExport.h b/src/module/sdk/GFSDKExport.h index a62168bc..a62168bc 100644 --- a/src/module/sdk/GpgFrontendModuleSDKExport.h +++ b/src/module/sdk/GFSDKExport.h diff --git a/src/module/sdk/Log.cpp b/src/module/sdk/GFSDKExtra.cpp index 384fac1d..bbfa8575 100644 --- a/src/module/sdk/Log.cpp +++ b/src/module/sdk/GFSDKExtra.cpp @@ -26,11 +26,17 @@ * */ -#include "Log.h" +#include "GFSDKExtra.h" +#include "core/utils/BuildInfoUtils.h" +#include "core/utils/CommonUtils.h" -#include <stdexcept> - -#include "core/function/GlobalSettingStation.h" - -namespace GpgFrontend::Module::SDK {} // namespace GpgFrontend::Module::SDK +auto GFCompareSoftwareVersion(const char *current_version, + const char *latest_version) -> int { + return GpgFrontend::GFCompareSoftwareVersion( + GpgFrontend::GFUnStrDup(current_version), + GpgFrontend::GFUnStrDup(latest_version)); +} +auto GFHttpRequestUserAgent() -> const char * { + return GpgFrontend::GFStrDup(GpgFrontend::GetHttpRequestUserAgent()); +}
\ No newline at end of file diff --git a/src/module/GpgFrontendModule.h b/src/module/sdk/GFSDKExtra.h index cf7d8557..3d7f4226 100644 --- a/src/module/GpgFrontendModule.h +++ b/src/module/sdk/GFSDKExtra.h @@ -28,9 +28,12 @@ #pragma once -/** - * Project internal dependencies - */ -#include "GpgFrontend.h" -#include "GpgFrontendModuleExport.h" -#include "core/GpgFrontendCore.h" +#include "GFSDKExport.h" + +extern "C" { + +auto GPGFRONTEND_MODULE_SDK_EXPORT GFCompareSoftwareVersion( + const char *current_version, const char *latest_version) -> int; + +auto GPGFRONTEND_MODULE_SDK_EXPORT GFHttpRequestUserAgent() -> const char *; +}
\ No newline at end of file diff --git a/src/module/sdk/Basic.cpp b/src/module/sdk/GFSDKGpg.cpp index 63859763..63859763 100644 --- a/src/module/sdk/Basic.cpp +++ b/src/module/sdk/GFSDKGpg.cpp diff --git a/src/module/sdk/UI.cpp b/src/module/sdk/GFSDKGpg.h index 63859763..8823bfc5 100644 --- a/src/module/sdk/UI.cpp +++ b/src/module/sdk/GFSDKGpg.h @@ -24,4 +24,10 @@ * * SPDX-License-Identifier: GPL-3.0-or-later * - */
\ No newline at end of file + */ + +#pragma once + +extern "C" { + +}
\ No newline at end of file diff --git a/src/module/sdk/Log.h b/src/module/sdk/GFSDKLog.cpp index 0c40a097..603cc325 100644 --- a/src/module/sdk/Log.h +++ b/src/module/sdk/GFSDKLog.cpp @@ -26,10 +26,9 @@ * */ -#pragma once +#include "GFSDKLog.h" #include "core/utils/LogUtils.h" -#include "module/sdk/GpgFrontendModuleSDK.h" #define MODULE_LOG_TRACE(...) GF_LOG_TRACE("module", __VA_ARGS__) #define MODULE_LOG_DEBUG(...) GF_LOG_DEBUG("module", __VA_ARGS__) @@ -37,35 +36,12 @@ #define MODULE_LOG_WARN(...) GF_LOG_WARN("module", __VA_ARGS__) #define MODULE_LOG_ERROR(...) GF_LOG_ERROR("module", __VA_ARGS__) -namespace spdlog { -class logger; -} +void GFModuleLogTrace(const char* l) { MODULE_LOG_TRACE(l); } -namespace GpgFrontend::Module::SDK { +void GFModuleLogDebug(const char* l) { MODULE_LOG_DEBUG(l); } -template <typename... Args> -void ModuleLogTrace(const char* fmt, const Args&... args) { - MODULE_LOG_TRACE(fmt, args...); -} +void GFModuleLogInfo(const char* l) { MODULE_LOG_INFO(l); } -template <typename... Args> -void ModuleLogDebug(const char* fmt, const Args&... args) { - MODULE_LOG_DEBUG(fmt, args...); -} +void GFModuleLogWarn(const char* l) { MODULE_LOG_WARN(l); } -template <typename... Args> -void ModuleLogInfo(const char* fmt, const Args&... args) { - MODULE_LOG_INFO(fmt, args...); -} - -template <typename... Args> -void ModuleLogWarn(const char* fmt, const Args&... args) { - MODULE_LOG_WARN(fmt, args...); -} - -template <typename... Args> -void ModuleLogError(const char* fmt, const Args&... args) { - MODULE_LOG_ERROR(fmt, args...); -} - -} // namespace GpgFrontend::Module::SDK +void GFModuleLogError(const char* l) { MODULE_LOG_ERROR(l); } diff --git a/src/module/sdk/GFSDKLog.h b/src/module/sdk/GFSDKLog.h new file mode 100644 index 00000000..77e019af --- /dev/null +++ b/src/module/sdk/GFSDKLog.h @@ -0,0 +1,44 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include "GFSDKExport.h" + +extern "C" { + +void GPGFRONTEND_MODULE_SDK_EXPORT GFModuleLogTrace(const char*); + +void GPGFRONTEND_MODULE_SDK_EXPORT GFModuleLogDebug(const char*); + +void GPGFRONTEND_MODULE_SDK_EXPORT GFModuleLogInfo(const char*); + +void GPGFRONTEND_MODULE_SDK_EXPORT GFModuleLogWarn(const char*); + +void GPGFRONTEND_MODULE_SDK_EXPORT GFModuleLogError(const char*); +}
\ No newline at end of file diff --git a/src/module/sdk/GFSDKModule.cpp b/src/module/sdk/GFSDKModule.cpp new file mode 100644 index 00000000..1eea578a --- /dev/null +++ b/src/module/sdk/GFSDKModule.cpp @@ -0,0 +1,98 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GFSDKModule.h" + +#include <core/module/ModuleManager.h> +#include <core/utils/CommonUtils.h> + +#include "GFSDKBasic.h" + +void GFModuleListenEvent(const char *module_id, const char *event_id) { + return GpgFrontend::Module::ModuleManager::GetInstance().ListenEvent( + GpgFrontend::GFUnStrDup(module_id).toLower(), + GpgFrontend::GFUnStrDup(event_id).toUpper()); +} + +auto GFModuleRetrieveRTValueOrDefault(const char *namespace_, const char *key, + const char *default_value) -> const + char * { + return GpgFrontend::GFStrDup( + GpgFrontend::Module::RetrieveRTValueTypedOrDefault( + GpgFrontend::GFUnStrDup(namespace_), GpgFrontend::GFUnStrDup(key), + GpgFrontend::GFUnStrDup(default_value))); +} + +void GFModuleUpsertRTValue(const char *namespace_, const char *key, + const char *vaule) { + GpgFrontend::Module::UpsertRTValue( + GpgFrontend::GFUnStrDup(namespace_).toLower(), + GpgFrontend::GFUnStrDup(key).toLower(), GpgFrontend::GFUnStrDup(vaule)); +} + +void GFModuleUpsertRTValueBool(const char *namespace_, const char *key, + int value) { + GpgFrontend::Module::UpsertRTValue( + GpgFrontend::GFUnStrDup(namespace_).toLower(), + GpgFrontend::GFUnStrDup(key).toLower(), value != 0); +} + +auto GFModuleListRTChildKeys(const char *namespace_, const char *key, + char ***child_keys) -> int32_t { + *child_keys = nullptr; + auto keys = GpgFrontend::Module::ListRTChildKeys( + GpgFrontend::GFUnStrDup(namespace_).toLower(), + GpgFrontend::GFUnStrDup(key).toLower()); + + if (keys.empty()) return 0; + + *child_keys = + static_cast<char **>(GFAllocateMemory(sizeof(char **) * keys.size())); + + for (int i = 0; i < keys.size(); i++) { + (*child_keys)[i] = GpgFrontend::GFStrDup(keys[i]); + } + + return static_cast<int32_t>(keys.size()); +} + +void GFModuleTriggerModuleEventCallback(GFModuleEvent *module_event, + const char *module_id, int argc, + char **argv) { + auto data_object = GpgFrontend::TransferParams(); + for (int i = 0; i < argc; i++) { + data_object->AppendObject(GpgFrontend::GFUnStrDup(argv[i])); + } + + auto event = GpgFrontend::Module::ModuleManager::GetInstance().SearchEvent( + GpgFrontend::GFUnStrDup(module_event->triggger_id).toLower()); + if (!event) return; + + event.value()->ExecuteCallback(GpgFrontend::GFUnStrDup(module_id), + data_object); +}
\ No newline at end of file diff --git a/src/module/sdk/GFSDKModule.h b/src/module/sdk/GFSDKModule.h new file mode 100644 index 00000000..4df07762 --- /dev/null +++ b/src/module/sdk/GFSDKModule.h @@ -0,0 +1,94 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include "GFSDKExport.h" + +extern "C" { + +#include <stdint.h> + +struct GFModuleMetaData { + const char *key; + const char *value; + GFModuleMetaData *next; +}; + +struct GFModuleEventParam { + const char *name; + const char *value; + GFModuleEventParam *next; +}; + +struct GFModuleEvent { + const char *id; + const char *triggger_id; + GFModuleEventParam *params; +}; + +using GFModuleAPIGetModuleGFSDKVersion = auto (*)() -> const char *; + +using GFModuleAPIGetModuleQtEnvVersion = auto (*)() -> const char *; + +using GFModuleAPIGetModuleID = auto (*)() -> const char *; + +using GFModuleAPIGetModuleVersion = auto (*)() -> const char *; + +using GFModuleAPIGetModuleMetaData = auto (*)() -> GFModuleMetaData *; + +using GFModuleAPIRegisterModule = auto (*)() -> int; + +using GFModuleAPIActivateModule = auto (*)() -> int; + +using GFModuleAPIExecuteModule = auto (*)(GFModuleEvent *) -> int; + +using GFModuleAPIDeactivateModule = auto (*)() -> int; + +using GFModuleAPIUnregisterModule = auto (*)() -> int; + +void GPGFRONTEND_MODULE_SDK_EXPORT GFModuleListenEvent(const char *module_id, + const char *event_id); + +auto GPGFRONTEND_MODULE_SDK_EXPORT GFModuleRetrieveRTValueOrDefault( + const char *namespace_, const char *key, const char *default_value) -> const + char *; + +void GPGFRONTEND_MODULE_SDK_EXPORT GFModuleUpsertRTValue(const char *namespace_, + const char *key, + const char *vaule); + +void GPGFRONTEND_MODULE_SDK_EXPORT +GFModuleUpsertRTValueBool(const char *namespace_, const char *key, int value); + +auto GPGFRONTEND_MODULE_SDK_EXPORT GFModuleListRTChildKeys( + const char *namespace_, const char *key, char ***child_keys) -> int32_t; + +void GPGFRONTEND_MODULE_SDK_EXPORT GFModuleTriggerModuleEventCallback( + GFModuleEvent *event, const char *module_id, int argc, char **argv); +};
\ No newline at end of file diff --git a/src/module/sdk/Gpg.cpp b/src/module/sdk/GFSDKUI.cpp index 63859763..63859763 100644 --- a/src/module/sdk/Gpg.cpp +++ b/src/module/sdk/GFSDKUI.cpp diff --git a/src/module/sdk/Gpg.h b/src/module/sdk/GFSDKUI.h index 0702632a..0702632a 100644 --- a/src/module/sdk/Gpg.h +++ b/src/module/sdk/GFSDKUI.h diff --git a/src/module/sdk/UI.h b/src/module/sdk/GFSDKUtils.cpp index 0702632a..fcb510e3 100644 --- a/src/module/sdk/UI.h +++ b/src/module/sdk/GFSDKUtils.cpp @@ -26,4 +26,4 @@ * */ -#pragma once
\ No newline at end of file +#include "GFSDKUtils.h"
\ No newline at end of file diff --git a/src/module/sdk/GFSDKUtils.h b/src/module/sdk/GFSDKUtils.h new file mode 100644 index 00000000..7d72e9ee --- /dev/null +++ b/src/module/sdk/GFSDKUtils.h @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +extern "C" { + + +}
\ No newline at end of file diff --git a/src/pinentry/CMakeLists.txt b/src/pinentry/CMakeLists.txt index 3145719a..9a6a9e03 100644 --- a/src/pinentry/CMakeLists.txt +++ b/src/pinentry/CMakeLists.txt @@ -50,25 +50,3 @@ target_link_libraries(gpgfrontend_pinentry PRIVATE spdlog) # using std c++ 17 target_compile_features(gpgfrontend_pinentry PUBLIC cxx_std_17) - -# link for different platforms -if (MINGW) - message(STATUS "Link GPG Static Library For MINGW") - target_link_libraries(gpgfrontend_pinentry PUBLIC wsock32) -elseif (APPLE) - message(STATUS "Link GPG Static Library For macOS") - target_link_libraries(gpgfrontend_pinentry PUBLIC dl) - if (XCODE_BUILD) - set_target_properties(gpgfrontend_pinentry - PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} - XCODE_ATTRIBUTE_SKIP_INSTALL "Yes" - XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}") - endif () -else () - # linux - message(STATUS "Link GPG Static Library For Unix") - target_link_libraries(gpgfrontend_pinentry PUBLIC pthread dl) -endif () diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 3f0686e2..e6b41b50 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -36,7 +36,7 @@ aux_source_directory(thread UI_SOURCE) aux_source_directory(dialog/details UI_SOURCE) aux_source_directory(struct UI_SOURCE) aux_source_directory(dialog/import_export UI_SOURCE) -aux_source_directory(dialog/gnupg UI_SOURCE) +aux_source_directory(dialog/controller UI_SOURCE) aux_source_directory(dialog UI_SOURCE) aux_source_directory(function UI_SOURCE) @@ -54,7 +54,7 @@ if(GPGFRONTEND_QT5_BUILD) else() # link Qt target_link_libraries(gpgfrontend_ui - Qt6::Core Qt6::Widgets Qt6::Network Qt6::PrintSupport Qt6::Core5Compat) + Qt6::Core Qt6::Widgets Qt6::Network Qt6::PrintSupport) endif() diff --git a/src/ui/GpgFrontendApplication.cpp b/src/ui/GpgFrontendApplication.cpp index c832ffe0..b3c12de6 100644 --- a/src/ui/GpgFrontendApplication.cpp +++ b/src/ui/GpgFrontendApplication.cpp @@ -28,9 +28,7 @@ #include "ui/GpgFrontendApplication.h" -#include <QTextCodec> - -#include "GpgFrontendBuildInfo.h" +#include "core/utils/BuildInfoUtils.h" namespace GpgFrontend::UI { @@ -42,17 +40,16 @@ GpgFrontendApplication::GpgFrontendApplication(int &argc, char *argv[]) #endif // set the extra information of the build - GpgFrontendApplication::setApplicationVersion(BUILD_VERSION); - GpgFrontendApplication::setApplicationName(PROJECT_NAME); - GpgFrontendApplication::setApplicationDisplayName(PROJECT_NAME); - GpgFrontendApplication::setOrganizationName(PROJECT_NAME); + GpgFrontendApplication::setApplicationVersion(GetProjectBuildVersion()); + GpgFrontendApplication::setApplicationName(QString::fromUtf8((PROJECT_NAME))); + GpgFrontendApplication::setApplicationDisplayName( + QString::fromUtf8((PROJECT_NAME))); + GpgFrontendApplication::setOrganizationName( + QString::fromUtf8((PROJECT_NAME))); GpgFrontendApplication::setQuitOnLastWindowClosed(true); // don't show icons in menus GpgFrontendApplication::setAttribute(Qt::AA_DontShowIconsInMenus); - - // unicode in source - QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf-8")); } bool GpgFrontendApplication::notify(QObject *receiver, QEvent *event) { diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp index 9daca57b..1fd5c3bb 100644 --- a/src/ui/UserInterfaceUtils.cpp +++ b/src/ui/UserInterfaceUtils.cpp @@ -30,25 +30,25 @@ #include <cstddef> -#include "GpgFrontendBuildInfo.h" #include "core/GpgConstants.h" #include "core/function/CoreSignalStation.h" #include "core/function/gpg/GpgKeyGetter.h" +#include "core/model/CacheObject.h" #include "core/model/GpgImportInformation.h" +#include "core/model/SettingsObject.h" #include "core/module/ModuleManager.h" #include "core/thread/Task.h" #include "core/thread/TaskRunnerGetter.h" #include "core/typedef/GpgTypedef.h" +#include "core/utils/BuildInfoUtils.h" #include "core/utils/GpgUtils.h" #include "core/utils/IOUtils.h" #include "thread/KeyServerImportTask.h" #include "ui/UISignalStation.h" #include "ui/dialog/WaitingDialog.h" -#include "ui/dialog/gnupg/GnuPGControllerDialog.h" +#include "ui/dialog/controller/GnuPGControllerDialog.h" #include "ui/dialog/import_export/KeyServerImportDialog.h" -#include "ui/struct/CacheObject.h" -#include "ui/struct/SettingsObject.h" -#include "ui/struct/settings/KeyServerSO.h" +#include "ui/struct/settings_object/KeyServerSO.h" #include "ui/widgets/TextEdit.h" namespace GpgFrontend::UI { @@ -431,7 +431,7 @@ void CommonUtils::SlotImportKeyFromKeyServer( // Waiting for reply auto request = QNetworkRequest(req_url); request.setHeader(QNetworkRequest::UserAgentHeader, - HTTP_REQUEST_USER_AGENT); + GetHttpRequestUserAgent()); QNetworkReply *reply = network_manager->get(request); QEventLoop loop; diff --git a/src/ui/dialog/GeneralDialog.cpp b/src/ui/dialog/GeneralDialog.cpp index 386573a3..2015322f 100644 --- a/src/ui/dialog/GeneralDialog.cpp +++ b/src/ui/dialog/GeneralDialog.cpp @@ -28,8 +28,8 @@ #include "GeneralDialog.h" -#include "ui/struct/SettingsObject.h" -#include "ui/struct/settings/WindowStateSO.h" +#include "core/model/SettingsObject.h" +#include "ui/struct/settings_object/WindowStateSO.h" namespace GpgFrontend { diff --git a/src/ui/dialog/SignersPicker.h b/src/ui/dialog/SignersPicker.h index c7e1bfa5..cea8dd9a 100644 --- a/src/ui/dialog/SignersPicker.h +++ b/src/ui/dialog/SignersPicker.h @@ -56,13 +56,13 @@ class SignersPicker : public GeneralDialog { * * @return GpgFrontend::KeyIdArgsListPtr */ - KeyIdArgsListPtr GetCheckedSigners(); + auto GetCheckedSigners() -> KeyIdArgsListPtr; /** * * @return */ - [[nodiscard]] bool GetStatus() const; + [[nodiscard]] auto GetStatus() const -> bool; private: KeyList* key_list_; ///< diff --git a/src/ui/dialog/gnupg/GnuPGControllerDialog.cpp b/src/ui/dialog/controller/GnuPGControllerDialog.cpp index f1fa87e2..f1fa87e2 100644 --- a/src/ui/dialog/gnupg/GnuPGControllerDialog.cpp +++ b/src/ui/dialog/controller/GnuPGControllerDialog.cpp diff --git a/src/ui/dialog/gnupg/GnuPGControllerDialog.h b/src/ui/dialog/controller/GnuPGControllerDialog.h index 6e8ef797..6e8ef797 100644 --- a/src/ui/dialog/gnupg/GnuPGControllerDialog.h +++ b/src/ui/dialog/controller/GnuPGControllerDialog.h diff --git a/src/ui/dialog/controller/ModuleControllerDialog.cpp b/src/ui/dialog/controller/ModuleControllerDialog.cpp new file mode 100644 index 00000000..f7b335dd --- /dev/null +++ b/src/ui/dialog/controller/ModuleControllerDialog.cpp @@ -0,0 +1,148 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "ModuleControllerDialog.h" + +#include "core/model/SettingsObject.h" +#include "core/struct/settings_object/ModuleSO.h" +#include "ui_ModuleControllerDialog.h" + +// +#include "core/module/ModuleManager.h" +#include "ui/widgets/ModuleListView.h" + +namespace GpgFrontend::UI { + +ModuleControllerDialog::ModuleControllerDialog(QWidget* parent) + : QDialog(parent), + ui_(std::make_shared<Ui_ModuleControllerDialog>()), + module_manager_(&Module::ModuleManager::GetInstance()) { + ui_->setupUi(this); + + connect(ui_->moduleListView, &ModuleListView::SignalSelectModule, this, + &ModuleControllerDialog::slot_load_module_details); + + connect(ui_->activateOrDeactiveButton, &QPushButton::clicked, this, [=]() { + auto module_id = ui_->moduleListView->GetCurrentModuleID(); + if (module_id.isEmpty()) return; + + if (!module_manager_->IsModuleActivated(module_id)) { + module_manager_->ActiveModule(module_id); + } else { + module_manager_->DeactiveModule(module_id); + } + + QTimer::singleShot(1000, [=]() { slot_load_module_details(module_id); }); + }); + + connect(ui_->autoActivateButton, &QPushButton::clicked, this, [=]() { + auto module_id = ui_->moduleListView->GetCurrentModuleID(); + SettingsObject so(QString("module.%1.so").arg(module_id)); + ModuleSO module_so(so); + + module_so.auto_activate = + ui_->autoActivateButton->text() == tr("Enable Auto Activate"); + so.Store(module_so.ToJson()); + + QTimer::singleShot(1000, [=]() { slot_load_module_details(module_id); }); + }); + + connect(ui_->triggerEventButton, &QPushButton::clicked, this, [=]() { + auto event_id = + QInputDialog::getText(this, "Please provide an Event ID", "Event ID"); + Module::TriggerEvent(event_id); + }); +} + +void ModuleControllerDialog::slot_load_module_details( + Module::ModuleIdentifier module_id) { + GF_UI_LOG_DEBUG("loading module details, module id: {}", module_id); + auto module = module_manager_->SearchModule(module_id); + SettingsObject so(QString("module.%1.so").arg(module_id)); + ModuleSO module_so(so); + + if (module_so.module_id != module_id || + module_so.module_hash != module->GetModuleHash()) { + module_so.module_id = module_id; + module_so.module_hash = module->GetModuleHash(); + module_so.auto_activate = false; + GF_UI_LOG_DEBUG("reseting module settings object, module id: {}", + module_id); + so.Store(module_so.ToJson()); + } + + QString buffer; + QTextStream info(&buffer); + + info << "# BASIC INFO" << Qt::endl << Qt::endl; + + info << " - " << tr("ID") << ": " << module->GetModuleIdentifier() + << Qt::endl; + info << " - " << tr("Version") << ": " << module->GetModuleVersion() + << Qt::endl; + info << " - " << tr("SDK Version") << ": " << module->GetModuleSDKVersion() + << Qt::endl; + info << " - " << tr("Qt ENV Version") << ": " + << module->GetModuleQtEnvVersion() << Qt::endl; + info << " - " << tr("Hash") << ": " << module->GetModuleHash() << Qt::endl; + info << " - " << tr("Path") << ": " << module->GetModulePath() << Qt::endl; + + bool if_activated = module_manager_->IsModuleActivated(module_id); + + info << " - " << tr("Auto Activate") << ": " + << (module_so.auto_activate ? tr("True") : tr("False")) << Qt::endl; + info << " - " << tr("Active") << ": " + << (if_activated ? tr("True") : tr("False")) << Qt::endl; + + info << Qt::endl; + + info << "# METADATA" << Qt::endl << Qt::endl; + + for (const auto& metadata : module->GetModuleMetaData().asKeyValueRange()) { + info << " - " << metadata.first << ": " << metadata.second << "\n"; + } + + info << Qt::endl; + + if (if_activated) { + info << "# Listening Event" << Qt::endl << Qt::endl; + + auto listening_event_ids = module_manager_->GetModuleListening(module_id); + for (const auto& event_id : listening_event_ids) { + info << " - " << event_id << "\n"; + } + } + + ui_->moduleInfoTextBrowser->setText(buffer); + ui_->activateOrDeactiveButton->setText(if_activated ? tr("Deactivate") + : tr("Activate")); + ui_->autoActivateButton->setText(module_so.auto_activate + ? tr("Disable Auto Activate") + : tr("Enable Auto Activate")); +} +} // namespace GpgFrontend::UI diff --git a/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h b/src/ui/dialog/controller/ModuleControllerDialog.h index 88f64d7d..6ded4808 100644 --- a/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h +++ b/src/ui/dialog/controller/ModuleControllerDialog.h @@ -28,28 +28,34 @@ #pragma once -#include "GpgFrontendModuleExport.h" #include "core/module/Module.h" -namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule { +class Ui_ModuleControllerDialog; -/** - * @brief Use to record some info about gnupg - * - */ -class GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT - GnuPGInfoGatheringModule : public Module { - public: - GnuPGInfoGatheringModule(); - - ~GnuPGInfoGatheringModule() override; +namespace GpgFrontend::UI { - auto Register() -> bool override; +class ModuleListView; - auto Active() -> bool override; - - auto Exec(EventRefrernce) -> int override; - - auto Deactive() -> bool override; +class ModuleControllerDialog : public QDialog { + Q_OBJECT + public: + /** + * @brief Construct a new Module Controller Dialog object + * + * @param parent + */ + explicit ModuleControllerDialog(QWidget* parent); + + private slots: + /** + * @brief + * + */ + void slot_load_module_details(Module::ModuleIdentifier); + + private: + std::shared_ptr<Ui_ModuleControllerDialog> ui_; ///< + Module::ModuleManager* module_manager_; }; -} // namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule + +} // namespace GpgFrontend::UI diff --git a/src/ui/dialog/help/AboutDialog.cpp b/src/ui/dialog/help/AboutDialog.cpp index 61b01dfe..ddc17fe7 100644 --- a/src/ui/dialog/help/AboutDialog.cpp +++ b/src/ui/dialog/help/AboutDialog.cpp @@ -30,32 +30,46 @@ #include <openssl/opensslv.h> -#include "GpgFrontendBuildInfo.h" #include "core/module/ModuleManager.h" +#include "core/utils/BuildInfoUtils.h" #include "ui/dialog/help/GnupgTab.h" namespace GpgFrontend::UI { -AboutDialog::AboutDialog(int defaultIndex, QWidget* parent) +AboutDialog::AboutDialog(const QString& default_tab_name, QWidget* parent) : GeneralDialog(typeid(AboutDialog).name(), parent) { this->setWindowTitle(tr("About") + " " + qApp->applicationName()); auto* tab_widget = new QTabWidget; auto* info_tab = new InfoTab(); - auto* gnupg_tab = new GnupgTab(); auto* translators_tab = new TranslatorsTab(); - update_tab_ = new UpdateTab(); tab_widget->addTab(info_tab, tr("About GpgFrontend")); - tab_widget->addTab(gnupg_tab, tr("GnuPG")); + + if (Module::IsModuleActivate(kGnuPGInfoGatheringModuleID)) { + auto* gnupg_tab = new GnupgTab(); + tab_widget->addTab(gnupg_tab, tr("GnuPG")); + } + tab_widget->addTab(translators_tab, tr("Translators")); - tab_widget->addTab(update_tab_, tr("Update")); + + if (Module::IsModuleActivate(kVersionCheckingModuleID)) { + auto* update_tab = new UpdateTab(); + tab_widget->addTab(update_tab, tr("Update")); + } connect(tab_widget, &QTabWidget::currentChanged, this, [&](int index) { GF_UI_LOG_DEBUG("current index: {}", index); }); - if (defaultIndex < tab_widget->count() && defaultIndex >= 0) { - tab_widget->setCurrentIndex(defaultIndex); + int default_index = 0; + for (int i = 0; i < tab_widget->count(); i++) { + if (tab_widget->tabText(i) == default_tab_name) { + default_index = i; + } + } + + if (default_index < tab_widget->count() && default_index >= 0) { + tab_widget->setCurrentIndex(default_index); } auto* button_box = new QDialogButtonBox(QDialogButtonBox::Ok); @@ -84,7 +98,7 @@ InfoTab::InfoTab(QWidget* parent) : QWidget(parent) { auto text = "<center><h2>" + qApp->applicationName() + "</h2></center>" + "<center><b>" + qApp->applicationVersion() + "</b></center>" + - "<center>" + GIT_VERSION + "</center>" + "<br><center>" + + "<center>" + GetProjectBuildGitVersion() + "</center>" + "<br><center>" + tr("GpgFrontend is an easy-to-use, compact, cross-platform, " "and installation-free GnuPG Frontend." "It visualizes most of the common operations of GnuPG." @@ -99,7 +113,8 @@ InfoTab::InfoTab(QWidget* parent) : QWidget(parent) { "href=\"mailto:[email protected]\">[email protected]</a>." + "<br><br> " + tr("Built with Qt") + " " + qVersion() + ", " + OPENSSL_VERSION_TEXT + " " + tr("and") + " " + "GPGME" + " " + gpgme_version + "<br>" + - tr("Built at") + " " + BUILD_TIMESTAMP + "</center>"; + tr("Built at") + " " + QLocale().toString(GetProjectBuildTimestamp()) + + "</center>"; auto* layout = new QGridLayout(); auto* pixmap_label = new QLabel(); @@ -140,8 +155,7 @@ TranslatorsTab::TranslatorsTab(QWidget* parent) : QWidget(parent) { UpdateTab::UpdateTab(QWidget* parent) : QWidget(parent) { auto* layout = new QGridLayout(); - current_version_ = - QString("v") + VERSION_MAJOR + "." + VERSION_MINOR + "." + VERSION_PATCH; + current_version_ = GetProjectVersion(); auto* tips_label = new QLabel(); tips_label->setText( @@ -189,17 +203,15 @@ void UpdateTab::showEvent(QShowEvent* event) { GF_UI_LOG_DEBUG("loading version loading info from rt"); auto is_loading_done = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.version-checking", - "version.loading_done", false); + kVersionCheckingModuleID, "version.loading_done", false); if (!is_loading_done) { Module::ListenRTPublishEvent( - this, "com.bktus.gpgfrontend.module.integrated.version-checking", - "version.loading_done", + this, kVersionCheckingModuleID, "version.loading_done", [=](Module::Namespace, Module::Key, int, std::any) { GF_UI_LOG_DEBUG( - "versionchecking version.loading_done changed, calling slot " - "version upgrade"); + "version_checking module version.loading_done changed, calling " + "slot version upgrade"); this->slot_show_version_status(); }); Module::TriggerEvent("CHECK_APPLICATION_VERSION"); @@ -213,29 +225,24 @@ void UpdateTab::slot_show_version_status() { this->pb_->setHidden(true); auto is_loading_done = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.version-checking", - "version.loading_done", false); + kVersionCheckingModuleID, "version.loading_done", false); if (!is_loading_done) { - GF_UI_LOG_DEBUG("version info loading havn't been done yet."); + GF_UI_LOG_DEBUG("version info loading haven't been done yet."); return; } auto is_need_upgrade = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.version-checking", - "version.need_upgrade", false); + kVersionCheckingModuleID, "version.need_upgrade", false); auto is_current_a_withdrawn_version = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.version-checking", - "version.current_a_withdrawn_version", false); + kVersionCheckingModuleID, "version.current_a_withdrawn_version", false); auto is_current_version_released = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.version-checking", - "version.current_version_released", false); + kVersionCheckingModuleID, "version.current_version_released", false); auto latest_version = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.version-checking", - "version.latest_version", QString{}); + kVersionCheckingModuleID, "version.latest_version", QString{}); latest_version_label_->setText("<center><b>" + tr("Latest Version From Github") + ": " + diff --git a/src/ui/dialog/help/AboutDialog.h b/src/ui/dialog/help/AboutDialog.h index b7871a29..6d152afb 100644 --- a/src/ui/dialog/help/AboutDialog.h +++ b/src/ui/dialog/help/AboutDialog.h @@ -120,7 +120,7 @@ class AboutDialog : public GeneralDialog { * @param defaultIndex * @param parent */ - explicit AboutDialog(int defaultIndex, QWidget* parent); + explicit AboutDialog(const QString& default_tab_name, QWidget* parent); protected: /** @@ -129,9 +129,6 @@ class AboutDialog : public GeneralDialog { * @param ev */ void showEvent(QShowEvent* ev) override; - - private: - UpdateTab* update_tab_; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/help/GnupgTab.cpp b/src/ui/dialog/help/GnupgTab.cpp index 1aceed1a..3dfdd994 100644 --- a/src/ui/dialog/help/GnupgTab.cpp +++ b/src/ui/dialog/help/GnupgTab.cpp @@ -35,7 +35,9 @@ #include "core/module/ModuleManager.h" #include "ui_GnuPGInfo.h" -GpgFrontend::UI::GnupgTab::GnupgTab(QWidget* parent) +namespace GpgFrontend::UI { + +GnupgTab::GnupgTab(QWidget* parent) : QWidget(parent), ui_(GpgFrontend::SecureCreateSharedObject<Ui_GnuPGInfo>()) { ui_->setupUi(this); @@ -103,10 +105,15 @@ GpgFrontend::UI::GnupgTab::GnupgTab(QWidget* parent) ui_->optionDetailsTable->setFocusPolicy(Qt::NoFocus); ui_->optionDetailsTable->setAlternatingRowColors(true); - process_software_info(); + if (Module::RetrieveRTValueTypedOrDefault( + "ui", "env.state.gnupg_info_gathering", 0) == 1) { + process_software_info(); + } else { + gather_gnupg_info(); + } } -void GpgFrontend::UI::GnupgTab::process_software_info() { +void GnupgTab::process_software_info() { const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>( "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"}); GF_UI_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version); @@ -114,9 +121,8 @@ void GpgFrontend::UI::GnupgTab::process_software_info() { ui_->gnupgVersionLabel->setText( QString::fromStdString(fmt::format("Version: {}", gnupg_version))); - auto components = Module::ListRTChildKeys( - "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering", - "gnupg.components"); + auto components = + Module::ListRTChildKeys(kGnuPGInfoGatheringModuleID, "gnupg.components"); GF_UI_LOG_DEBUG("got gnupg components from rt, size: {}", components.size()); ui_->componentDetailsTable->setRowCount(components.size()); @@ -124,12 +130,12 @@ void GpgFrontend::UI::GnupgTab::process_software_info() { int row = 0; for (auto& component : components) { auto component_info_json_bytes = Module::RetrieveRTValueTypedOrDefault( - "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering", - QString("gnupg.components.%1").arg(component), QByteArray{}); + kGnuPGInfoGatheringModuleID, + QString("gnupg.components.%1").arg(component), QString{}); GF_UI_LOG_DEBUG("got gnupg component {} info from rt", component); auto component_info_json = - QJsonDocument::fromJson(component_info_json_bytes); + QJsonDocument::fromJson(component_info_json_bytes.toUtf8()); if (!component_info_json.isObject()) { GF_UI_LOG_WARN("illegal gnupg component info, json: {}", QString(component_info_json_bytes)); @@ -170,17 +176,16 @@ void GpgFrontend::UI::GnupgTab::process_software_info() { ui_->componentDetailsTable->resizeColumnsToContents(); - auto directories = Module::ListRTChildKeys( - "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering", - QString("gnupg.dirs")); + auto directories = Module::ListRTChildKeys(kGnuPGInfoGatheringModuleID, + QString("gnupg.dirs")); ui_->directoriesDetailsTable->setRowCount(directories.size()); row = 0; for (auto& dir : directories) { const auto dir_path = Module::RetrieveRTValueTypedOrDefault( - "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering", - QString("gnupg.dirs.%1").arg(dir), QString{}); + kGnuPGInfoGatheringModuleID, QString("gnupg.dirs.%1").arg(dir), + QString{}); if (dir_path.isEmpty()) continue; @@ -201,16 +206,17 @@ void GpgFrontend::UI::GnupgTab::process_software_info() { row = 0; for (auto& component : components) { auto options = Module::ListRTChildKeys( - "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering", + kGnuPGInfoGatheringModuleID, QString("gnupg.components.%1.options").arg(component)); for (auto& option : options) { const auto option_info_json = QJsonDocument::fromJson(Module::RetrieveRTValueTypedOrDefault( - "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering", - QString("gnupg.components.%1.options.%2") - .arg(component) - .arg(option), - QByteArray{})); + kGnuPGInfoGatheringModuleID, + QString("gnupg.components.%1.options.%2") + .arg(component) + .arg(option), + QString{}) + .toUtf8()); if (!option_info_json.isObject()) continue; @@ -228,18 +234,19 @@ void GpgFrontend::UI::GnupgTab::process_software_info() { QString configuration_group; for (auto& component : components) { auto options = Module::ListRTChildKeys( - "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering", + kGnuPGInfoGatheringModuleID, QString("gnupg.components.%1.options").arg(component)); for (auto& option : options) { auto option_info_json_bytes = Module::RetrieveRTValueTypedOrDefault( - "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering", + kGnuPGInfoGatheringModuleID, QString("gnupg.components.%1.options.%2").arg(component).arg(option), - QByteArray{}); + QString{}); GF_UI_LOG_DEBUG("got gnupg component's option {} info from rt, info: {}", component, option_info_json_bytes); - auto option_info_json = QJsonDocument::fromJson(option_info_json_bytes); + auto option_info_json = + QJsonDocument::fromJson(option_info_json_bytes.toUtf8()); if (!option_info_json.isObject()) { GF_UI_LOG_WARN("illegal gnupg option info, json: {}", @@ -291,3 +298,33 @@ void GpgFrontend::UI::GnupgTab::process_software_info() { } // ui_->configurationDetailsTable->resizeColumnsToContents(); } + +void GnupgTab::gather_gnupg_info() { + // if gnupg_info_gathering module activated + if (Module::IsModuleActivate(kGnuPGInfoGatheringModuleID)) { + GF_CORE_LOG_DEBUG( + "module gnupg_info_gathering is activated, " + "loading external gnupg info..."); + + // gather external gnupg info + Module::TriggerEvent( + "REQUEST_GATHERING_GNUPG_INFO", + [=](const Module::EventIdentifier& /*e*/, + const Module::Event::ListenerIdentifier& l_id, DataObjectPtr o) { + GF_CORE_LOG_DEBUG( + "received event REQUEST_GATHERING_GNUPG_INFO callback " + "from module: {}", + l_id); + + if (l_id == kGnuPGInfoGatheringModuleID) { + Module::UpsertRTValue("ui", "env.state.gnupg_info_gathering", 1); + + // gnupg info gathering process finished + GF_CORE_LOG_INFO("gnupg information gathering finished"); + process_software_info(); + } + }); + } +} + +} // namespace GpgFrontend::UI
\ No newline at end of file diff --git a/src/ui/dialog/help/GnupgTab.h b/src/ui/dialog/help/GnupgTab.h index 9e6191db..60abd048 100644 --- a/src/ui/dialog/help/GnupgTab.h +++ b/src/ui/dialog/help/GnupgTab.h @@ -50,6 +50,16 @@ class GnupgTab : public QWidget { private: std::shared_ptr<Ui_GnuPGInfo> ui_; ///< + /** + * @brief + * + */ void process_software_info(); + + /** + * @brief + * + */ + void gather_gnupg_info(); }; } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/import_export/KeyServerImportDialog.cpp b/src/ui/dialog/import_export/KeyServerImportDialog.cpp index 296df539..575a97e4 100644 --- a/src/ui/dialog/import_export/KeyServerImportDialog.cpp +++ b/src/ui/dialog/import_export/KeyServerImportDialog.cpp @@ -28,14 +28,12 @@ #include "KeyServerImportDialog.h" -#include <QRegExp> - #include "core/GpgModel.h" #include "core/function/GlobalSettingStation.h" #include "core/function/gpg/GpgKeyImportExporter.h" +#include "core/model/SettingsObject.h" #include "ui/UISignalStation.h" -#include "ui/struct/SettingsObject.h" -#include "ui/struct/settings/KeyServerSO.h" +#include "ui/struct/settings_object/KeyServerSO.h" #include "ui/thread/KeyServerImportTask.h" #include "ui/thread/KeyServerSearchTask.h" @@ -243,11 +241,14 @@ void KeyServerImportDialog::slot_search_finished( set_message("<h4>" + tr("Too many responses from keyserver!") + "</h4>", true); return; - } else if (text.contains("No keys found")) { + } + + if (text.contains("No keys found")) { + auto query = search_line_edit_->text(); + // if string looks like hex string, search again with 0x prepended - QRegExp rx("[0-9A-Fa-f]*"); - QString query = search_line_edit_->text(); - if (rx.exactMatch(query)) { + QRegularExpression rx("[0-9A-Fa-f]*"); + if (rx.match(query).hasMatch()) { set_message("<h4>" + tr("No keys found, input may be kexId, retrying search " "with 0x.") + @@ -257,102 +258,104 @@ void KeyServerImportDialog::slot_search_finished( this->slot_search(); return; } + set_message( "<h4>" + tr("No keys found containing the search string!") + "</h4>", true); return; + } - } else if (text.contains("Insufficiently specific words")) { + if (text.contains("Insufficiently specific words")) { set_message( "<h4>" + tr("Insufficiently specific search string!") + "</h4>", true); return; - } else { - set_message(text, true); - return; } - } else { - int row = 0; - bool strikeout = false; - - // read lines until end of steam - while (!stream.atEnd()) { - QStringList line = - QString::fromUtf8(QByteArray::fromPercentEncoding( - stream.readLine().trimmed().toUtf8())) - .split(":"); - - // TODO: have a look at two following pub lines - if (line[0] == "pub") { - strikeout = false; - - QString flags = line[line.size() - 1]; - keys_table_->setRowCount(row + 1); - - // flags can be "d" for disabled, "r" for revoked - // or "e" for expired - if (flags.contains("r") or flags.contains("d") or flags.contains("e")) { - strikeout = true; - if (flags.contains("e")) { - keys_table_->setItem(row, 3, - new QTableWidgetItem(QString("expired"))); - } - if (flags.contains("r")) { - keys_table_->setItem(row, 3, new QTableWidgetItem(tr("revoked"))); - } - if (flags.contains("d")) { - keys_table_->setItem(row, 3, new QTableWidgetItem(tr("disabled"))); - } - } - QStringList line2 = QString(QByteArray::fromPercentEncoding( - stream.readLine().trimmed().toUtf8())) - .split(":"); + set_message(text, true); + return; + } - auto* uid = new QTableWidgetItem(); - if (line2.size() > 1) { - uid->setText(line2[1]); - keys_table_->setItem(row, 0, uid); + int row = 0; + bool strikeout = false; + + // read lines until end of steam + while (!stream.atEnd()) { + QStringList line = + QString::fromUtf8(QByteArray::fromPercentEncoding( + stream.readLine().trimmed().toUtf8())) + .split(":"); + + // TODO: have a look at two following pub lines + if (line[0] == "pub") { + strikeout = false; + + QString flags = line[line.size() - 1]; + keys_table_->setRowCount(row + 1); + + // flags can be "d" for disabled, "r" for revoked + // or "e" for expired + if (flags.contains("r") or flags.contains("d") or flags.contains("e")) { + strikeout = true; + if (flags.contains("e")) { + keys_table_->setItem(row, 3, + new QTableWidgetItem(QString("expired"))); + } + if (flags.contains("r")) { + keys_table_->setItem(row, 3, new QTableWidgetItem(tr("revoked"))); + } + if (flags.contains("d")) { + keys_table_->setItem(row, 3, new QTableWidgetItem(tr("disabled"))); } - auto* creation_date = - new QTableWidgetItem(QDateTime::fromSecsSinceEpoch(line[4].toInt()) - .toString("dd. MMM. yyyy")); - keys_table_->setItem(row, 1, creation_date); - auto* keyid = new QTableWidgetItem(line[1]); - keys_table_->setItem(row, 2, keyid); + } + + QStringList line2 = QString(QByteArray::fromPercentEncoding( + stream.readLine().trimmed().toUtf8())) + .split(":"); + + auto* uid = new QTableWidgetItem(); + if (line2.size() > 1) { + uid->setText(line2[1]); + keys_table_->setItem(row, 0, uid); + } + auto* creation_date = + new QTableWidgetItem(QDateTime::fromSecsSinceEpoch(line[4].toInt()) + .toString("dd. MMM. yyyy")); + keys_table_->setItem(row, 1, creation_date); + auto* keyid = new QTableWidgetItem(line[1]); + keys_table_->setItem(row, 2, keyid); + if (strikeout) { + QFont strike = uid->font(); + strike.setStrikeOut(true); + uid->setFont(strike); + creation_date->setFont(strike); + keyid->setFont(strike); + } + row++; + } else { + if (line[0] == "uid") { + QStringList l; + int height = keys_table_->rowHeight(row - 1); + keys_table_->setRowHeight(row - 1, height + 16); + QString tmp = keys_table_->item(row - 1, 0)->text(); + tmp.append(QString("\n") + line[1]); + auto* tmp1 = new QTableWidgetItem(tmp); + keys_table_->setItem(row - 1, 0, tmp1); if (strikeout) { - QFont strike = uid->font(); + QFont strike = tmp1->font(); strike.setStrikeOut(true); - uid->setFont(strike); - creation_date->setFont(strike); - keyid->setFont(strike); - } - row++; - } else { - if (line[0] == "uid") { - QStringList l; - int height = keys_table_->rowHeight(row - 1); - keys_table_->setRowHeight(row - 1, height + 16); - QString tmp = keys_table_->item(row - 1, 0)->text(); - tmp.append(QString("\n") + line[1]); - auto* tmp1 = new QTableWidgetItem(tmp); - keys_table_->setItem(row - 1, 0, tmp1); - if (strikeout) { - QFont strike = tmp1->font(); - strike.setStrikeOut(true); - tmp1->setFont(strike); - } + tmp1->setFont(strike); } } - set_message( - QString("<h4>") + - tr("%1 keys found. Double click a key to import it.").arg(row) + - "</h4>", - false); } - keys_table_->resizeColumnsToContents(); - import_button_->setDisabled(keys_table_->size().isEmpty()); + set_message( + QString("<h4>") + + tr("%1 keys found. Double click a key to import it.").arg(row) + + "</h4>", + false); } + keys_table_->resizeColumnsToContents(); + import_button_->setDisabled(keys_table_->size().isEmpty()); } void KeyServerImportDialog::slot_import() { diff --git a/src/ui/dialog/import_export/KeyUploadDialog.cpp b/src/ui/dialog/import_export/KeyUploadDialog.cpp index 0e0dca4d..7ab34c49 100644 --- a/src/ui/dialog/import_export/KeyUploadDialog.cpp +++ b/src/ui/dialog/import_export/KeyUploadDialog.cpp @@ -30,14 +30,14 @@ #include <QtNetwork> -#include "GpgFrontendBuildInfo.h" #include "core/GpgModel.h" #include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyImportExporter.h" +#include "core/model/SettingsObject.h" +#include "core/utils/BuildInfoUtils.h" #include "core/utils/GpgUtils.h" #include "ui/UserInterfaceUtils.h" -#include "ui/struct/SettingsObject.h" -#include "ui/struct/settings/KeyServerSO.h" +#include "ui/struct/settings_object/KeyServerSO.h" namespace GpgFrontend::UI { @@ -116,7 +116,8 @@ void KeyUploadDialog::slot_upload_key_to_server( data.replace(" ", "+"); QNetworkRequest request(req_url); - request.setHeader(QNetworkRequest::UserAgentHeader, HTTP_REQUEST_USER_AGENT); + request.setHeader(QNetworkRequest::UserAgentHeader, + GetHttpRequestUserAgent()); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); diff --git a/src/ui/dialog/settings/SettingsAppearance.cpp b/src/ui/dialog/settings/SettingsAppearance.cpp index d4f97c4c..b756ae05 100644 --- a/src/ui/dialog/settings/SettingsAppearance.cpp +++ b/src/ui/dialog/settings/SettingsAppearance.cpp @@ -28,9 +28,9 @@ #include "SettingsAppearance.h" +#include "core/model/SettingsObject.h" #include "core/utils/MemoryUtils.h" -#include "ui/struct/SettingsObject.h" -#include "ui/struct/settings/AppearanceSO.h" +#include "ui/struct/settings_object/AppearanceSO.h" #include "ui_AppearanceSettings.h" namespace GpgFrontend::UI { diff --git a/src/ui/dialog/settings/SettingsKeyServer.cpp b/src/ui/dialog/settings/SettingsKeyServer.cpp index 5613ed45..fb6e624c 100644 --- a/src/ui/dialog/settings/SettingsKeyServer.cpp +++ b/src/ui/dialog/settings/SettingsKeyServer.cpp @@ -31,10 +31,10 @@ #include <cstddef> #include "core/function/GlobalSettingStation.h" +#include "core/model/SettingsObject.h" #include "core/thread/Task.h" #include "core/thread/TaskRunnerGetter.h" -#include "ui/struct/SettingsObject.h" -#include "ui/struct/settings/KeyServerSO.h" +#include "ui/struct/settings_object/KeyServerSO.h" #include "ui/thread/ListedKeyServerTestTask.h" #include "ui_KeyServerSettings.h" diff --git a/src/ui/dialog/settings/SettingsNetwork.cpp b/src/ui/dialog/settings/SettingsNetwork.cpp index c7e1e9f6..a923e5a2 100644 --- a/src/ui/dialog/settings/SettingsNetwork.cpp +++ b/src/ui/dialog/settings/SettingsNetwork.cpp @@ -29,6 +29,7 @@ #include "SettingsNetwork.h" #include "core/function/GlobalSettingStation.h" +#include "core/module/ModuleManager.h" #include "ui/thread/ProxyConnectionTestTask.h" #include "ui_NetworkSettings.h" @@ -86,8 +87,11 @@ GpgFrontend::UI::NetworkTab::NetworkTab(QWidget *parent) ui_->forbidALLGnuPGNetworkConnectionCheckBox->setText( tr("Forbid all GnuPG network connection.")); - ui_->prohibitUpdateCheck->setText( - tr("Prohibit checking for version updates when the program starts.")); + + if (Module::IsModuleActivate(kVersionCheckingModuleID)) { + ui_->prohibitUpdateCheck->setText( + tr("Prohibit checking for version updates when the program starts.")); + } ui_->autoImportMissingKeyCheckBox->setText( tr("Automatically import a missing key for signature verification.")); ui_->networkAbilityTipsLabel->setText( diff --git a/src/ui/main_window/GeneralMainWindow.cpp b/src/ui/main_window/GeneralMainWindow.cpp index f58326f9..f925eb18 100644 --- a/src/ui/main_window/GeneralMainWindow.cpp +++ b/src/ui/main_window/GeneralMainWindow.cpp @@ -28,9 +28,9 @@ #include "GeneralMainWindow.h" -#include "ui/struct/SettingsObject.h" -#include "ui/struct/settings/AppearanceSO.h" -#include "ui/struct/settings/WindowStateSO.h" +#include "core/model/SettingsObject.h" +#include "ui/struct/settings_object/AppearanceSO.h" +#include "ui/struct/settings_object/WindowStateSO.h" namespace GpgFrontend::UI { diff --git a/src/ui/main_window/MainWindow.cpp b/src/ui/main_window/MainWindow.cpp index a7bd63d8..e1c355c4 100644 --- a/src/ui/main_window/MainWindow.cpp +++ b/src/ui/main_window/MainWindow.cpp @@ -33,11 +33,11 @@ #include "core/function/GlobalSettingStation.h" #include "core/function/gpg/GpgAdvancedOperator.h" #include "core/model/GpgPassphraseContext.h" +#include "core/model/SettingsObject.h" #include "core/module/ModuleManager.h" #include "ui/UISignalStation.h" #include "ui/main_window/GeneralMainWindow.h" -#include "ui/struct/SettingsObject.h" -#include "ui/struct/settings/KeyServerSO.h" +#include "ui/struct/settings_object/KeyServerSO.h" #include "ui/widgets/KeyList.h" #include "ui/widgets/TextEdit.h" @@ -131,8 +131,7 @@ void MainWindow::Init() noexcept { edit_->CurTextPage()->setFocus(); Module::ListenRTPublishEvent( - this, "com.bktus.gpgfrontend.module.integrated.version-checking", - "version.loading_done", + this, kVersionCheckingModuleID, "version.loading_done", [=](Module::Namespace, Module::Key, int, std::any) { GF_UI_LOG_DEBUG( "versionchecking version.loading_done changed, calling slot " diff --git a/src/ui/main_window/MainWindow.h b/src/ui/main_window/MainWindow.h index 523c14f0..6847ec4a 100644 --- a/src/ui/main_window/MainWindow.h +++ b/src/ui/main_window/MainWindow.h @@ -430,7 +430,7 @@ class MainWindow : public GeneralMainWindow { QMenu* file_menu_{}; ///< Submenu for file-operations QMenu* edit_menu_{}; ///< Submenu for text-operations QMenu* crypt_menu_{}; ///< Submenu for crypt-operations - QMenu* gpg_menu_{}; ///< Submenu for help-operations + QMenu* advance_menu_{}; ///< Submenu for help-operations QMenu* help_menu_{}; ///< Submenu for help-operations QMenu* key_menu_{}; ///< Submenu for key-operations QMenu* view_menu_{}; ///< Submenu for view operations @@ -473,6 +473,7 @@ class MainWindow : public GeneralMainWindow { ///< breaks QAction* gnupg_controller_open_act_{}; ///< + QAction* module_controller_open_act_{}; ///< QAction* clean_gpg_password_cache_act_{}; ///< QAction* reload_components_act_{}; ///< QAction* restart_components_act_{}; ///< diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp index 61c5de56..4a95d450 100644 --- a/src/ui/main_window/MainWindowSlotFunction.cpp +++ b/src/ui/main_window/MainWindowSlotFunction.cpp @@ -266,8 +266,7 @@ void MainWindow::slot_version_upgrade_nofity() { GF_UI_LOG_DEBUG( "slot version upgrade notify called, checking version info from rt..."); auto is_loading_done = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.version-checking", - "version.loading_done", false); + kVersionCheckingModuleID, "version.loading_done", false); GF_UI_LOG_DEBUG("checking version info from rt, is loading done state: {}", is_loading_done); @@ -277,20 +276,16 @@ void MainWindow::slot_version_upgrade_nofity() { } auto is_need_upgrade = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.version-checking", - "version.need_upgrade", false); + kVersionCheckingModuleID, "version.need_upgrade", false); auto is_current_a_withdrawn_version = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.version-checking", - "version.current_a_withdrawn_version", false); + kVersionCheckingModuleID, "version.current_a_withdrawn_version", false); auto is_current_version_released = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.version-checking", - "version.current_version_released", false); + kVersionCheckingModuleID, "version.current_version_released", false); auto latest_version = Module::RetrieveRTValueTypedOrDefault<>( - "com.bktus.gpgfrontend.module.integrated.version-checking", - "version.latest_version", QString{}); + kVersionCheckingModuleID, "version.latest_version", QString{}); GF_UI_LOG_DEBUG( "got version info from rt, need upgrade: {}, with drawn: {}, " @@ -304,7 +299,7 @@ void MainWindow::slot_version_upgrade_nofity() { 30000); auto* update_button = new QPushButton("Update GpgFrontend", this); connect(update_button, &QPushButton::clicked, [=]() { - auto* about_dialog = new AboutDialog(2, this); + auto* about_dialog = new AboutDialog(tr("Update"), this); about_dialog->show(); }); statusBar()->addPermanentWidget(update_button, 0); diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp index 99a26626..897c1950 100644 --- a/src/ui/main_window/MainWindowSlotUI.cpp +++ b/src/ui/main_window/MainWindowSlotUI.cpp @@ -29,12 +29,12 @@ #include "MainWindow.h" #include "core/GpgConstants.h" #include "core/model/GpgPassphraseContext.h" +#include "core/model/SettingsObject.h" #include "ui/UserInterfaceUtils.h" #include "ui/dialog/Wizard.h" #include "ui/function/RaisePinentry.h" #include "ui/main_window/KeyMgmt.h" -#include "ui/struct/SettingsObject.h" -#include "ui/struct/settings/AppearanceSO.h" +#include "ui/struct/settings_object/AppearanceSO.h" #include "ui/widgets/TextEdit.h" namespace GpgFrontend::UI { diff --git a/src/ui/main_window/MainWindowUI.cpp b/src/ui/main_window/MainWindowUI.cpp index 8b6fc74c..475eed0e 100644 --- a/src/ui/main_window/MainWindowUI.cpp +++ b/src/ui/main_window/MainWindowUI.cpp @@ -30,8 +30,9 @@ #include "core/function/GlobalSettingStation.h" #include "core/function/gpg/GpgAdvancedOperator.h" #include "core/module/ModuleManager.h" +#include "dialog/controller/ModuleControllerDialog.h" #include "ui/UserInterfaceUtils.h" -#include "ui/dialog/gnupg/GnuPGControllerDialog.h" +#include "ui/dialog/controller/GnuPGControllerDialog.h" #include "ui/dialog/help/AboutDialog.h" #include "ui/widgets/KeyList.h" #include "ui/widgets/TextEdit.h" @@ -404,6 +405,12 @@ void MainWindow::create_actions() { connect(gnupg_controller_open_act_, &QAction::triggered, this, [this]() { (new GnuPGControllerDialog(this))->exec(); }); + module_controller_open_act_ = new QAction(tr("Open Module Controller"), this); + module_controller_open_act_->setIcon(QIcon(":/icons/configure.png")); + module_controller_open_act_->setToolTip(tr("Open Module Controller Dialog")); + connect(module_controller_open_act_, &QAction::triggered, this, + [this]() { (new ModuleControllerDialog(this))->exec(); }); + /* * About Menu */ @@ -414,26 +421,27 @@ void MainWindow::create_actions() { connect(about_act_, &QAction::triggered, this, [=]() { new AboutDialog(0, this); }); - gnupg_act_ = new QAction(tr("GnuPG"), this); - gnupg_act_->setIcon(QIcon(":/icons/help.png")); - gnupg_act_->setToolTip(tr("Information about Gnupg")); - connect(gnupg_act_, &QAction::triggered, this, - [=]() { new AboutDialog(1, this); }); + if (Module::IsModuleActivate(kGnuPGInfoGatheringModuleID)) { + gnupg_act_ = new QAction(tr("GnuPG"), this); + gnupg_act_->setIcon(QIcon(":/icons/help.png")); + gnupg_act_->setToolTip(tr("Information about Gnupg")); + connect(gnupg_act_, &QAction::triggered, this, + [=]() { new AboutDialog(tr("GnuPG"), this); }); + } translate_act_ = new QAction(tr("Translate"), this); translate_act_->setIcon(QIcon(":/icons/help.png")); translate_act_->setToolTip(tr("Information about translation")); connect(translate_act_, &QAction::triggered, this, - [=]() { new AboutDialog(2, this); }); + [=]() { new AboutDialog(tr("Translators"), this); }); - /* - * Check Update Menu - */ - check_update_act_ = new QAction(tr("Check for Updates"), this); - check_update_act_->setIcon(QIcon(":/icons/help.png")); - check_update_act_->setToolTip(tr("Check for updates")); - connect(check_update_act_, &QAction::triggered, this, - [=]() { new AboutDialog(3, this); }); + if (Module::IsModuleActivate(kVersionCheckingModuleID)) { + check_update_act_ = new QAction(tr("Check for Updates"), this); + check_update_act_->setIcon(QIcon(":/icons/help.png")); + check_update_act_->setToolTip(tr("Check for updates")); + connect(check_update_act_, &QAction::triggered, this, + [=]() { new AboutDialog(tr("Update"), this); }); + } start_wizard_act_ = new QAction(tr("Open Wizard"), this); start_wizard_act_->setToolTip(tr("Open the wizard")); @@ -587,13 +595,13 @@ void MainWindow::create_menus() { import_key_menu_->addAction(import_key_from_key_server_act_); key_menu_->addAction(open_key_management_act_); - gpg_menu_ = menuBar()->addMenu(tr("GnuPG")); - gpg_menu_->addAction(clean_gpg_password_cache_act_); - gpg_menu_->addSeparator(); - gpg_menu_->addAction(reload_components_act_); - gpg_menu_->addAction(restart_components_act_); - gpg_menu_->addSeparator(); - gpg_menu_->addAction(gnupg_controller_open_act_); + advance_menu_ = menuBar()->addMenu(tr("Advance")); + advance_menu_->addAction(clean_gpg_password_cache_act_); + advance_menu_->addAction(reload_components_act_); + advance_menu_->addAction(restart_components_act_); + advance_menu_->addSeparator(); + advance_menu_->addAction(gnupg_controller_open_act_); + advance_menu_->addAction(module_controller_open_act_); steganography_menu_ = menuBar()->addMenu(tr("Steganography")); steganography_menu_->addAction(cut_pgp_header_act_); diff --git a/src/ui/struct/settings/AppearanceSO.h b/src/ui/struct/settings_object/AppearanceSO.h index 25262f22..25262f22 100644 --- a/src/ui/struct/settings/AppearanceSO.h +++ b/src/ui/struct/settings_object/AppearanceSO.h diff --git a/src/ui/struct/settings/KeyServerSO.h b/src/ui/struct/settings_object/KeyServerSO.h index 3c9320d2..3c9320d2 100644 --- a/src/ui/struct/settings/KeyServerSO.h +++ b/src/ui/struct/settings_object/KeyServerSO.h diff --git a/src/ui/struct/settings/WindowStateSO.h b/src/ui/struct/settings_object/WindowStateSO.h index 3fa56f3c..3fa56f3c 100644 --- a/src/ui/struct/settings/WindowStateSO.h +++ b/src/ui/struct/settings_object/WindowStateSO.h diff --git a/src/ui/thread/KeyServerImportTask.cpp b/src/ui/thread/KeyServerImportTask.cpp index c908f5d7..8bcb2eab 100644 --- a/src/ui/thread/KeyServerImportTask.cpp +++ b/src/ui/thread/KeyServerImportTask.cpp @@ -28,10 +28,10 @@ #include "ui/thread/KeyServerImportTask.h" -#include "GpgFrontendBuildInfo.h" #include "core/function/gpg/GpgKeyImportExporter.h" -#include "ui/struct/SettingsObject.h" -#include "ui/struct/settings/KeyServerSO.h" +#include "core/model/SettingsObject.h" +#include "core/utils/BuildInfoUtils.h" +#include "ui/struct/settings_object/KeyServerSO.h" GpgFrontend::UI::KeyServerImportTask::KeyServerImportTask( QString keyserver_url, std::vector<QString> keyids) @@ -57,7 +57,7 @@ auto GpgFrontend::UI::KeyServerImportTask::Run() -> int { auto request = QNetworkRequest(req_url); request.setHeader(QNetworkRequest::UserAgentHeader, - HTTP_REQUEST_USER_AGENT); + GetHttpRequestUserAgent()); reply_ = manager_->get(request); connect(reply_, &QNetworkReply::finished, this, diff --git a/src/ui/thread/KeyServerSearchTask.cpp b/src/ui/thread/KeyServerSearchTask.cpp index eb650c4b..828ce5ac 100644 --- a/src/ui/thread/KeyServerSearchTask.cpp +++ b/src/ui/thread/KeyServerSearchTask.cpp @@ -28,7 +28,7 @@ #include "ui/thread/KeyServerSearchTask.h" -#include "GpgFrontendBuildInfo.h" +#include "core/utils/BuildInfoUtils.h" GpgFrontend::UI::KeyServerSearchTask::KeyServerSearchTask(QString keyserver_url, QString search_string) @@ -45,7 +45,8 @@ auto GpgFrontend::UI::KeyServerSearchTask::Run() -> int { "&op=index&options=mr"; auto request = QNetworkRequest(url_from_remote); - request.setHeader(QNetworkRequest::UserAgentHeader, HTTP_REQUEST_USER_AGENT); + request.setHeader(QNetworkRequest::UserAgentHeader, + GetHttpRequestUserAgent()); reply_ = manager_->get(request); connect(reply_, &QNetworkReply::finished, this, diff --git a/src/ui/thread/ListedKeyServerTestTask.cpp b/src/ui/thread/ListedKeyServerTestTask.cpp index 15ea959f..5f7e2dca 100644 --- a/src/ui/thread/ListedKeyServerTestTask.cpp +++ b/src/ui/thread/ListedKeyServerTestTask.cpp @@ -29,9 +29,8 @@ #include "ListedKeyServerTestTask.h" #include <QtNetwork> -#include <vector> -#include "GpgFrontendBuildInfo.h" +#include "core/utils/BuildInfoUtils.h" GpgFrontend::UI::ListedKeyServerTestTask::ListedKeyServerTestTask( QStringList urls, int timeout, QWidget* /*parent*/) @@ -53,7 +52,7 @@ auto GpgFrontend::UI::ListedKeyServerTestTask::Run() -> int { auto request = QNetworkRequest(key_url); request.setHeader(QNetworkRequest::UserAgentHeader, - HTTP_REQUEST_USER_AGENT); + GetHttpRequestUserAgent()); auto* network_reply = network_manager_->get(request); auto* timer = new QTimer(this); diff --git a/src/ui/thread/ProxyConnectionTestTask.cpp b/src/ui/thread/ProxyConnectionTestTask.cpp index 003205e5..c1d2f3e6 100644 --- a/src/ui/thread/ProxyConnectionTestTask.cpp +++ b/src/ui/thread/ProxyConnectionTestTask.cpp @@ -30,7 +30,7 @@ #include <QtNetwork> -#include "GpgFrontendBuildInfo.h" +#include "core/utils/BuildInfoUtils.h" GpgFrontend::UI::ProxyConnectionTestTask::ProxyConnectionTestTask(QString url, int timeout) @@ -43,7 +43,8 @@ GpgFrontend::UI::ProxyConnectionTestTask::ProxyConnectionTestTask(QString url, auto GpgFrontend::UI::ProxyConnectionTestTask::Run() -> int { auto request = QNetworkRequest(url_); - request.setHeader(QNetworkRequest::UserAgentHeader, HTTP_REQUEST_USER_AGENT); + request.setHeader(QNetworkRequest::UserAgentHeader, + GetHttpRequestUserAgent()); auto* network_reply = network_manager_->get(request); auto* timer = new QTimer(this); diff --git a/src/ui/widgets/FileTreeView.cpp b/src/ui/widgets/FileTreeView.cpp index 7a725e10..de22ec83 100644 --- a/src/ui/widgets/FileTreeView.cpp +++ b/src/ui/widgets/FileTreeView.cpp @@ -54,6 +54,10 @@ FileTreeView::FileTreeView(QWidget* parent, const QString& target_path) &FileTreeView::slot_show_custom_context_menu); connect(this, &QTreeView::doubleClicked, this, &FileTreeView::slot_file_tree_view_item_double_clicked); + connect(dir_model_, &QFileSystemModel::layoutChanged, this, + &FileTreeView::slot_adjust_column_widths); + connect(dir_model_, &QFileSystemModel::dataChanged, this, + &FileTreeView::slot_adjust_column_widths); } void FileTreeView::selectionChanged(const QItemSelection& selected, @@ -82,9 +86,7 @@ void FileTreeView::SlotGoPath(const QString& target_path) { GF_UI_LOG_DEBUG("file tree view set target path: {}", current_path_); this->setRootIndex(dir_model_->index(file_info.filePath())); dir_model_->setRootPath(file_info.filePath()); - for (int i = 1; i < dir_model_->columnCount(); ++i) { - this->resizeColumnToContents(i); - } + slot_adjust_column_widths(); } else { QMessageBox::critical( this, tr("Error"), @@ -413,12 +415,21 @@ void FileTreeView::slot_compress_files() {} void FileTreeView::paintEvent(QPaintEvent* event) { QTreeView::paintEvent(event); - for (int i = 1; i < dir_model_->columnCount(); ++i) { - this->resizeColumnToContents(i); + + if (!initial_resize_done_) { + slot_adjust_column_widths(); + initial_resize_done_ = true; } } void FileTreeView::mousePressEvent(QMouseEvent* event) { QTreeView::mousePressEvent(event); } + +void FileTreeView::slot_adjust_column_widths() { + for (int i = 1; i < dir_model_->columnCount(); ++i) { + this->resizeColumnToContents(i); + } +} + } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/FileTreeView.h b/src/ui/widgets/FileTreeView.h index cd3b1cb8..b1cc8897 100644 --- a/src/ui/widgets/FileTreeView.h +++ b/src/ui/widgets/FileTreeView.h @@ -219,6 +219,12 @@ class FileTreeView : public QTreeView { */ void slot_create_popup_menu(); + /** + * @brief + * + */ + void slot_adjust_column_widths(); + private: QFileSystemModel* dir_model_; ///< QString current_path_; ///< @@ -233,5 +239,7 @@ class FileTreeView : public QTreeView { QAction* action_create_empty_file_; QAction* action_make_directory_; QAction* action_compress_files_; + + bool initial_resize_done_ = false; }; } // namespace GpgFrontend::UI
\ No newline at end of file diff --git a/src/ui/widgets/GRTTreeView.cpp b/src/ui/widgets/GRTTreeView.cpp new file mode 100644 index 00000000..09d7dcf0 --- /dev/null +++ b/src/ui/widgets/GRTTreeView.cpp @@ -0,0 +1,66 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GRTTreeView.h" + +#include "core/module/GlobalRegisterTableTreeModel.h" +#include "core/module/ModuleManager.h" + +namespace GpgFrontend::UI { + +GRTTreeView::GRTTreeView(QWidget* parent) : QTreeView(parent) { + setModel(new Module::GlobalRegisterTableTreeModel( + Module::ModuleManager::GetInstance().GRT())); + + connect(model(), &QFileSystemModel::layoutChanged, this, + &GRTTreeView::slot_adjust_column_widths); + connect(model(), &QFileSystemModel::dataChanged, this, + &GRTTreeView::slot_adjust_column_widths); + connect(this, &GRTTreeView::expanded, this, + &GRTTreeView::slot_adjust_column_widths); + connect(this, &GRTTreeView::collapsed, this, + &GRTTreeView::slot_adjust_column_widths); +} + +GRTTreeView::~GRTTreeView() = default; + +void GRTTreeView::paintEvent(QPaintEvent* event) { + QTreeView::paintEvent(event); + + if (!initial_resize_done_) { + slot_adjust_column_widths(); + initial_resize_done_ = true; + } +} + +void GRTTreeView::slot_adjust_column_widths() { + for (int i = 0; i < model()->columnCount(); ++i) { + this->resizeColumnToContents(i); + } +} +} // namespace GpgFrontend::UI
\ No newline at end of file diff --git a/src/ui/widgets/GRTTreeView.h b/src/ui/widgets/GRTTreeView.h new file mode 100644 index 00000000..6f3f83c8 --- /dev/null +++ b/src/ui/widgets/GRTTreeView.h @@ -0,0 +1,69 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +namespace GpgFrontend::UI { + +class GRTTreeView : public QTreeView { + Q_OBJECT + public: + /** + * @brief Construct a new GRTTreeView object + * + * @param parent + */ + explicit GRTTreeView(QWidget* parent); + + /** + * @brief Destroy the GRTTreeView object + * + */ + virtual ~GRTTreeView() override; + + protected: + /** + * @brief + * + * @param event + */ + void paintEvent(QPaintEvent* event) override; + + private slots: + + /** + * @brief + * + */ + void slot_adjust_column_widths(); + + private: + bool initial_resize_done_ = false; +}; + +} // namespace GpgFrontend::UI
\ No newline at end of file diff --git a/src/ui/widgets/InfoBoardWidget.cpp b/src/ui/widgets/InfoBoardWidget.cpp index d1a006c5..425e6ccd 100644 --- a/src/ui/widgets/InfoBoardWidget.cpp +++ b/src/ui/widgets/InfoBoardWidget.cpp @@ -29,9 +29,9 @@ #include "ui/widgets/InfoBoardWidget.h" #include "core/GpgModel.h" +#include "core/model/SettingsObject.h" #include "ui/UISignalStation.h" -#include "ui/struct/SettingsObject.h" -#include "ui/struct/settings/AppearanceSO.h" +#include "ui/struct/settings_object/AppearanceSO.h" #include "ui_InfoBoard.h" namespace GpgFrontend::UI { diff --git a/src/ui/widgets/ModuleListView.cpp b/src/ui/widgets/ModuleListView.cpp new file mode 100644 index 00000000..6a386813 --- /dev/null +++ b/src/ui/widgets/ModuleListView.cpp @@ -0,0 +1,70 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "ModuleListView.h" + +#include "core/module/ModuleManager.h" + +namespace GpgFrontend::UI { + +ModuleListView::ModuleListView(QWidget *parent) + : QListView(parent), model_(new QStandardItemModel(this)) { + setModel(model_); + setEditTriggers(QAbstractItemView::NoEditTriggers); + + load_module_informations(); +} + +void ModuleListView::currentChanged(const QModelIndex ¤t, + const QModelIndex &previous) { + QListView::currentChanged(current, previous); + auto *item = model_->itemFromIndex(current); + if (item != nullptr) { + emit this->SignalSelectModule(item->data(Qt::UserRole + 1).toString()); + } +} + +void ModuleListView::load_module_informations() { + auto &module_manager = Module::ModuleManager::GetInstance(); + auto module_ids = module_manager.ListAllRegisteredModuleID(); + + model_->clear(); + for (const auto &module_id : module_ids) { + auto module = module_manager.SearchModule(module_id); + auto meta_data = module->GetModuleMetaData(); + auto *item = new QStandardItem(meta_data.value("Name", module_id)); + item->setData(module_id, Qt::UserRole + 1); + model_->appendRow(item); + } +} + +auto ModuleListView::GetCurrentModuleID() -> Module::ModuleIdentifier { + auto *item = model_->itemFromIndex(currentIndex()); + return item != nullptr ? item->data(Qt::UserRole + 1).toString() : ""; +} +}; // namespace GpgFrontend::UI diff --git a/src/ui/widgets/ModuleListView.h b/src/ui/widgets/ModuleListView.h new file mode 100644 index 00000000..0b294bbf --- /dev/null +++ b/src/ui/widgets/ModuleListView.h @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include "core/module/Module.h" + +namespace GpgFrontend::UI { +class ModuleListView : public QListView { + Q_OBJECT + public: + explicit ModuleListView(QWidget *parent); + + auto GetCurrentModuleID() -> Module::ModuleIdentifier; + + signals: + void SignalSelectModule(Module::ModuleIdentifier); + + protected: + void currentChanged(const QModelIndex ¤t, + const QModelIndex &previous) override; + + private: + QStandardItemModel *model_; + + void load_module_informations(); +}; +}; // namespace GpgFrontend::UI
\ No newline at end of file diff --git a/src/ui/widgets/PlainTextEditorPage.cpp b/src/ui/widgets/PlainTextEditorPage.cpp index 8f4890cc..874bbf3b 100644 --- a/src/ui/widgets/PlainTextEditorPage.cpp +++ b/src/ui/widgets/PlainTextEditorPage.cpp @@ -28,10 +28,10 @@ #include "PlainTextEditorPage.h" +#include "core/model/SettingsObject.h" #include "core/thread/FileReadTask.h" #include "core/thread/TaskRunnerGetter.h" -#include "ui/struct/SettingsObject.h" -#include "ui/struct/settings/AppearanceSO.h" +#include "ui/struct/settings_object/AppearanceSO.h" #include "ui_PlainTextEditor.h" namespace GpgFrontend::UI { diff --git a/src/ui/widgets/TextEdit.cpp b/src/ui/widgets/TextEdit.cpp index 1373c5d9..25fce9b8 100644 --- a/src/ui/widgets/TextEdit.cpp +++ b/src/ui/widgets/TextEdit.cpp @@ -34,8 +34,8 @@ #include "core/GpgModel.h" #include "core/function/GlobalSettingStation.h" +#include "core/model/CacheObject.h" #include "ui/UISignalStation.h" -#include "ui/struct/CacheObject.h" namespace GpgFrontend::UI { diff --git a/ui/ModuleControllerDialog.ui b/ui/ModuleControllerDialog.ui new file mode 100644 index 00000000..92f70c15 --- /dev/null +++ b/ui/ModuleControllerDialog.ui @@ -0,0 +1,221 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ModuleControllerDialog</class> + <widget class="QDialog" name="ModuleControllerDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>829</width> + <height>660</height> + </rect> + </property> + <property name="windowTitle"> + <string>Module Controller</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="tabPosition"> + <enum>QTabWidget::North</enum> + </property> + <property name="tabShape"> + <enum>QTabWidget::Rounded</enum> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <property name="documentMode"> + <bool>false</bool> + </property> + <widget class="QWidget" name="registeredModuleTab"> + <attribute name="title"> + <string>Registered Modules</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <item> + <layout class="QHBoxLayout" name="moduleControllerLayout"> + <item> + <layout class="QVBoxLayout" name="moduleListViewLayout"> + <property name="sizeConstraint"> + <enum>QLayout::SetDefaultConstraint</enum> + </property> + <item> + <widget class="GpgFrontend::UI::ModuleListView" name="moduleListView"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>250</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>250</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="Line" name="line_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <property name="sizeConstraint"> + <enum>QLayout::SetDefaultConstraint</enum> + </property> + <item> + <widget class="QLabel" name="moduleInfoLabel"> + <property name="text"> + <string>Module Informations</string> + </property> + </widget> + </item> + <item> + <widget class="QTextBrowser" name="moduleInfoTextBrowser"> + <property name="lineWrapMode"> + <enum>QTextEdit::NoWrap</enum> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="activateOrDeactiveButton"> + <property name="text"> + <string>Activate</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="autoActivateButton"> + <property name="text"> + <string>Auto Activate</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab"> + <attribute name="title"> + <string>Global Register Table</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="GpgFrontend::UI::GRTTreeView" name="treeView"> + <property name="uniformRowHeights"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab_2"> + <attribute name="title"> + <string>Debugger</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_8"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_7"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_10"> + <item> + <widget class="QPushButton" name="triggerEventButton"> + <property name="text"> + <string>Trigger Event</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_11"> + <item> + <widget class="QPushButton" name="pushButton_4"> + <property name="text"> + <string>Upsert GRT Value</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>GpgFrontend::UI::ModuleListView</class> + <extends>QListView</extends> + <header>ui/widgets/ModuleListView.h</header> + </customwidget> + <customwidget> + <class>GpgFrontend::UI::GRTTreeView</class> + <extends>QTreeView</extends> + <header>ui/widgets/GRTTreeView.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> |