aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt38
-rw-r--r--src/core/CMakeLists.txt24
-rw-r--r--src/core/GpgFrontendCore.h6
-rw-r--r--src/core/function/ArchiveFileOperator.cpp11
-rw-r--r--src/core/function/ArchiveFileOperator.h8
-rw-r--r--src/core/plugin/Event.cpp59
-rw-r--r--src/core/plugin/Event.h107
-rw-r--r--src/core/plugin/GlobalPluginContext.cpp263
-rw-r--r--src/core/plugin/GlobalPluginContext.h103
-rw-r--r--src/core/plugin/Plugin.cpp70
-rw-r--r--src/core/plugin/Plugin.h100
-rw-r--r--src/core/plugin/PluginManager.cpp85
-rw-r--r--src/core/plugin/PluginManager.h79
-rw-r--r--src/main.cpp3
-rw-r--r--src/plugin/CMakeLists.txt94
-rw-r--r--src/plugin/GpgFrontendPlugin.h39
-rw-r--r--src/plugin/GpgFrontendPluginExport.h42
-rw-r--r--src/plugin/GpgFrontendPluginInit.cpp99
-rw-r--r--src/plugin/GpgFrontendPluginInit.h56
-rw-r--r--src/plugin/integrated_plugins/version_checking_plugin/CMakeLists.txt46
-rw-r--r--src/plugin/integrated_plugins/version_checking_plugin/SoftwareVersion.cpp105
-rw-r--r--src/plugin/integrated_plugins/version_checking_plugin/SoftwareVersion.h90
-rw-r--r--src/plugin/integrated_plugins/version_checking_plugin/VersionCheckTask.cpp179
-rw-r--r--src/plugin/integrated_plugins/version_checking_plugin/VersionCheckTask.h99
-rw-r--r--src/plugin/integrated_plugins/version_checking_plugin/VersionCheckingPlugin.cpp63
-rw-r--r--src/plugin/integrated_plugins/version_checking_plugin/VersionCheckingPlugin.h54
-rw-r--r--src/plugin/sdk/Basic.cpp27
-rw-r--r--src/plugin/sdk/Basic.h27
-rw-r--r--src/plugin/sdk/Gpg.cpp27
-rw-r--r--src/plugin/sdk/Gpg.h27
-rw-r--r--src/plugin/sdk/GpgFrontendPluginSDK.h31
-rw-r--r--src/plugin/sdk/GpgFrontendPluginSDKExport.h42
-rw-r--r--src/plugin/sdk/Plugin.cpp62
-rw-r--r--src/plugin/sdk/Plugin.h79
-rw-r--r--src/plugin/sdk/Task.cpp62
-rw-r--r--src/plugin/sdk/Task.h80
-rw-r--r--src/plugin/sdk/UI.cpp27
-rw-r--r--src/plugin/sdk/UI.h27
-rw-r--r--src/ui/GpgFrontendUI.h4
-rw-r--r--src/ui/GpgFrontendUIInit.cpp1
-rw-r--r--src/ui/UserInterfaceUtils.cpp1
-rw-r--r--src/ui/dialog/Wizard.cpp2
-rw-r--r--src/ui/dialog/import_export/KeyServerImportDialog.h1
-rw-r--r--src/ui/dialog/import_export/KeyUploadDialog.cpp1
-rw-r--r--src/ui/dialog/settings/SettingsGeneral.cpp10
-rw-r--r--src/ui/dialog/settings/SettingsGeneral.h4
-rw-r--r--src/ui/dialog/settings/SettingsNetwork.h2
-rw-r--r--src/ui/thread/KeyServerImportTask.h2
-rw-r--r--src/ui/thread/KeyServerSearchTask.h2
-rw-r--r--src/ui/thread/ListedKeyServerTestTask.cpp1
-rw-r--r--src/ui/thread/ListedKeyServerTestTask.h4
-rw-r--r--src/ui/thread/ProxyConnectionTestTask.cpp2
-rw-r--r--src/ui/thread/ProxyConnectionTestTask.h4
-rw-r--r--src/ui/thread/VersionCheckTask.cpp1
-rw-r--r--src/ui/thread/VersionCheckTask.h5
-rw-r--r--src/ui/widgets/TextEdit.cpp1
56 files changed, 2429 insertions, 59 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9cd214de..8d889bd7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -67,7 +67,7 @@ if (QT5_ENV_SUPPORT)
endif ()
# configure for output path and resources
-if (APPLICATION_BUILD)
+if (BUILD_APPLICATION)
aux_source_directory(. BASE_SOURCE)
set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_SOURCE_DIR}/gpgfrontend.rc")
set_property(SOURCE gpgfrontend.rc APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_SOURCE_DIR}/gpgfrontend.ico)
@@ -81,23 +81,21 @@ if (APPLICATION_BUILD)
endif ()
endif ()
-
-if (GPG_CORE)
- message(STATUS "Build Core Module")
+if (BUILD_CORE_MODULE)
+ message("[*] Build Core Module")
add_subdirectory(core)
endif ()
-if (UI_CORE)
- message(STATUS "Build UI Module")
+if (BUILD_UI_MODULE)
+ message("[*] Build UI Module")
add_subdirectory(ui)
endif ()
-if (PLUGIN_CORE)
- message(STATUS "Build Plugin Module")
- add_subdirectory(plugin)
+if (BUILD_PLUGIN_MODULE)
+ message("[*] Build Plugin Module")
endif ()
-if (APPLICATION_BUILD)
+if (BUILD_APPLICATION)
# Set Resource Output Path
if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
if (APPLE)
@@ -119,7 +117,7 @@ endif ()
file(GLOB_RECURSE ALL_SOURCE_FILES RELACTIVE ${CMAKE_SOURCE_DIR}/src/*.cpp)
# i18n
-if (MULTI_LANG_SUPPORT)
+if (SUPPORT_MULTI_LANG)
message(STATUS "Build Multiply Languages Support")
# Set Translation Files
find_package(Gettext REQUIRED)
@@ -171,7 +169,7 @@ if (BASIC_ENV_CONFIG)
endif ()
endif ()
-if (APPLICATION_BUILD)
+if (BUILD_APPLICATION)
# Copy Resource Files
file(COPY ${CMAKE_SOURCE_DIR}/resource/css DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
file(COPY ${CMAKE_SOURCE_DIR}/resource/lfs/icons DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
@@ -181,7 +179,7 @@ if (APPLICATION_BUILD)
endif ()
endif ()
-if (APPLICATION_BUILD)
+if (BUILD_APPLICATION)
if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
if (APPLE)
file(COPY ${CMAKE_SOURCE_DIR}/gpgfrontend.icns DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
@@ -193,7 +191,7 @@ if (APPLICATION_BUILD)
endif ()
endif ()
-if (APPLICATION_BUILD)
+if (BUILD_APPLICATION)
# Copy Utils Files
if (MINGW)
message(STATUS "Copying Dependent DLL For Windows Runtime Env")
@@ -342,15 +340,15 @@ if (APPLICATION_BUILD)
endif ()
endif ()
-if (APPLICATION_BUILD)
+if (BUILD_APPLICATION)
set(RESOURCE_FILES ${CMAKE_SOURCE_DIR}/gpgfrontend.qrc ${APP_ICON_RESOURCE_WINDOWS} ${QON_QM_FILES})
add_custom_target(resources ALL DEPENDS ${RESOURCE_FILES})
- if (MULTI_LANG_SUPPORT)
+ if (SUPPORT_MULTI_LANG)
add_dependencies(resources translations)
endif ()
endif ()
-if (APPLICATION_BUILD)
+if (BUILD_APPLICATION)
if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
if (MINGW)
add_executable(${AppName} WIN32 ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
@@ -468,8 +466,8 @@ if (APPLICATION_BUILD)
endif ()
# link options for GpgFrontend
-if (APPLICATION_BUILD)
- target_link_libraries(${AppName} gpgfrontend_ui)
+if (BUILD_APPLICATION)
+ target_link_libraries(${AppName} gpgfrontend_ui gpgfrontend_plugin)
if (MINGW)
message(STATUS "Link Application Library For MINGW")
target_link_libraries(${AppName} crypto)
@@ -525,7 +523,7 @@ if (LINUX AND LINUX_INSTALL_SOFTWARE)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/lfs/hicolor/
DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/icons/hicolor/)
endif ()
- if (MULTI_LANG_SUPPORT)
+ if (SUPPORT_MULTI_LANG)
install(DIRECTORY ${LOCALE_OUTPUT_PATH}/
DESTINATION ${CMAKE_INSTALL_FULL_LOCALEDIR})
endif ()
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index cb050336..5587c6a4 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -24,20 +24,20 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
-aux_source_directory(./function/result_analyse GPG_SOURCE)
-aux_source_directory(./function/gpg GPG_SOURCE)
-aux_source_directory(./function/aes GPG_SOURCE)
-aux_source_directory(./function GPG_SOURCE)
-aux_source_directory(./thread GPG_SOURCE)
-aux_source_directory(./model GPG_SOURCE)
-aux_source_directory(./common GPG_SOURCE)
-aux_source_directory(./plugin GPG_SOURCE)
-aux_source_directory(. GPG_SOURCE)
+aux_source_directory(./function/result_analyse CORE_SOURCE)
+aux_source_directory(./function/gpg CORE_SOURCE)
+aux_source_directory(./function/aes CORE_SOURCE)
+aux_source_directory(./function CORE_SOURCE)
+aux_source_directory(./thread CORE_SOURCE)
+aux_source_directory(./model CORE_SOURCE)
+aux_source_directory(./common CORE_SOURCE)
+aux_source_directory(./plugin CORE_SOURCE)
+aux_source_directory(. CORE_SOURCE)
# define libgpgfrontend_core
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
-add_library(gpgfrontend_core SHARED ${GPG_SOURCE})
+add_library(gpgfrontend_core SHARED ${CORE_SOURCE})
set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendCoreExport.h")
generate_export_header(gpgfrontend_core EXPORT_FILE_NAME "${_export_file}")
@@ -62,9 +62,6 @@ if (APPLE)
target_link_libraries(gpgfrontend_core PRIVATE icui18n icuuc icudata)
else ()
find_package(ICU REQUIRED COMPONENTS i18n uc data)
- message("ICU version: ${ICU_VERSION}")
- message("ICU includes: ${ICU_INCLUDE_DIRS}")
- message("ICU libraries: ${ICU_LIBRARIES}")
target_include_directories(gpgfrontend_core PRIVATE ${ICU_INCLUDE_DIRS})
target_link_libraries(gpgfrontend_core PRIVATE ${ICU_LIBRARIES})
endif ()
@@ -89,6 +86,7 @@ target_link_libraries(gpgfrontend_core PRIVATE archive)
# link json
target_link_libraries(gpgfrontend_core
PUBLIC nlohmann_json::nlohmann_json)
+
# link Qt core
if(Qt6_DIR)
target_link_libraries(gpgfrontend_core PUBLIC Qt6::Core)
diff --git a/src/core/GpgFrontendCore.h b/src/core/GpgFrontendCore.h
index 599a4ce8..2b89caa1 100644
--- a/src/core/GpgFrontendCore.h
+++ b/src/core/GpgFrontendCore.h
@@ -58,8 +58,6 @@
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/format.hpp>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/uniform_int_distribution.hpp>
// Qt includes
#include <QtCore>
@@ -67,10 +65,6 @@
// libconfig includes
#include <libconfig.h++>
-// libarchive includes
-#include <libarchive/libarchive/archive.h>
-#include <libarchive/libarchive/archive_entry.h>
-
// json includes
#include <nlohmann/json.hpp>
diff --git a/src/core/function/ArchiveFileOperator.cpp b/src/core/function/ArchiveFileOperator.cpp
index 8aad0500..9b23151f 100644
--- a/src/core/function/ArchiveFileOperator.cpp
+++ b/src/core/function/ArchiveFileOperator.cpp
@@ -28,6 +28,17 @@
#include "ArchiveFileOperator.h"
+#include <libarchive/libarchive/archive.h>
+#include <libarchive/libarchive/archive_entry.h>
+
+struct ArchiveStruct {
+ struct archive *archive;
+ struct archive_entry *entry;
+ int fd;
+ bool is_open;
+ std::string name;
+};
+
int copy_data(struct archive *ar, struct archive *aw) {
int r;
const void *buff;
diff --git a/src/core/function/ArchiveFileOperator.h b/src/core/function/ArchiveFileOperator.h
index 4db5af5f..749cf2f1 100644
--- a/src/core/function/ArchiveFileOperator.h
+++ b/src/core/function/ArchiveFileOperator.h
@@ -34,14 +34,6 @@
namespace GpgFrontend {
-struct ArchiveStruct {
- struct archive *archive;
- struct archive_entry *entry;
- int fd;
- bool is_open;
- std::string name;
-};
-
class GPGFRONTEND_CORE_EXPORT ArchiveFileOperator {
public:
static void ListArchive(const std::filesystem::path &archive_path);
diff --git a/src/core/plugin/Event.cpp b/src/core/plugin/Event.cpp
new file mode 100644
index 00000000..ec898f27
--- /dev/null
+++ b/src/core/plugin/Event.cpp
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "Event.h"
+
+namespace GpgFrontend::Plugin {
+
+Event::Event(const std::string& event_dientifier,
+ std::initializer_list<ParameterInitializer> params_init_list)
+ : event_identifier_(event_dientifier) {
+ for (const auto& param : params_init_list) {
+ AddParameter(param);
+ }
+}
+
+bool Event::Event::operator==(const Event& other) const {
+ return event_identifier_ == other.event_identifier_;
+}
+
+bool Event::Event::operator!=(const Event& other) const {
+ return !(*this == other);
+}
+
+bool Event::Event::operator<(const Event& other) const {
+ return !(*this < other);
+}
+
+bool Event::Event::operator<=(const Event& other) const {
+ return !(*this <= other);
+}
+
+Event::Event::operator std::string() const { return event_identifier_; }
+
+EventIdentifier Event::Event::GetIdentifier() { return event_identifier_; }
+
+} // namespace GpgFrontend::Plugin \ No newline at end of file
diff --git a/src/core/plugin/Event.h b/src/core/plugin/Event.h
new file mode 100644
index 00000000..b6b70730
--- /dev/null
+++ b/src/core/plugin/Event.h
@@ -0,0 +1,107 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_EVENT_H
+#define GPGFRONTEND_EVENT_H
+
+#include "core/GpgFrontendCore.h"
+
+namespace GpgFrontend::Plugin {
+
+class Event;
+
+using EventRefrernce = std::shared_ptr<Event>;
+using EventIdentifier = std::string;
+using Evnets = std::vector<Event>;
+
+class Event {
+ public:
+ class ParameterBase {
+ public:
+ virtual ~ParameterBase() = default;
+ };
+
+ struct ParameterInitializer {
+ std::string key;
+ std::shared_ptr<ParameterBase> value;
+ };
+
+ Event(const std::string& event_dientifier,
+ std::initializer_list<ParameterInitializer> params_init_list = {});
+
+ template <typename T>
+ std::optional<T> operator[](const std::string& key) const {
+ return GetParameter<T>(key);
+ }
+
+ bool operator==(const Event& other) const;
+ bool operator!=(const Event& other) const;
+ bool operator<(const Event& other) const;
+ bool operator<=(const Event& other) const;
+ operator std::string() const;
+
+ EventIdentifier GetIdentifier();
+
+ template <typename T>
+ void AddParameter(const std::string& key, const T& value) {
+ data_[key] = std::make_shared<ParameterValue<T>>(value);
+ }
+
+ void AddParameter(const ParameterInitializer& init) {
+ data_[init.key] = init.value;
+ }
+
+ template <typename T>
+ std::optional<T> GetParameter(const std::string& key) const {
+ if (data_.find(key) == data_.end()) {
+ throw std::nullopt;
+ }
+ auto value = std::dynamic_pointer_cast<ParameterValue<T>>(data_.at(key));
+ if (!value) {
+ throw std::nullopt;
+ }
+ return value->GetValue();
+ }
+
+ private:
+ template <typename T>
+ class ParameterValue : public ParameterBase {
+ public:
+ ParameterValue(const T& value) : value_(value) {}
+
+ T GetValue() const { return value_; }
+
+ private:
+ T value_;
+ };
+
+ EventIdentifier event_identifier_;
+ std::map<std::string, std::shared_ptr<ParameterBase>> data_;
+};
+
+} // namespace GpgFrontend::Plugin
+
+#endif // GPGFRONTEND_EVENT_H \ No newline at end of file
diff --git a/src/core/plugin/GlobalPluginContext.cpp b/src/core/plugin/GlobalPluginContext.cpp
new file mode 100644
index 00000000..3b3744b5
--- /dev/null
+++ b/src/core/plugin/GlobalPluginContext.cpp
@@ -0,0 +1,263 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "GlobalPluginContext.h"
+
+#include <memory>
+#include <optional>
+#include <unordered_set>
+
+#include "GpgConstants.h"
+#include "plugin/Event.h"
+#include "plugin/Plugin.h"
+#include "spdlog/spdlog.h"
+#include "thread/Task.h"
+
+namespace GpgFrontend::Plugin {
+
+// Constructor for GlobalPluginContext, takes a TaskRunnerPtr as an argument.
+GlobalPluginContext::GlobalPluginContext(TaskRunnerPtr task_runner)
+ : default_task_runner_(task_runner),
+ random_gen_((boost::posix_time::microsec_clock::universal_time() -
+ boost::posix_time::ptime(boost::gregorian::date(1970, 1, 1)))
+ .total_milliseconds()) {
+ // Initialize acquired channels with default values.
+ acquired_channel_.insert(GPGFRONTEND_DEFAULT_CHANNEL);
+ acquired_channel_.insert(GPGFRONTEND_NON_ASCII_CHANNEL);
+}
+
+// Function to acquire a new unique channel.
+int GlobalPluginContext::acquire_new_unique_channel() {
+ boost::random::uniform_int_distribution<> dist(1, 65535);
+
+ int random_channel = dist(random_gen_);
+ // Ensure the acquired channel is unique.
+ while (acquired_channel_.find(random_channel) != acquired_channel_.end()) {
+ random_channel = dist(random_gen_);
+ }
+
+ // Add the acquired channel to the set.
+ acquired_channel_.insert(random_channel);
+ return random_channel;
+}
+
+// Function to search for a plugin in the register table.
+std::optional<PluginRegisterInfoPtr>
+GlobalPluginContext::search_plugin_register_table(PluginIdentifier identifier) {
+ auto it = plugin_register_table_.find(identifier);
+ if (it == plugin_register_table_.end()) {
+ return std::nullopt;
+ }
+ return it->second;
+}
+
+// Function to get the task runner associated with a plugin.
+std::optional<TaskRunnerPtr> GlobalPluginContext::GetTaskRunner(
+ PluginPtr plugin) {
+ auto opt = search_plugin_register_table(plugin->gpc_get_identifier());
+ if (!opt.has_value()) {
+ return std::nullopt;
+ }
+ return opt.value()->task_runner;
+}
+
+// Function to get the task runner associated with a plugin.
+std::optional<TaskRunnerPtr> GlobalPluginContext::GetTaskRunner(
+ PluginIdentifier plugin) {
+ // Search for the plugin in the register table.
+ auto plugin_info_opt = search_plugin_register_table(plugin);
+ if (!plugin_info_opt.has_value()) {
+ SPDLOG_ERROR("cannot find plugin id {} at register table", plugin);
+ return std::nullopt;
+ }
+ return plugin_info_opt.value()->task_runner;
+}
+
+// Function to get the global task runner.
+std::optional<TaskRunnerPtr> GlobalPluginContext::GetGlobalTaskRunner() {
+ return default_task_runner_;
+}
+
+bool GlobalPluginContext::RegisterPlugin(PluginPtr plugin) {
+ SPDLOG_DEBUG("attempting to register plugin: {}",
+ plugin->gpc_get_identifier());
+ // Check if the plugin is null or already registered.
+ if (plugin == nullptr ||
+ plugin_register_table_.find(plugin->gpc_get_identifier()) !=
+ plugin_register_table_.end()) {
+ SPDLOG_ERROR("plugin is null or have already registered this plugin");
+ return false;
+ }
+
+ PluginRegisterInfo register_info;
+ register_info.plugin = plugin;
+ register_info.channel = acquire_new_unique_channel();
+ register_info.task_runner = std::make_shared<Thread::TaskRunner>();
+
+ // Register the plugin with its identifier.
+ plugin_register_table_[plugin->gpc_get_identifier()] =
+ std::make_shared<PluginRegisterInfo>(std::move(register_info));
+
+ SPDLOG_DEBUG("successfully registered plugin: {}",
+ plugin->gpc_get_identifier());
+ return true;
+}
+
+bool GlobalPluginContext::ActivePlugin(PluginIdentifier plugin_id) {
+ SPDLOG_DEBUG("attempting to activate plugin: {}", plugin_id);
+
+ // Search for the plugin in the register table.
+ auto plugin_info_opt = search_plugin_register_table(plugin_id);
+ if (!plugin_info_opt.has_value()) {
+ SPDLOG_ERROR("cannot find plugin id {} at register table", plugin_id);
+ return false;
+ }
+
+ auto plugin_info = plugin_info_opt.value();
+ // Activate the plugin if it is not already active.
+ if (plugin_info->activate && plugin_info->plugin->Active()) {
+ plugin_info->activate = true;
+ }
+
+ SPDLOG_DEBUG("plugin activation status: {}", plugin_info->activate);
+ return plugin_info->activate;
+}
+
+bool GlobalPluginContext::ListenEvent(PluginIdentifier plugin_id,
+ EventIdentifier event) {
+ SPDLOG_DEBUG("plugin: {} is attempting to listen to event {}", plugin_id,
+ event);
+ // Check if the event exists, if not, create it.
+ auto it = plugin_events_table_.find(event);
+ if (it == plugin_events_table_.end()) {
+ plugin_events_table_[event] = std::unordered_set<PluginIdentifier>();
+ it = plugin_events_table_.find(event);
+ SPDLOG_INFO("new event {} of plugin system created", event);
+ }
+
+ auto& listeners_set = it->second;
+ // Add the listener (plugin) to the event.
+ auto listener_it =
+ std::find(listeners_set.begin(), listeners_set.end(), plugin_id);
+ if (listener_it == listeners_set.end()) {
+ listeners_set.insert(plugin_id);
+ }
+ return true;
+}
+
+bool GlobalPluginContext::DeactivatePlugin(PluginIdentifier plugin_id) {
+ // Search for the plugin in the register table.
+ auto plugin_info_opt = search_plugin_register_table(plugin_id);
+ if (!plugin_info_opt.has_value()) {
+ SPDLOG_ERROR("cannot find plugin id {} at register table", plugin_id);
+ return false;
+ }
+
+ auto plugin_info = plugin_info_opt.value();
+ // Activate the plugin if it is not already deactive.
+ if (!plugin_info->activate && plugin_info->plugin->Deactive()) {
+ plugin_info->activate = false;
+ }
+
+ return !plugin_info->activate;
+}
+
+bool GlobalPluginContext::TriggerEvent(EventRefrernce event) {
+ SPDLOG_DEBUG("attempting to trigger event: {}", event->GetIdentifier());
+
+ // Find the set of listeners associated with the given event in the table
+ auto it = plugin_events_table_.find(event->GetIdentifier());
+ if (it == plugin_events_table_.end()) {
+ // Log a warning if the event is not registered and nobody is listening
+ SPDLOG_WARN(
+ "event {} is not listening by anyone and not registered as well",
+ event->GetIdentifier());
+ return false;
+ }
+
+ // Retrieve the set of listeners for this event
+ auto& listeners_set = it->second;
+
+ // Check if the set of listeners is empty
+ if (listeners_set.empty()) {
+ // Log a warning if nobody is listening to this event
+ SPDLOG_WARN("event {} is not listening by anyone", event->GetIdentifier());
+ return false;
+ }
+
+ // Log the number of listeners for this event
+ SPDLOG_DEBUG("event {}'s current listeners size: {}", event->GetIdentifier(),
+ listeners_set.size());
+
+ // Iterate through each listener and execute the corresponding plugin
+ for (auto& listener_plugin_id : listeners_set) {
+ // Search for the plugin's information in the registration table
+ auto plugin_info_opt = search_plugin_register_table(listener_plugin_id);
+
+ // Log an error if the plugin is not found in the registration table
+ if (!plugin_info_opt.has_value()) {
+ SPDLOG_ERROR("cannot find plugin id {} at register table",
+ listener_plugin_id);
+ }
+
+ // Retrieve the plugin's information
+ auto plugin_info = plugin_info_opt.value();
+
+ // Check if the plugin is activated
+ if (!plugin_info->activate) continue;
+
+ // Execute the plugin and check if it fails
+ if (plugin_info->plugin->Exec(event)) {
+ // Log an error if the plugin execution fails
+ SPDLOG_ERROR("plugin {} executed failed", listener_plugin_id);
+ }
+ }
+
+ // Return true to indicate successful execution of all plugins
+ return true;
+}
+
+int GlobalPluginContext::GetChannel(PluginPtr plugin) {
+ // Search for the plugin in the register table.
+ auto plugin_info_opt =
+ search_plugin_register_table(plugin->gpc_get_identifier());
+ if (!plugin_info_opt.has_value()) {
+ SPDLOG_ERROR(
+ "cannot find plugin id {} at register table, fallbacking to default "
+ "channel",
+ plugin->gpc_get_identifier());
+ return GetDefaultChannel(plugin);
+ }
+
+ auto plugin_info = plugin_info_opt.value();
+ return plugin_info->channel;
+}
+
+int GlobalPluginContext::GetDefaultChannel(PluginPtr) {
+ return GPGFRONTEND_DEFAULT_CHANNEL;
+}
+
+} // namespace GpgFrontend::Plugin
diff --git a/src/core/plugin/GlobalPluginContext.h b/src/core/plugin/GlobalPluginContext.h
new file mode 100644
index 00000000..c53cb28d
--- /dev/null
+++ b/src/core/plugin/GlobalPluginContext.h
@@ -0,0 +1,103 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_GLOBALPLUGINCONTEXT_H
+#define GPGFRONTEND_GLOBALPLUGINCONTEXT_H
+
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+
+#include "core/GpgFrontendCore.h"
+#include "core/plugin/Event.h"
+#include "core/plugin/Plugin.h"
+#include "core/thread/TaskRunner.h"
+
+namespace GpgFrontend::Plugin {
+
+class Plugin;
+class PluginManager;
+
+using PluginList = std::list<std::string>;
+
+struct PluginRegisterInfo {
+ int channel;
+ TaskRunnerPtr task_runner;
+ PluginPtr plugin;
+ bool activate;
+};
+
+using PluginRegisterInfoPtr = std::shared_ptr<PluginRegisterInfo>;
+
+class GPGFRONTEND_CORE_EXPORT GlobalPluginContext : public QObject {
+ Q_OBJECT
+ public:
+ GlobalPluginContext(TaskRunnerPtr);
+
+ int GetChannel(PluginPtr);
+
+ int GetDefaultChannel(PluginPtr);
+
+ std::optional<TaskRunnerPtr> GetTaskRunner(PluginPtr);
+
+ std::optional<TaskRunnerPtr> GetTaskRunner(PluginIdentifier plugin);
+
+ std::optional<TaskRunnerPtr> GetGlobalTaskRunner();
+
+ bool RegisterPlugin(PluginPtr);
+
+ bool ActivePlugin(PluginIdentifier);
+
+ bool DeactivatePlugin(PluginIdentifier);
+
+ bool ListenEvent(PluginIdentifier, EventIdentifier);
+
+ bool TriggerEvent(EventRefrernce);
+
+ private:
+ std::unordered_map<PluginIdentifier, PluginRegisterInfoPtr>
+ plugin_register_table_;
+ std::map<EventIdentifier, std::unordered_set<PluginIdentifier>>
+ plugin_events_table_;
+
+ std::set<int> acquired_channel_;
+ boost::random::mt19937 random_gen_;
+ TaskRunnerPtr default_task_runner_;
+
+ int acquire_new_unique_channel();
+
+ std::optional<PluginRegisterInfoPtr> search_plugin_register_table(
+ PluginIdentifier);
+
+ std::list<PluginIdentifier> &search_plugin_events_table(PluginIdentifier);
+};
+
+} // namespace GpgFrontend::Plugin
+
+#endif // GPGFRONTEND_GLOBALPLUGINCONTEXT_H \ No newline at end of file
diff --git a/src/core/plugin/Plugin.cpp b/src/core/plugin/Plugin.cpp
new file mode 100644
index 00000000..23fb3fce
--- /dev/null
+++ b/src/core/plugin/Plugin.cpp
@@ -0,0 +1,70 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "Plugin.h"
+
+#include "GpgConstants.h"
+#include "core/GpgFrontendCore.h"
+#include "core/plugin/GlobalPluginContext.h"
+
+namespace GpgFrontend::Plugin {
+
+Plugin::Plugin(PluginIdentifier id, PluginVersion version,
+ PluginMetaData meta_data)
+ : self_shared_ptr_(this),
+ identifier_((boost::format("__plugin_%1%") % id).str()),
+ version_(version),
+ meta_data_(meta_data) {}
+
+const GlobalPluginContextPtr
+GpgFrontend::Plugin::Plugin::get_global_plugin_context() {
+ if (global_plugin_context_ == nullptr) {
+ throw std::runtime_error("plugin is not registered by plugin manager");
+ }
+ return global_plugin_context_;
+}
+
+int Plugin::getChannel() {
+ return get_global_plugin_context()->GetChannel(self_shared_ptr_);
+}
+
+int Plugin::getDefaultChannel() {
+ return get_global_plugin_context()->GetDefaultChannel(self_shared_ptr_);
+}
+
+std::optional<TaskRunnerPtr> Plugin::getTaskRunner() {
+ return get_global_plugin_context()->GetTaskRunner(self_shared_ptr_);
+}
+
+bool Plugin::listenEvent(EventIdentifier event) {
+ return get_global_plugin_context()->ListenEvent(gpc_get_identifier(), event);
+}
+
+PluginIdentifier Plugin::GetPluginIdentifier() const { return identifier_; }
+
+PluginIdentifier Plugin::gpc_get_identifier() { return identifier_; }
+
+} // namespace GpgFrontend::Plugin \ No newline at end of file
diff --git a/src/core/plugin/Plugin.h b/src/core/plugin/Plugin.h
new file mode 100644
index 00000000..7983e9dd
--- /dev/null
+++ b/src/core/plugin/Plugin.h
@@ -0,0 +1,100 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_PLUGIN_H
+#define GPGFRONTEND_PLUGIN_H
+
+#include "core/plugin/Event.h"
+#include "core/thread/Task.h"
+#include "core/thread/TaskRunner.h"
+
+namespace GpgFrontend::Plugin {
+
+using TaskRunnerPtr = std::shared_ptr<Thread::TaskRunner>;
+
+class Plugin;
+class GlobalPluginContext;
+class PluginManager;
+
+using PluginIdentifier = std::string;
+using PluginVersion = std::string;
+using PluginMetaData = std::map<std::string, std::string>;
+using PluginPtr = std::shared_ptr<Plugin>;
+
+using GlobalPluginContextPtr = std::shared_ptr<GlobalPluginContext>;
+
+class GPGFRONTEND_CORE_EXPORT Plugin : public QObject {
+ Q_OBJECT
+ public:
+ friend class PluginManager;
+ friend class GlobalPluginContext;
+
+ Plugin(PluginIdentifier, PluginVersion, PluginMetaData);
+
+ virtual bool Register() = 0;
+
+ virtual bool Active() = 0;
+
+ virtual int Exec(EventRefrernce) = 0;
+
+ virtual bool Deactive() = 0;
+
+ PluginIdentifier GetPluginIdentifier() const;
+
+ protected:
+ int getChannel();
+
+ int getDefaultChannel();
+
+ std::optional<TaskRunnerPtr> getTaskRunner();
+
+ bool listenEvent(EventIdentifier);
+
+ private:
+ const GlobalPluginContextPtr global_plugin_context_;
+ const std::shared_ptr<Plugin> self_shared_ptr_;
+ const PluginIdentifier identifier_;
+ const PluginVersion version_;
+ const PluginMetaData meta_data_;
+
+ void pm_set_global_plugin_cotext(GlobalPluginContextPtr);
+
+ PluginIdentifier gpc_get_identifier();
+
+ bool gpc_register_plugin();
+
+ bool gpc_active_plugin();
+
+ bool gpc_deactive_plugin();
+
+ int gpc_exec_plugin();
+
+ const GlobalPluginContextPtr get_global_plugin_context();
+};
+
+} // namespace GpgFrontend::Plugin
+
+#endif // GPGFRONTEND_PLUGIN_H \ No newline at end of file
diff --git a/src/core/plugin/PluginManager.cpp b/src/core/plugin/PluginManager.cpp
new file mode 100644
index 00000000..9fd488bb
--- /dev/null
+++ b/src/core/plugin/PluginManager.cpp
@@ -0,0 +1,85 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "PluginManager.h"
+
+#include <memory>
+
+#include "core/plugin/Event.h"
+#include "core/plugin/GlobalPluginContext.h"
+#include "core/plugin/Plugin.h"
+#include "core/thread/TaskRunner.h"
+
+namespace GpgFrontend::Plugin {
+
+PluginMangerPtr PluginManager::global_plugin_manager_ = nullptr;
+
+PluginManager::PluginManager()
+ : task_runner_(std::make_shared<Thread::TaskRunner>()),
+ global_plugin_context_(
+ std::make_shared<GlobalPluginContext>(task_runner_)) {}
+
+PluginMangerPtr PluginManager::GetInstance() {
+ if (global_plugin_manager_ == nullptr) {
+ global_plugin_manager_ =
+ std::shared_ptr<PluginManager>(new PluginManager());
+ }
+ return global_plugin_manager_;
+}
+
+void PluginManager::RegisterPlugin(PluginPtr plugin) {
+ task_runner_->PostTask(new Thread::Task(
+ std::move([=](GpgFrontend::Thread::Task::DataObjectPtr) -> int {
+ global_plugin_context_->RegisterPlugin(plugin);
+ return 0;
+ }),
+ __func__, nullptr, true));
+}
+
+void PluginManager::TriggerEvent(EventRefrernce event) {
+ task_runner_->PostTask(new Thread::Task(
+ std::move([=](GpgFrontend::Thread::Task::DataObjectPtr) -> int {
+ global_plugin_context_->TriggerEvent(event);
+ return 0;
+ }),
+ __func__, nullptr, true));
+}
+
+void PluginManager::ActivePlugin(PluginIdentifier identifier) {
+ task_runner_->PostTask(new Thread::Task(
+ std::move([=](GpgFrontend::Thread::Task::DataObjectPtr) -> int {
+ global_plugin_context_->ActivePlugin(identifier);
+ return 0;
+ }),
+ __func__, nullptr, true));
+}
+
+std::optional<TaskRunnerPtr> PluginManager::GetTaskRunner(
+ PluginIdentifier plugin_id) {
+ return global_plugin_context_->GetTaskRunner(plugin_id);
+}
+
+} // namespace GpgFrontend::Plugin \ No newline at end of file
diff --git a/src/core/plugin/PluginManager.h b/src/core/plugin/PluginManager.h
new file mode 100644
index 00000000..5b6ac0b1
--- /dev/null
+++ b/src/core/plugin/PluginManager.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_PLUGINMANAGER_H
+#define GPGFRONTEND_PLUGINMANAGER_H
+
+#include <string>
+
+#include "core/GpgFrontendCore.h"
+#include "core/thread/Task.h"
+
+namespace GpgFrontend::Thread {
+class TaskRunner;
+}
+
+namespace GpgFrontend::Plugin {
+
+using TaskRunnerPtr = std::shared_ptr<Thread::TaskRunner>;
+
+class Event;
+class Plugin;
+class GlobalPluginContext;
+class PluginManager;
+
+using EventRefrernce = std::shared_ptr<Event>;
+using PluginIdentifier = std::string;
+using PluginPtr = std::shared_ptr<Plugin>;
+using PluginMangerPtr = std::shared_ptr<PluginManager>;
+using GlobalPluginContextPtr = std::shared_ptr<GlobalPluginContext>;
+
+class GPGFRONTEND_CORE_EXPORT PluginManager : public QObject {
+ Q_OBJECT
+ public:
+ static PluginMangerPtr GetInstance();
+
+ void RegisterPlugin(PluginPtr);
+
+ void TriggerEvent(EventRefrernce);
+
+ void ActivePlugin(PluginIdentifier);
+
+ void DeactivePlugin(PluginIdentifier);
+
+ std::optional<TaskRunnerPtr> GetTaskRunner(PluginIdentifier);
+
+ private:
+ PluginManager();
+
+ static PluginMangerPtr global_plugin_manager_;
+ TaskRunnerPtr task_runner_;
+ GlobalPluginContextPtr global_plugin_context_;
+};
+
+} // namespace GpgFrontend::Plugin
+
+#endif // GPGFRONTEND_PLUGINMANAGER_H \ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index d3a409d9..44176945 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -132,6 +132,9 @@ int main(int argc, char* argv[]) {
int return_from_event_loop_code;
int restart_count = 0;
+ // load integrated plugins
+ GpgFrontend::Plugin::LoadGpgFrontendIntegratedPlugins();
+
do {
#ifndef WINDOWS
int r = sigsetjmp(recover_env, 1);
diff --git a/src/plugin/CMakeLists.txt b/src/plugin/CMakeLists.txt
new file mode 100644
index 00000000..e9cb7b48
--- /dev/null
+++ b/src/plugin/CMakeLists.txt
@@ -0,0 +1,94 @@
+#
+# Copyright (C) 2021 Saturneric
+#
+# 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
+
+# define libgpgfrontend_plugin_sdk
+aux_source_directory(sdk PLUGIN_SDK_SOURCE)
+add_library(gpgfrontend_plugin_sdk SHARED ${PLUGIN_SDK_SOURCE})
+set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/sdk/GpgFrontendPluginSDKExport.h")
+generate_export_header(gpgfrontend_plugin_sdk EXPORT_FILE_NAME "${_export_file}")
+target_include_directories(gpgfrontend_plugin_sdk PUBLIC sdk)
+
+# link json
+target_link_libraries(gpgfrontend_plugin_sdk
+ PUBLIC nlohmann_json::nlohmann_json)
+
+# spdlog
+target_link_libraries(gpgfrontend_plugin_sdk PUBLIC spdlog)
+
+# link Qt core
+if(Qt6_DIR)
+ target_link_libraries(gpgfrontend_plugin_sdk PUBLIC Qt6::Core)
+else()
+ target_link_libraries(gpgfrontend_plugin_sdk PUBLIC Qt5::Core)
+endif()
+
+# link core and ui module
+target_link_libraries(gpgfrontend_plugin_sdk PRIVATE
+ gpgfrontend_core gpgfrontend_ui)
+
+# tracking integrated plugins
+set(all_integrated_plugins_libraries "")
+file(GLOB children LIST_DIRECTORIES true "integrated_plugins/*")
+foreach(child ${children})
+ if(IS_DIRECTORY ${child})
+ get_filename_component(dirName ${child} NAME)
+ add_subdirectory("integrated_plugins/${dirName}")
+
+ string(REPLACE "_plugin" "" stripped_plugin ${dirName})
+ set(integrated_lib_name "gpgfrontend_integrated_plugin_${stripped_plugin}")
+ list(APPEND all_integrated_plugins_libraries ${integrated_lib_name})
+ endif()
+endforeach()
+
+set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
+aux_source_directory(. PLUGIN_SOURCE)
+add_library(gpgfrontend_plugin SHARED ${PLUGIN_SOURCE})
+
+set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendPluginExport.h")
+generate_export_header(gpgfrontend_plugin EXPORT_FILE_NAME "${_export_file}")
+
+# set up pch
+target_precompile_headers(gpgfrontend_plugin PUBLIC GpgFrontendPlugin.h)
+
+# add ui generator include path
+target_include_directories(gpgfrontend_plugin PUBLIC
+ ${CMAKE_CURRENT_BINARY_DIR}/gpgfrontend_plugin_autogen/include
+ ${CMAKE_SOURCE_DIR}/third_party/spdlog/include)
+
+target_link_libraries(gpgfrontend_plugin PRIVATE
+ gpgfrontend_core gpgfrontend_ui)
+
+# link gpgfrontend_plugin_sdk
+target_link_libraries(gpgfrontend_plugin PRIVATE
+ gpgfrontend_plugin_sdk)
+
+# link all integrated plugins
+message(STATUS "All Integrated Plugin Libraries: ${all_integrated_plugins_libraries}")
+target_link_libraries(gpgfrontend_plugin PRIVATE ${all_integrated_plugins_libraries})
+
+# using std c++ 17
+target_compile_features(gpgfrontend_plugin PUBLIC cxx_std_17) \ No newline at end of file
diff --git a/src/plugin/GpgFrontendPlugin.h b/src/plugin/GpgFrontendPlugin.h
new file mode 100644
index 00000000..8ba2bf66
--- /dev/null
+++ b/src/plugin/GpgFrontendPlugin.h
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_GPGFRONTENDPLUGIN_H
+#define GPGFRONTEND_GPGFRONTENDPLUGIN_H
+
+/**
+ * Project internal dependencies
+ */
+#include "GpgFrontend.h"
+#include "GpgFrontendPluginExport.h"
+#include "core/GpgFrontendCore.h"
+
+#endif // GPGFRONTEND_GPGFRONTENDPLUGIN_H \ No newline at end of file
diff --git a/src/plugin/GpgFrontendPluginExport.h b/src/plugin/GpgFrontendPluginExport.h
new file mode 100644
index 00000000..a0eaa86c
--- /dev/null
+++ b/src/plugin/GpgFrontendPluginExport.h
@@ -0,0 +1,42 @@
+
+#ifndef GPGFRONTEND_PLUGIN_EXPORT_H
+#define GPGFRONTEND_PLUGIN_EXPORT_H
+
+#ifdef GPGFRONTEND_PLUGIN_STATIC_DEFINE
+# define GPGFRONTEND_PLUGIN_EXPORT
+# define GPGFRONTEND_PLUGIN_NO_EXPORT
+#else
+# ifndef GPGFRONTEND_PLUGIN_EXPORT
+# ifdef gpgfrontend_plugin_EXPORTS
+ /* We are building this library */
+# define GPGFRONTEND_PLUGIN_EXPORT __attribute__((visibility("default")))
+# else
+ /* We are using this library */
+# define GPGFRONTEND_PLUGIN_EXPORT __attribute__((visibility("default")))
+# endif
+# endif
+
+# ifndef GPGFRONTEND_PLUGIN_NO_EXPORT
+# define GPGFRONTEND_PLUGIN_NO_EXPORT __attribute__((visibility("hidden")))
+# endif
+#endif
+
+#ifndef GPGFRONTEND_PLUGIN_DEPRECATED
+# define GPGFRONTEND_PLUGIN_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef GPGFRONTEND_PLUGIN_DEPRECATED_EXPORT
+# define GPGFRONTEND_PLUGIN_DEPRECATED_EXPORT GPGFRONTEND_PLUGIN_EXPORT GPGFRONTEND_PLUGIN_DEPRECATED
+#endif
+
+#ifndef GPGFRONTEND_PLUGIN_DEPRECATED_NO_EXPORT
+# define GPGFRONTEND_PLUGIN_DEPRECATED_NO_EXPORT GPGFRONTEND_PLUGIN_NO_EXPORT GPGFRONTEND_PLUGIN_DEPRECATED
+#endif
+
+#if 0 /* DEFINE_NO_DEPRECATED */
+# ifndef GPGFRONTEND_PLUGIN_NO_DEPRECATED
+# define GPGFRONTEND_PLUGIN_NO_DEPRECATED
+# endif
+#endif
+
+#endif /* GPGFRONTEND_PLUGIN_EXPORT_H */
diff --git a/src/plugin/GpgFrontendPluginInit.cpp b/src/plugin/GpgFrontendPluginInit.cpp
new file mode 100644
index 00000000..53455447
--- /dev/null
+++ b/src/plugin/GpgFrontendPluginInit.cpp
@@ -0,0 +1,99 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "GpgFrontendPluginInit.h"
+
+#include <spdlog/async.h>
+#include <spdlog/common.h>
+#include <spdlog/sinks/rotating_file_sink.h>
+#include <spdlog/sinks/stdout_color_sinks.h>
+
+#include <memory>
+
+#include "core/function/GlobalSettingStation.h"
+#include "core/plugin/Plugin.h"
+#include "core/plugin/PluginManager.h"
+
+// integrated plugins
+#include "integrated_plugins/version_checking_plugin/VersionCheckingPlugin.h"
+
+namespace GpgFrontend::Plugin {
+
+void LoadGpgFrontendIntegratedPlugins() {
+ PluginManager::GetInstance()->RegisterPlugin(
+ std::make_shared<
+ IntegradedPlugin::VersionCheckingPlugin::VersionCheckingPlugin>());
+}
+
+void InitPluginLoggingSystem() {
+ using namespace boost::posix_time;
+ using namespace boost::gregorian;
+
+ // get the log directory
+ auto logfile_path =
+ (GpgFrontend::GlobalSettingStation::GetInstance().GetLogDir() / "plugin");
+ logfile_path.replace_extension(".log");
+
+ // sinks
+ std::vector<spdlog::sink_ptr> sinks;
+ sinks.push_back(std::make_shared<spdlog::sinks::stderr_color_sink_mt>());
+ sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
+ logfile_path.u8string(), 1048576 * 32, 32));
+
+ // thread pool
+ spdlog::init_thread_pool(1024, 2);
+
+ // logger
+ auto plugin_logger = std::make_shared<spdlog::async_logger>(
+ "ui", begin(sinks), end(sinks), spdlog::thread_pool());
+ plugin_logger->set_pattern(
+ "[%H:%M:%S.%e] [T:%t] [%=4n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
+
+#ifdef DEBUG
+ plugin_logger->set_level(spdlog::level::trace);
+#else
+ ui_logger->set_level(spdlog::level::info);
+#endif
+
+ // flush policy
+ plugin_logger->flush_on(spdlog::level::err);
+ spdlog::flush_every(std::chrono::seconds(5));
+
+ // register it as default logger
+ spdlog::set_default_logger(plugin_logger);
+}
+
+void ShutdownPluginLoggingSystem() {
+#ifdef WINDOWS
+ // Under VisualStudio, this must be called before main finishes to workaround
+ // a known VS issue
+ spdlog::drop_all();
+ spdlog::shutdown();
+#endif
+}
+} // namespace GpgFrontend::Plugin \ No newline at end of file
diff --git a/src/plugin/GpgFrontendPluginInit.h b/src/plugin/GpgFrontendPluginInit.h
new file mode 100644
index 00000000..683ba896
--- /dev/null
+++ b/src/plugin/GpgFrontendPluginInit.h
@@ -0,0 +1,56 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_GPGFRONTENDPLUGININIT_H
+#define GPGFRONTEND_GPGFRONTENDPLUGININIT_H
+
+#include "plugin/GpgFrontendPlugin.h"
+
+namespace GpgFrontend::Plugin {
+
+/**
+ * @brief init the plugin library
+ *
+ */
+void GPGFRONTEND_PLUGIN_EXPORT LoadGpgFrontendIntegratedPlugins();
+
+/**
+ * @brief
+ *
+ */
+void GPGFRONTEND_PLUGIN_EXPORT InitPluginLoggingSystem();
+
+/**
+ * @brief
+ *
+ */
+void GPGFRONTEND_PLUGIN_EXPORT ShutdownPluginLoggingSystem();
+
+}; // namespace GpgFrontend::Plugin
+
+#endif // GPGFRONTEND_GPGFRONTENDPLUGININIT_H
diff --git a/src/plugin/integrated_plugins/version_checking_plugin/CMakeLists.txt b/src/plugin/integrated_plugins/version_checking_plugin/CMakeLists.txt
new file mode 100644
index 00000000..bca0f2d4
--- /dev/null
+++ b/src/plugin/integrated_plugins/version_checking_plugin/CMakeLists.txt
@@ -0,0 +1,46 @@
+#
+# Copyright (C) 2021 Saturneric
+#
+# 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
+
+aux_source_directory(. INTEGRATED_PLUGIN_SOURCE)
+
+# define libgpgfrontend_plugin
+set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
+add_library(gpgfrontend_integrated_plugin_version_checking SHARED ${INTEGRATED_PLUGIN_SOURCE})
+
+# link sdk
+target_link_libraries(gpgfrontend_integrated_plugin_version_checking PRIVATE
+ gpgfrontend_plugin_sdk)
+
+# link Qt
+if(Qt6_DIR)
+ target_link_libraries(gpgfrontend_integrated_plugin_version_checking PRIVATE Qt6::Network)
+else()
+ target_link_libraries(gpgfrontend_integrated_plugin_version_checking PRIVATE Qt5::Network)
+endif()
+
+# using std c++ 17
+target_compile_features(gpgfrontend_integrated_plugin_version_checking PRIVATE cxx_std_17) \ No newline at end of file
diff --git a/src/plugin/integrated_plugins/version_checking_plugin/SoftwareVersion.cpp b/src/plugin/integrated_plugins/version_checking_plugin/SoftwareVersion.cpp
new file mode 100644
index 00000000..9ea4b80f
--- /dev/null
+++ b/src/plugin/integrated_plugins/version_checking_plugin/SoftwareVersion.cpp
@@ -0,0 +1,105 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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"
+
+int GpgFrontend::Plugin::IntegradedPlugin::VersionCheckingPlugin::
+ SoftwareVersion::version_compare(const std::string& a,
+ const std::string& b) {
+ auto temp_a = a, temp_b = b;
+
+ if (!temp_a.empty() && temp_a.front() == 'v') {
+ temp_a = temp_a.erase(0, 1);
+ SPDLOG_DEBUG("real version a: {}", temp_a);
+ }
+
+ if (!temp_b.empty() && temp_b.front() == 'v') {
+ temp_b.erase(0, 1);
+ SPDLOG_DEBUG("real version b: {}", temp_b);
+ }
+
+ // First, split the string.
+ std::vector<std::string> va, vb;
+ boost::split(va, temp_a, boost::is_any_of("."));
+ boost::split(vb, temp_b, boost::is_any_of("."));
+
+ // Compare the numbers step by step, but only as deep as the version
+ // with the least elements allows.
+ const int depth =
+ std::min(static_cast<int>(va.size()), static_cast<int>(vb.size()));
+ int ia = 0, ib = 0;
+ for (int i = 0; i < depth; ++i) {
+ try {
+ ia = boost::lexical_cast<int>(va[i]);
+ ib = boost::lexical_cast<int>(vb[i]);
+ } catch (boost::bad_lexical_cast& ignored) {
+ break;
+ }
+ if (ia != ib) break;
+ }
+
+ // Return the required number.
+ if (ia > ib)
+ return 1;
+ else if (ia < ib)
+ return -1;
+ else {
+ // In case of equal versions, assumes that the version
+ // with the most elements is the highest version.
+ if (va.size() > vb.size())
+ return 1;
+ else if (va.size() < vb.size())
+ return -1;
+ }
+
+ // Everything is equal, return 0.
+ return 0;
+}
+
+bool GpgFrontend::Plugin::IntegradedPlugin::VersionCheckingPlugin::
+ SoftwareVersion::NeedUpgrade() const {
+ SPDLOG_DEBUG("compair version current {} latest {}, result {}",
+ current_version, latest_version,
+ version_compare(current_version, latest_version));
+
+ SPDLOG_DEBUG("load done: {}, pre-release: {}, draft: {}", load_info_done,
+ latest_prerelease, latest_draft);
+ return load_info_done && !latest_prerelease && !latest_draft &&
+ version_compare(current_version, latest_version) < 0;
+}
+
+bool GpgFrontend::Plugin::IntegradedPlugin::VersionCheckingPlugin::
+ SoftwareVersion::VersionWithDrawn() const {
+ return load_info_done && !current_version_found && current_prerelease &&
+ !current_draft;
+}
+
+bool GpgFrontend::Plugin::IntegradedPlugin::VersionCheckingPlugin::
+ SoftwareVersion::CurrentVersionReleased() const {
+ return load_info_done && current_version_found;
+} \ No newline at end of file
diff --git a/src/plugin/integrated_plugins/version_checking_plugin/SoftwareVersion.h b/src/plugin/integrated_plugins/version_checking_plugin/SoftwareVersion.h
new file mode 100644
index 00000000..8d33e920
--- /dev/null
+++ b/src/plugin/integrated_plugins/version_checking_plugin/SoftwareVersion.h
@@ -0,0 +1,90 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_PLUGIN_SOFTWAREVERSION_H
+#define GPGFRONTEND_PLUGIN_SOFTWAREVERSION_H
+
+#include <GpgFrontendPluginSDK.h>
+
+#include <boost/date_time.hpp>
+
+namespace GpgFrontend::Plugin::IntegradedPlugin::VersionCheckingPlugin {
+/**
+ * @brief
+ *
+ */
+struct SoftwareVersion {
+ std::string latest_version; ///<
+ std::string current_version; ///<
+ bool latest_prerelease = false; ///<
+ bool latest_draft = false; ///<
+ bool current_prerelease = false; ///<
+ bool current_draft = false; ///<
+ bool load_info_done = false; ///<
+ bool current_version_found = false; ///<
+ std::string publish_date; ///<
+ std::string release_note; ///<
+
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ [[nodiscard]] bool InfoValid() const { return load_info_done; }
+
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ [[nodiscard]] bool NeedUpgrade() const;
+
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ [[nodiscard]] bool VersionWithDrawn() const;
+
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ [[nodiscard]] bool CurrentVersionReleased() const;
+
+ private:
+ static int version_compare(const std::string& a, const std::string& b);
+};
+} // namespace GpgFrontend::Plugin::IntegradedPlugin::VersionCheckingPlugin
+
+#endif // GPGFRONTEND_PLUGIN_SOFTWAREVERSION_H
diff --git a/src/plugin/integrated_plugins/version_checking_plugin/VersionCheckTask.cpp b/src/plugin/integrated_plugins/version_checking_plugin/VersionCheckTask.cpp
new file mode 100644
index 00000000..9cf4442f
--- /dev/null
+++ b/src/plugin/integrated_plugins/version_checking_plugin/VersionCheckTask.cpp
@@ -0,0 +1,179 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "VersionCheckTask.h"
+
+#include <QMetaType>
+#include <QtNetwork>
+#include <memory>
+
+#include "GpgFrontendBuildInfo.h"
+
+namespace GpgFrontend::Plugin::IntegradedPlugin::VersionCheckingPlugin {
+
+VersionCheckTask::VersionCheckTask()
+ : STask("version_check_task"),
+ network_manager_(new QNetworkAccessManager(this)),
+ current_version_(std::string("v") + std::to_string(VERSION_MAJOR) + "." +
+ std::to_string(VERSION_MINOR) + "." +
+ std::to_string(VERSION_PATCH)) {
+ qRegisterMetaType<SoftwareVersion>("SoftwareVersion");
+ version_.current_version = current_version_;
+}
+
+void VersionCheckTask::Run() {
+ HoldOnLifeCycle(true);
+
+ try {
+ using namespace nlohmann;
+ SPDLOG_DEBUG("current version: {}", current_version_);
+ std::string latest_version_url =
+ "https://api.github.com/repos/saturneric/gpgfrontend/releases/latest";
+
+ QNetworkRequest latest_request;
+ latest_request.setUrl(QUrl(latest_version_url.c_str()));
+ latest_reply_ = network_manager_->get(latest_request);
+ connect(latest_reply_, &QNetworkReply::finished, this,
+ &VersionCheckTask::slot_parse_latest_version_info);
+
+ // loading done
+ version_.load_info_done = true;
+
+ } catch (...) {
+ SPDLOG_ERROR("unknown error occurred");
+ emit SignalTaskRunnableEnd(-1);
+ }
+}
+
+void VersionCheckTask::slot_parse_latest_version_info() {
+ version_.current_version = current_version_;
+
+ try {
+ if (latest_reply_ == nullptr ||
+ latest_reply_->error() != QNetworkReply::NoError) {
+ SPDLOG_ERROR("latest version request error");
+ version_.latest_version = current_version_;
+ } else {
+ latest_reply_bytes_ = latest_reply_->readAll();
+
+ auto latest_reply_json =
+ nlohmann::json::parse(latest_reply_bytes_.toStdString());
+
+ std::string latest_version = latest_reply_json["tag_name"];
+
+ SPDLOG_INFO("latest version from Github: {}", latest_version);
+
+ QRegularExpression re(R"(^[vV](\d+\.)?(\d+\.)?(\*|\d+))");
+ auto version_match = re.match(latest_version.c_str());
+ if (version_match.hasMatch()) {
+ latest_version = version_match.captured(0).toStdString();
+ SPDLOG_DEBUG("latest version matched: {}", latest_version);
+ } else {
+ latest_version = current_version_;
+ SPDLOG_WARN("latest version unknown");
+ }
+
+ bool prerelease = latest_reply_json["prerelease"],
+ draft = latest_reply_json["draft"];
+ std::string publish_date = latest_reply_json["published_at"];
+ std::string release_note = latest_reply_json["body"];
+ version_.latest_version = latest_version;
+ version_.latest_prerelease = prerelease;
+ version_.latest_draft = draft;
+ version_.publish_date = publish_date;
+ version_.release_note = release_note;
+ }
+ } catch (...) {
+ SPDLOG_ERROR("unknown error occurred");
+ version_.load_info_done = false;
+ }
+
+ if (latest_reply_ != nullptr) {
+ latest_reply_->deleteLater();
+ }
+
+ try {
+ std::string current_version_url =
+ "https://api.github.com/repos/saturneric/gpgfrontend/releases/tags/" +
+ current_version_;
+
+ QNetworkRequest current_request;
+ current_request.setUrl(QUrl(current_version_url.c_str()));
+ current_reply_ = network_manager_->get(current_request);
+
+ connect(current_reply_, &QNetworkReply::finished, this,
+ &VersionCheckTask::slot_parse_current_version_info);
+ } catch (...) {
+ SPDLOG_ERROR("current version request create error");
+ emit SignalTaskRunnableEnd(-1);
+ }
+}
+
+void VersionCheckTask::slot_parse_current_version_info() {
+ try {
+ if (current_reply_ == nullptr ||
+ current_reply_->error() != QNetworkReply::NoError) {
+ if (current_reply_ != nullptr) {
+ SPDLOG_ERROR("current version request network error: {}",
+ current_reply_->errorString().toStdString());
+ } else {
+ SPDLOG_ERROR(
+ "current version request network error, null reply object");
+ }
+
+ version_.current_version_found = false;
+ version_.load_info_done = false;
+ } else {
+ version_.current_version_found = true;
+ current_reply_bytes_ = current_reply_->readAll();
+ SPDLOG_DEBUG("current version: {}", current_reply_bytes_.size());
+ auto current_reply_json =
+ nlohmann::json::parse(current_reply_bytes_.toStdString());
+ bool current_prerelease = current_reply_json["prerelease"],
+ current_draft = current_reply_json["draft"];
+ version_.latest_prerelease = current_prerelease;
+ version_.latest_draft = current_draft;
+ version_.load_info_done = true;
+ }
+ } catch (...) {
+ SPDLOG_ERROR("unknown error occurred");
+ version_.load_info_done = false;
+ }
+
+ SPDLOG_DEBUG("current version parse done: {}",
+ version_.current_version_found);
+
+ if (current_reply_ != nullptr) {
+ current_reply_->deleteLater();
+ }
+
+ emit SignalUpgradeVersion(version_);
+ emit SignalTaskRunnableEnd(0);
+}
+
+} // namespace GpgFrontend::Plugin::IntegradedPlugin::VersionCheckingPlugin
diff --git a/src/plugin/integrated_plugins/version_checking_plugin/VersionCheckTask.h b/src/plugin/integrated_plugins/version_checking_plugin/VersionCheckTask.h
new file mode 100644
index 00000000..f7d7ad41
--- /dev/null
+++ b/src/plugin/integrated_plugins/version_checking_plugin/VersionCheckTask.h
@@ -0,0 +1,99 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_VERSIONCHECKTHREAD_H
+#define GPGFRONTEND_VERSIONCHECKTHREAD_H
+
+#include <GpgFrontendPluginSDK.h>
+#include <Task.h>
+
+#include "SoftwareVersion.h"
+
+class QNetworkReply;
+class QNetworkAccessManager;
+
+namespace GpgFrontend::Plugin::IntegradedPlugin::VersionCheckingPlugin {
+
+/**
+ * @brief
+ *
+ */
+class VersionCheckTask : public SDK::STask {
+ Q_OBJECT
+ public:
+ /**
+ * @brief Construct a new Version Check Thread object
+ *
+ */
+ explicit VersionCheckTask();
+
+ signals:
+
+ /**
+ * @brief
+ *
+ * @param version
+ */
+ void SignalUpgradeVersion(SoftwareVersion version);
+
+ protected:
+ /**
+ * @brief
+
+ *
+ */
+ void Run() override;
+
+ private slots:
+
+ /**
+ * @brief
+ *
+ */
+ void slot_parse_latest_version_info();
+
+ /**
+ * @brief
+ *
+ */
+ void slot_parse_current_version_info();
+
+ private:
+ QByteArray latest_reply_bytes_; ///<
+ QByteArray current_reply_bytes_; ///<
+ QNetworkReply* latest_reply_ = nullptr; ///< latest version info reply
+ QNetworkReply* current_reply_ = nullptr; ///< current version info reply
+ QNetworkAccessManager* network_manager_; ///<
+ std::string current_version_;
+ SoftwareVersion version_;
+};
+
+} // namespace GpgFrontend::Plugin::IntegradedPlugin::VersionCheckingPlugin
+ // GpgFrontend::Plugin::Custom::IntegradedPlugin::VersionCheckingPlugin
+
+#endif // GPGFRONTEND_VERSIONCHECKTHREAD_H
diff --git a/src/plugin/integrated_plugins/version_checking_plugin/VersionCheckingPlugin.cpp b/src/plugin/integrated_plugins/version_checking_plugin/VersionCheckingPlugin.cpp
new file mode 100644
index 00000000..1de12db4
--- /dev/null
+++ b/src/plugin/integrated_plugins/version_checking_plugin/VersionCheckingPlugin.cpp
@@ -0,0 +1,63 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "VersionCheckingPlugin.h"
+
+#include "Plugin.h"
+#include "Task.h"
+#include "VersionCheckTask.h"
+
+namespace GpgFrontend::Plugin::IntegradedPlugin::VersionCheckingPlugin {
+
+VersionCheckingPlugin::VersionCheckingPlugin()
+ : SPlugin("com.bktus.gpgfrontend.plugin.integrated.versionchecking",
+ "1.0.0",
+ SDK::SPluginMetaData{
+ {"description", "try to check gpgfrontend version"},
+ {"author", "saturneric"}}) {}
+
+bool VersionCheckingPlugin::Register() {
+ SPDLOG_INFO("version checking plugin registering");
+ return true;
+}
+
+bool VersionCheckingPlugin::Active() {
+ SPDLOG_INFO("version checking plugin activating");
+
+ listenEvent("APPLICATION_STARTED");
+ return true;
+}
+
+int VersionCheckingPlugin::Exec(SDK::SEventRefrernce event) {
+ SPDLOG_INFO("version checking plugin ececuting");
+ SDK::PostTask(SDK::GetPluginTaskRunner(this), new VersionCheckTask());
+ return 0;
+}
+
+bool VersionCheckingPlugin::Deactive() { return true; }
+} // namespace GpgFrontend::Plugin::IntegradedPlugin::VersionCheckingPlugin
diff --git a/src/plugin/integrated_plugins/version_checking_plugin/VersionCheckingPlugin.h b/src/plugin/integrated_plugins/version_checking_plugin/VersionCheckingPlugin.h
new file mode 100644
index 00000000..88652de6
--- /dev/null
+++ b/src/plugin/integrated_plugins/version_checking_plugin/VersionCheckingPlugin.h
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_PLUGIN_VERSIONCHECKINGPLUGIN_H
+#define GPGFRONTEND_PLUGIN_VERSIONCHECKINGPLUGIN_H
+
+#include <GpgFrontendPluginSDK.h>
+#include <Plugin.h>
+
+#include "SoftwareVersion.h"
+
+namespace GpgFrontend::Plugin::IntegradedPlugin::VersionCheckingPlugin {
+
+class GPGFRONTEND_PLUGIN_SDK_EXPORT VersionCheckingPlugin
+ : public SDK::SPlugin {
+ public:
+ VersionCheckingPlugin();
+
+ virtual bool Register() override;
+
+ virtual bool Active() override;
+
+ virtual int Exec(SDK::SEventRefrernce) override;
+
+ virtual bool Deactive() override;
+};
+} // namespace GpgFrontend::Plugin::IntegradedPlugin::VersionCheckingPlugin
+
+#endif // GPGFRONTEND_PLUGIN_VERSIONCHECKINGPLUGIN_H \ No newline at end of file
diff --git a/src/plugin/sdk/Basic.cpp b/src/plugin/sdk/Basic.cpp
new file mode 100644
index 00000000..71a5aaee
--- /dev/null
+++ b/src/plugin/sdk/Basic.cpp
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */ \ No newline at end of file
diff --git a/src/plugin/sdk/Basic.h b/src/plugin/sdk/Basic.h
new file mode 100644
index 00000000..71a5aaee
--- /dev/null
+++ b/src/plugin/sdk/Basic.h
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */ \ No newline at end of file
diff --git a/src/plugin/sdk/Gpg.cpp b/src/plugin/sdk/Gpg.cpp
new file mode 100644
index 00000000..71a5aaee
--- /dev/null
+++ b/src/plugin/sdk/Gpg.cpp
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */ \ No newline at end of file
diff --git a/src/plugin/sdk/Gpg.h b/src/plugin/sdk/Gpg.h
new file mode 100644
index 00000000..71a5aaee
--- /dev/null
+++ b/src/plugin/sdk/Gpg.h
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */ \ No newline at end of file
diff --git a/src/plugin/sdk/GpgFrontendPluginSDK.h b/src/plugin/sdk/GpgFrontendPluginSDK.h
new file mode 100644
index 00000000..7b45c7f3
--- /dev/null
+++ b/src/plugin/sdk/GpgFrontendPluginSDK.h
@@ -0,0 +1,31 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 <core/GpgFrontendCore.h>
+
+#include "GpgFrontendPluginSDKExport.h" \ No newline at end of file
diff --git a/src/plugin/sdk/GpgFrontendPluginSDKExport.h b/src/plugin/sdk/GpgFrontendPluginSDKExport.h
new file mode 100644
index 00000000..8e508e35
--- /dev/null
+++ b/src/plugin/sdk/GpgFrontendPluginSDKExport.h
@@ -0,0 +1,42 @@
+
+#ifndef GPGFRONTEND_PLUGIN_SDK_EXPORT_H
+#define GPGFRONTEND_PLUGIN_SDK_EXPORT_H
+
+#ifdef GPGFRONTEND_PLUGIN_SDK_STATIC_DEFINE
+# define GPGFRONTEND_PLUGIN_SDK_EXPORT
+# define GPGFRONTEND_PLUGIN_SDK_NO_EXPORT
+#else
+# ifndef GPGFRONTEND_PLUGIN_SDK_EXPORT
+# ifdef gpgfrontend_plugin_sdk_EXPORTS
+ /* We are building this library */
+# define GPGFRONTEND_PLUGIN_SDK_EXPORT __attribute__((visibility("default")))
+# else
+ /* We are using this library */
+# define GPGFRONTEND_PLUGIN_SDK_EXPORT __attribute__((visibility("default")))
+# endif
+# endif
+
+# ifndef GPGFRONTEND_PLUGIN_SDK_NO_EXPORT
+# define GPGFRONTEND_PLUGIN_SDK_NO_EXPORT __attribute__((visibility("hidden")))
+# endif
+#endif
+
+#ifndef GPGFRONTEND_PLUGIN_SDK_DEPRECATED
+# define GPGFRONTEND_PLUGIN_SDK_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef GPGFRONTEND_PLUGIN_SDK_DEPRECATED_EXPORT
+# define GPGFRONTEND_PLUGIN_SDK_DEPRECATED_EXPORT GPGFRONTEND_PLUGIN_SDK_EXPORT GPGFRONTEND_PLUGIN_SDK_DEPRECATED
+#endif
+
+#ifndef GPGFRONTEND_PLUGIN_SDK_DEPRECATED_NO_EXPORT
+# define GPGFRONTEND_PLUGIN_SDK_DEPRECATED_NO_EXPORT GPGFRONTEND_PLUGIN_SDK_NO_EXPORT GPGFRONTEND_PLUGIN_SDK_DEPRECATED
+#endif
+
+#if 0 /* DEFINE_NO_DEPRECATED */
+# ifndef GPGFRONTEND_PLUGIN_SDK_NO_DEPRECATED
+# define GPGFRONTEND_PLUGIN_SDK_NO_DEPRECATED
+# endif
+#endif
+
+#endif /* GPGFRONTEND_PLUGIN_SDK_EXPORT_H */
diff --git a/src/plugin/sdk/Plugin.cpp b/src/plugin/sdk/Plugin.cpp
new file mode 100644
index 00000000..5d715105
--- /dev/null
+++ b/src/plugin/sdk/Plugin.cpp
@@ -0,0 +1,62 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "Plugin.h"
+
+#include <core/plugin/PluginManager.h>
+
+namespace GpgFrontend::Plugin::SDK {
+
+SPlugin::SPlugin(SPluginIdentifier id, SPluginVersion version,
+ SPluginMetaData meta_data)
+ : Plugin::Plugin(id, version, meta_data) {}
+
+bool SPlugin::Register() { return true; }
+
+bool SPlugin::Active() { return true; }
+
+int SPlugin::Exec(SEventRefrernce) { return 0; }
+
+bool SPlugin::Deactive() { return true; }
+
+SPluginIdentifier SPlugin::GetSPluginIdentifier() const {
+ return GetPluginIdentifier();
+}
+
+Thread::TaskRunner* GetPluginTaskRunner(SPlugin* plugin) {
+ if (plugin == nullptr) return nullptr;
+
+ auto opt = GpgFrontend::Plugin::PluginManager::GetInstance()->GetTaskRunner(
+ plugin->GetSPluginIdentifier());
+ if (!opt.has_value()) {
+ return nullptr;
+ }
+
+ return opt.value().get();
+}
+} // namespace GpgFrontend::Plugin::SDK
diff --git a/src/plugin/sdk/Plugin.h b/src/plugin/sdk/Plugin.h
new file mode 100644
index 00000000..2ec55fcb
--- /dev/null
+++ b/src/plugin/sdk/Plugin.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_SDK_PLUGIN_H
+#define GPGFRONTEND_SDK_PLUGIN_H
+
+#include <core/plugin/Plugin.h>
+#include <core/plugin/PluginManager.h>
+
+#include "GpgFrontendPluginSDK.h"
+#include "Task.h"
+
+namespace GpgFrontend::Plugin::SDK {
+
+class SPlugin;
+
+using SEventRefrernce = std::shared_ptr<Event>;
+using SEventIdentifier = std::string;
+using SPluginIdentifier = std::string;
+using SPluginVersion = std::string;
+using SPluginMetaData = std::map<std::string, std::string>;
+using SEvnets = std::vector<Event>;
+using GlobalPluginContextPtr = std::shared_ptr<GlobalPluginContext>;
+using SPluginPtr = std::shared_ptr<SPlugin>;
+using SPluginList = std::list<std::string>;
+
+class GPGFRONTEND_PLUGIN_SDK_EXPORT SPlugin
+ : public GpgFrontend::Plugin::Plugin {
+ Q_OBJECT
+ public:
+ SPlugin(SPluginIdentifier, SPluginVersion, SPluginMetaData);
+
+ virtual ~SPlugin() = default;
+
+ SPluginIdentifier GetSPluginIdentifier() const;
+
+ virtual bool Register() override;
+
+ virtual bool Active() override;
+
+ virtual int Exec(SEventRefrernce) override;
+
+ virtual bool Deactive() override;
+};
+
+class GPGFRONTEND_PLUGIN_SDK_EXPORT SEvent
+ : protected GpgFrontend::Plugin::Event {};
+
+bool GPGFRONTEND_PLUGIN_SDK_EXPORT ListenEvent(SPluginPtr, SEvent);
+
+Thread::TaskRunner* GetPluginTaskRunner(SPlugin*);
+} // namespace GpgFrontend::Plugin::SDK
+
+#endif // GPGFRONTEND_SDK_PLUGIN_H \ No newline at end of file
diff --git a/src/plugin/sdk/Task.cpp b/src/plugin/sdk/Task.cpp
new file mode 100644
index 00000000..f06fb297
--- /dev/null
+++ b/src/plugin/sdk/Task.cpp
@@ -0,0 +1,62 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "Task.h"
+
+#include "core/thread/Task.h"
+
+namespace GpgFrontend::Plugin::SDK {
+/**
+ * @brief Construct a new Task object
+ *
+ */
+STask::STask(STaskName name) : Thread::Task(name) {}
+
+/**
+ * @brief Construct a new Task object
+ *
+ * @param callback The callback function to be executed.
+ */
+STask::STask(STaskName name, STaskRunnable runnable, SDataObjectPtr data_object)
+ : Thread::Task(runnable, name, data_object, true) {}
+
+/**
+ * @brief Construct a new Task object
+ *
+ * @param runnable
+ */
+STask::STask(STaskName name, STaskRunnable runnable, SDataObjectPtr data_object,
+ STaskCallback callback)
+ : Thread::Task(runnable, name, data_object, callback, true) {}
+
+void PostTask(Thread::TaskRunner *runner, STask *task) {
+ if (runner == nullptr || task == nullptr) return;
+ runner->PostTask(task);
+}
+
+} // namespace GpgFrontend::Plugin::SDK \ No newline at end of file
diff --git a/src/plugin/sdk/Task.h b/src/plugin/sdk/Task.h
new file mode 100644
index 00000000..f4f87308
--- /dev/null
+++ b/src/plugin/sdk/Task.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_SDK_TASK_H
+#define GPGFRONTEND_SDK_TASK_H
+
+#include <string>
+
+#include "GpgFrontendPluginSDK.h"
+#include "core/thread/Task.h"
+#include "core/thread/TaskRunner.h"
+
+namespace GpgFrontend::Plugin::SDK {
+
+using STaskRunnerPtr = std::shared_ptr<Thread::TaskRunner>;
+
+class GPGFRONTEND_PLUGIN_SDK_EXPORT STask : public Thread::Task {
+ Q_OBJECT
+ public:
+ using STaskName = std::string;
+ using SDataObjectPtr = std::shared_ptr<DataObject>; ///<
+ using STaskRunnable = std::function<int(SDataObjectPtr)>; ///<
+ using STaskCallback = std::function<void(int, SDataObjectPtr)>; ///<
+
+ /**
+ * @brief Construct a new Task object
+ *
+ */
+ STask(STaskName name = DEFAULT_TASK_NAME);
+
+ /**
+ * @brief Construct a new Task object
+ *
+ * @param callback The callback function to be executed.
+ */
+ explicit STask(STaskName name, STaskRunnable runnable,
+ SDataObjectPtr data_object = nullptr);
+
+ /**
+ * @brief Construct a new Task object
+ *
+ * @param runnable
+ */
+ explicit STask(
+ STaskName name, STaskRunnable runnable, SDataObjectPtr data_object,
+ STaskCallback callback = [](int, const SDataObjectPtr &) {});
+
+ virtual ~STask() = default;
+};
+
+void PostTask(Thread::TaskRunner *, STask *);
+
+} // namespace GpgFrontend::Plugin::SDK
+
+#endif // GPGFRONTEND_SDK_TASK_H
diff --git a/src/plugin/sdk/UI.cpp b/src/plugin/sdk/UI.cpp
new file mode 100644
index 00000000..71a5aaee
--- /dev/null
+++ b/src/plugin/sdk/UI.cpp
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */ \ No newline at end of file
diff --git a/src/plugin/sdk/UI.h b/src/plugin/sdk/UI.h
new file mode 100644
index 00000000..71a5aaee
--- /dev/null
+++ b/src/plugin/sdk/UI.h
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */ \ No newline at end of file
diff --git a/src/ui/GpgFrontendUI.h b/src/ui/GpgFrontendUI.h
index 4389aa41..0c66ee83 100644
--- a/src/ui/GpgFrontendUI.h
+++ b/src/ui/GpgFrontendUI.h
@@ -32,11 +32,7 @@
/**
* Basic dependency
*/
-#include <QtCore>
-#include <QtNetwork>
-#include <QtPrintSupport>
#include <QtWidgets>
-#include <optional>
/**
* Project internal dependencies
diff --git a/src/ui/GpgFrontendUIInit.cpp b/src/ui/GpgFrontendUIInit.cpp
index bfe4d828..947c7f82 100644
--- a/src/ui/GpgFrontendUIInit.cpp
+++ b/src/ui/GpgFrontendUIInit.cpp
@@ -33,6 +33,7 @@
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
+#include <QtNetwork>
#include <string>
#include "core/GpgConstants.h"
diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp
index 7e236c02..93dac390 100644
--- a/src/ui/UserInterfaceUtils.cpp
+++ b/src/ui/UserInterfaceUtils.cpp
@@ -28,6 +28,7 @@
#include "UserInterfaceUtils.h"
+#include <QtNetwork>
#include <string>
#include <utility>
#include <vector>
diff --git a/src/ui/dialog/Wizard.cpp b/src/ui/dialog/Wizard.cpp
index 77f07559..3f2b27e9 100644
--- a/src/ui/dialog/Wizard.cpp
+++ b/src/ui/dialog/Wizard.cpp
@@ -106,7 +106,7 @@ IntroPage::IntroPage(QWidget* parent) : QWizardPage(parent) {
auto* layout = new QVBoxLayout;
layout->addWidget(topLabel);
layout->addStretch();
-#ifdef MULTI_LANG_SUPPORT
+#ifdef SUPPORT_MULTI_LANG
layout->addWidget(langLabel);
#endif
diff --git a/src/ui/dialog/import_export/KeyServerImportDialog.h b/src/ui/dialog/import_export/KeyServerImportDialog.h
index fd912bdd..4435ada5 100644
--- a/src/ui/dialog/import_export/KeyServerImportDialog.h
+++ b/src/ui/dialog/import_export/KeyServerImportDialog.h
@@ -29,6 +29,7 @@
#ifndef __KEY_SERVER_IMPORT_DIALOG_H__
#define __KEY_SERVER_IMPORT_DIALOG_H__
+#include <QtNetwork>
#include <string>
#include "KeyImportDetailDialog.h"
diff --git a/src/ui/dialog/import_export/KeyUploadDialog.cpp b/src/ui/dialog/import_export/KeyUploadDialog.cpp
index 5e05da2d..3b067c90 100644
--- a/src/ui/dialog/import_export/KeyUploadDialog.cpp
+++ b/src/ui/dialog/import_export/KeyUploadDialog.cpp
@@ -28,6 +28,7 @@
#include "KeyUploadDialog.h"
+#include <QtNetwork>
#include <algorithm>
#include "core/function/GlobalSettingStation.h"
diff --git a/src/ui/dialog/settings/SettingsGeneral.cpp b/src/ui/dialog/settings/SettingsGeneral.cpp
index be5190dd..6ded4505 100644
--- a/src/ui/dialog/settings/SettingsGeneral.cpp
+++ b/src/ui/dialog/settings/SettingsGeneral.cpp
@@ -30,7 +30,7 @@
#include "core/GpgContext.h"
-#ifdef MULTI_LANG_SUPPORT
+#ifdef SUPPORT_MULTI_LANG
#include "SettingsDialog.h"
#endif
@@ -73,7 +73,7 @@ GeneralTab::GeneralTab(QWidget* parent)
GlobalSettingStation::GetInstance().GetDataObjectsFilesSize())
.str()));
-#ifdef MULTI_LANG_SUPPORT
+#ifdef SUPPORT_MULTI_LANG
lang_ = SettingsDialog::ListLanguages();
for (const auto& l : lang_) {
ui_->langSelectBox->addItem(l);
@@ -154,7 +154,7 @@ void GeneralTab::SetSettings() {
SPDLOG_ERROR("setting operation error: longer_expiration_date");
}
-#ifdef MULTI_LANG_SUPPORT
+#ifdef SUPPORT_MULTI_LANG
try {
std::string lang_key = settings.lookup("general.lang");
QString lang_value = lang_.value(lang_key.c_str());
@@ -225,7 +225,7 @@ void GeneralTab::ApplySettings() {
ui_->restoreTextEditorPageCheckBox->isChecked();
}
-#ifdef MULTI_LANG_SUPPORT
+#ifdef SUPPORT_MULTI_LANG
if (!general.exists("lang"))
general.add("lang", libconfig::Setting::TypeBoolean) =
lang_.key(ui_->langSelectBox->currentText()).toStdString();
@@ -244,7 +244,7 @@ void GeneralTab::ApplySettings() {
}
}
-#ifdef MULTI_LANG_SUPPORT
+#ifdef SUPPORT_MULTI_LANG
void GeneralTab::slot_language_changed() { emit SignalRestartNeeded(true); }
#endif
diff --git a/src/ui/dialog/settings/SettingsGeneral.h b/src/ui/dialog/settings/SettingsGeneral.h
index be145b1f..f99cc7ea 100644
--- a/src/ui/dialog/settings/SettingsGeneral.h
+++ b/src/ui/dialog/settings/SettingsGeneral.h
@@ -82,7 +82,7 @@ class GeneralTab : public QWidget {
private:
std::shared_ptr<Ui_GeneralSettings> ui_; ///<
-#ifdef MULTI_LANG_SUPPORT
+#ifdef SUPPORT_MULTI_LANG
QHash<QString, QString> lang_; ///<
#endif
@@ -92,7 +92,7 @@ class GeneralTab : public QWidget {
private slots:
-#ifdef MULTI_LANG_SUPPORT
+#ifdef SUPPORT_MULTI_LANG
/**
* @brief
*
diff --git a/src/ui/dialog/settings/SettingsNetwork.h b/src/ui/dialog/settings/SettingsNetwork.h
index d4c0d00d..7e0aa857 100644
--- a/src/ui/dialog/settings/SettingsNetwork.h
+++ b/src/ui/dialog/settings/SettingsNetwork.h
@@ -29,6 +29,8 @@
#ifndef GPGFRONTEND_SETTINGSNETWORK_H
#define GPGFRONTEND_SETTINGSNETWORK_H
+#include <QtNetwork>
+
#include "ui/GpgFrontendUI.h"
class Ui_NetworkSettings;
diff --git a/src/ui/thread/KeyServerImportTask.h b/src/ui/thread/KeyServerImportTask.h
index 7d3b66c6..336f0503 100644
--- a/src/ui/thread/KeyServerImportTask.h
+++ b/src/ui/thread/KeyServerImportTask.h
@@ -27,6 +27,8 @@
#ifndef GPGFRONTEND_KEYSERVERIMPORTTASK_H
#define GPGFRONTEND_KEYSERVERIMPORTTASK_H
+#include <QtNetwork>
+
#include "GpgFrontendUI.h"
namespace GpgFrontend::UI {
diff --git a/src/ui/thread/KeyServerSearchTask.h b/src/ui/thread/KeyServerSearchTask.h
index 3333e949..f01d0c2a 100644
--- a/src/ui/thread/KeyServerSearchTask.h
+++ b/src/ui/thread/KeyServerSearchTask.h
@@ -27,6 +27,8 @@
#ifndef GPGFRONTEND_KEYSERVERSEARCHTASK_H
#define GPGFRONTEND_KEYSERVERSEARCHTASK_H
+#include <QtNetwork>
+
#include "GpgFrontendUI.h"
namespace GpgFrontend::UI {
diff --git a/src/ui/thread/ListedKeyServerTestTask.cpp b/src/ui/thread/ListedKeyServerTestTask.cpp
index 259953aa..205c4d80 100644
--- a/src/ui/thread/ListedKeyServerTestTask.cpp
+++ b/src/ui/thread/ListedKeyServerTestTask.cpp
@@ -26,6 +26,7 @@
#include "ListedKeyServerTestTask.h"
+#include <QtNetwork>
#include <vector>
GpgFrontend::UI::ListedKeyServerTestTask::ListedKeyServerTestTask(
diff --git a/src/ui/thread/ListedKeyServerTestTask.h b/src/ui/thread/ListedKeyServerTestTask.h
index aa1bac5e..abfd925d 100644
--- a/src/ui/thread/ListedKeyServerTestTask.h
+++ b/src/ui/thread/ListedKeyServerTestTask.h
@@ -28,6 +28,10 @@
#define GPGFRONTEND_LISTEDKEYSERVERTESTTHREAD_H
#include "GpgFrontendUI.h"
+
+class QNetworkAccessManager;
+class QNetworkReply;
+
namespace GpgFrontend::UI {
/**
diff --git a/src/ui/thread/ProxyConnectionTestTask.cpp b/src/ui/thread/ProxyConnectionTestTask.cpp
index d32bf2be..d48d0c36 100644
--- a/src/ui/thread/ProxyConnectionTestTask.cpp
+++ b/src/ui/thread/ProxyConnectionTestTask.cpp
@@ -26,6 +26,8 @@
#include "ProxyConnectionTestTask.h"
+#include <QtNetwork>
+
GpgFrontend::UI::ProxyConnectionTestTask::ProxyConnectionTestTask(QString url,
int timeout)
: Task("proxy_connection_test_task"),
diff --git a/src/ui/thread/ProxyConnectionTestTask.h b/src/ui/thread/ProxyConnectionTestTask.h
index 38e78ae4..a2aa25fd 100644
--- a/src/ui/thread/ProxyConnectionTestTask.h
+++ b/src/ui/thread/ProxyConnectionTestTask.h
@@ -27,12 +27,16 @@
#ifndef GPGFRONTEND_PROXYCONNECTIONTESTTHREAD_H
#define GPGFRONTEND_PROXYCONNECTIONTESTTHREAD_H
+#include <qnetworkreply.h>
class ProxyConnectionTestThread {};
#include <utility>
#include "GpgFrontendUI.h"
+class QNetworkAccessManager;
+class QNetworkReply;
+
namespace GpgFrontend::UI {
/**
diff --git a/src/ui/thread/VersionCheckTask.cpp b/src/ui/thread/VersionCheckTask.cpp
index f9929837..d5ab1f7d 100644
--- a/src/ui/thread/VersionCheckTask.cpp
+++ b/src/ui/thread/VersionCheckTask.cpp
@@ -29,6 +29,7 @@
#include "VersionCheckTask.h"
#include <QMetaType>
+#include <QtNetwork>
#include <memory>
#include "GpgFrontendBuildInfo.h"
diff --git a/src/ui/thread/VersionCheckTask.h b/src/ui/thread/VersionCheckTask.h
index 0dbce17f..985dde9d 100644
--- a/src/ui/thread/VersionCheckTask.h
+++ b/src/ui/thread/VersionCheckTask.h
@@ -29,6 +29,8 @@
#ifndef GPGFRONTEND_VERSIONCHECKTHREAD_H
#define GPGFRONTEND_VERSIONCHECKTHREAD_H
+#include <qnetworkreply.h>
+
#include <memory>
#include <string>
@@ -36,6 +38,9 @@
#include "ui/GpgFrontendUI.h"
#include "ui/struct/SoftwareVersion.h"
+class QNetworkAccessManager;
+class QNetworkReply;
+
namespace GpgFrontend::UI {
/**
diff --git a/src/ui/widgets/TextEdit.cpp b/src/ui/widgets/TextEdit.cpp
index 7af4d5f8..e1520840 100644
--- a/src/ui/widgets/TextEdit.cpp
+++ b/src/ui/widgets/TextEdit.cpp
@@ -28,6 +28,7 @@
#include "ui/widgets/TextEdit.h"
+#include <QtPrintSupport>
#include <boost/format.hpp>
#include <string>
#include <tuple>