aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/thread/Task.cpp91
-rw-r--r--src/core/thread/Task.h141
-rw-r--r--src/core/thread/TaskRunner.cpp28
-rw-r--r--src/core/thread/ThreadingModel.h34
-rw-r--r--src/ui/GpgFrontendUI.h2
-rw-r--r--src/ui/UserInterfaceUtils.cpp28
-rw-r--r--src/ui/UserInterfaceUtils.h7
-rw-r--r--src/ui/main_window/MainWindowFileSlotFunction.cpp183
-rw-r--r--src/ui/main_window/MainWindowSlotFunction.cpp334
9 files changed, 617 insertions, 231 deletions
diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp
index 9626ba69..7b8423b2 100644
--- a/src/core/thread/Task.cpp
+++ b/src/core/thread/Task.cpp
@@ -26,24 +26,48 @@
#include "core/thread/Task.h"
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/uuid_generators.hpp>
+#include <boost/uuid/uuid_io.hpp>
#include <functional>
+#include <string>
+#include <utility>
#include "core/thread/TaskRunner.h"
+#include "easylogging++.h"
-GpgFrontend::Thread::Task::Task() { init(); }
+GpgFrontend::Thread::Task::Task() : uuid_(generate_uuid()) {
+ LOG(INFO) << "Task" << uuid_ << "created";
+ init();
+}
-GpgFrontend::Thread::Task::Task(TaskCallback callback)
- : callback_(std::move(callback)) {
+GpgFrontend::Thread::Task::Task(TaskCallback callback,
+ DataObjectPtr data_object)
+ : uuid_(generate_uuid()),
+ callback_(std::move(callback)),
+ callback_thread_(QThread::currentThread()),
+ data_object_(data_object) {
+ LOG(INFO) << "Task" << uuid_ << "created with callback"
+ << "callback_thread_: " << callback_thread_;
init();
}
-GpgFrontend::Thread::Task::Task(TaskRunnable runnable, TaskCallback callback)
- : runnable_(runnable), callback_(std::move(callback)) {
+GpgFrontend::Thread::Task::Task(TaskRunnable runnable, TaskCallback callback,
+ DataObjectPtr data_object)
+ : uuid_(generate_uuid()),
+ runnable_(std::move(runnable)),
+ callback_(std::move(callback)),
+ callback_thread_(QThread::currentThread()),
+ data_object_(data_object) {
init();
+ LOG(INFO) << "Task" << uuid_ << "created with runnable and callback"
+ << "callback_thread_: " << callback_thread_;
}
GpgFrontend::Thread::Task::~Task() = default;
+std::string GpgFrontend::Thread::Task::GetUUID() const { return uuid_; }
+
void GpgFrontend::Thread::Task::SetFinishAfterRun(bool finish_after_run) {
this->finish_after_run_ = finish_after_run;
}
@@ -51,24 +75,71 @@ void GpgFrontend::Thread::Task::SetFinishAfterRun(bool finish_after_run) {
void GpgFrontend::Thread::Task::SetRTN(int rtn) { this->rtn_ = rtn; }
void GpgFrontend::Thread::Task::init() {
- LOG(INFO) << "called";
connect(this, &Task::SignalTaskFinished, this, &Task::before_finish_task);
connect(this, &Task::SignalTaskFinished, this, &Task::deleteLater);
}
void GpgFrontend::Thread::Task::before_finish_task() {
- LOG(INFO) << "called";
- if (callback_) callback_(rtn_);
+ LOG(INFO) << "Task" << uuid_ << "finished";
+ if (callback_) {
+ bool if_invoke = QMetaObject::invokeMethod(
+ callback_thread_,
+ [callback = callback_, rtn = rtn_, data_object = data_object_]() {
+ callback(rtn, data_object);
+ });
+ if (!if_invoke) {
+ LOG(ERROR) << "failed to invoke callback";
+ }
+ }
}
void GpgFrontend::Thread::Task::run() {
- LOG(INFO) << "called";
+ LOG(INFO) << "Task" << uuid_ << "started";
Run();
if (finish_after_run_) emit SignalTaskFinished();
}
void GpgFrontend::Thread::Task::Run() {
if (runnable_) {
- rtn_ = runnable_();
+ bool if_invoke = QMetaObject::invokeMethod(
+ this, [=]() { return runnable_(data_object_); }, &rtn_);
+ if (!if_invoke) {
+ LOG(ERROR) << "invokeMethod failed";
+ }
+ }
+}
+
+GpgFrontend::Thread::Task::DataObject::Destructor *
+GpgFrontend::Thread::Task::DataObject::get_heap_ptr(size_t bytes_size) {
+ Destructor *dstr_ptr = new Destructor();
+ dstr_ptr->p_obj = malloc(bytes_size);
+ return dstr_ptr;
+}
+
+GpgFrontend::Thread::Task::DataObject::~DataObject() {
+ if (!data_objects_.empty())
+ LOG(WARNING) << "data_objects_ is not empty"
+ << "address:" << this;
+ while (!data_objects_.empty()) {
+ free_heap_ptr(data_objects_.top());
+ data_objects_.pop();
+ }
+}
+
+size_t GpgFrontend::Thread::Task::DataObject::GetObjectSize() {
+ return data_objects_.size();
+}
+
+void GpgFrontend::Thread::Task::DataObject::free_heap_ptr(Destructor *ptr) {
+ LOG(INFO) << "p_obj: " << ptr->p_obj << "destructor: " << ptr->destroy
+ << "DataObject:" << this;
+ if (ptr->destroy != nullptr) {
+ ptr->destroy(ptr->p_obj);
}
+ free((void *)ptr->p_obj);
+ delete ptr;
+}
+
+std::string GpgFrontend::Thread::Task::generate_uuid() {
+ return boost::uuids::to_string(boost::uuids::random_generator()());
}
diff --git a/src/core/thread/Task.h b/src/core/thread/Task.h
index 4b536176..e2105415 100644
--- a/src/core/thread/Task.h
+++ b/src/core/thread/Task.h
@@ -28,6 +28,11 @@
#define GPGFRONTEND_TASK_H
#include <functional>
+#include <memory>
+#include <stack>
+#include <string>
+#include <type_traits>
+#include <utility>
#include "core/GpgFrontendCore.h"
@@ -38,11 +43,97 @@ class TaskRunner;
class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
Q_OBJECT
public:
- using TaskRunnable = std::function<int()>; ///<
- using TaskCallback = std::function<void(int)>; ///<
+ class DataObject;
+ using DataObjectPtr = std::shared_ptr<DataObject>; ///<
+ using TaskRunnable = std::function<int(DataObjectPtr)>; ///<
+ using TaskCallback = std::function<void(int, DataObjectPtr)>; ///<
+
friend class TaskRunner;
/**
+ * @brief DataObject to be passed to the callback function.
+ *
+ */
+ class DataObject {
+ public:
+ struct Destructor {
+ const void *p_obj;
+ void (*destroy)(const void *);
+ };
+
+ /**
+ * @brief Get the Objects Size
+ *
+ * @return size_t
+ */
+ size_t GetObjectSize();
+
+ /**
+ * @brief
+ *
+ * @tparam T
+ * @param ptr
+ */
+ template <typename T>
+ void AppendObject(T &&obj) {
+ LOG(INFO) << "called:" << this;
+ auto *obj_dstr = this->get_heap_ptr(sizeof(T));
+ auto *ptr_heap = new ((void *)obj_dstr->p_obj) T(std::move(obj));
+ if (std::is_class_v<T>) {
+ auto destructor = [](const void *x) {
+ static_cast<const T *>(x)->~T();
+ };
+ obj_dstr->destroy = destructor;
+ } else {
+ obj_dstr->destroy = nullptr;
+ }
+ data_objects_.push(std::move(obj_dstr));
+ }
+
+ /**
+ * @brief
+ *
+ * @tparam T
+ * @return std::shared_ptr<T>
+ */
+ template <typename T>
+ T PopObject() {
+ LOG(INFO) << "called:" << this;
+ if (data_objects_.empty()) throw std::runtime_error("No object to pop");
+ auto *obj_dstr = data_objects_.top();
+ auto *heap_ptr = (T *)obj_dstr->p_obj;
+ auto obj = std::move(*(T *)(heap_ptr));
+ this->free_heap_ptr(obj_dstr);
+ data_objects_.pop();
+ return obj;
+ }
+
+ /**
+ * @brief Destroy the Data Object object
+ *
+ */
+ ~DataObject();
+
+ private:
+ std::stack<Destructor *> data_objects_; ///<
+
+ /**
+ * @brief Get the heap ptr object
+ *
+ * @param bytes_size
+ * @return void*
+ */
+ Destructor *get_heap_ptr(size_t bytes_size);
+
+ /**
+ * @brief
+ *
+ * @param heap_ptr
+ */
+ void free_heap_ptr(Destructor *);
+ };
+
+ /**
* @brief Construct a new Task object
*
*/
@@ -52,9 +143,8 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
* @brief Construct a new Task object
*
* @param callback The callback function to be executed.
- * callback must not be nullptr, and not tp opreate UI object.
*/
- Task(TaskCallback callback);
+ Task(TaskCallback callback, DataObjectPtr data_object = nullptr);
/**
* @brief Construct a new Task object
@@ -62,7 +152,9 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
* @param runnable
*/
Task(
- TaskRunnable runnable, TaskCallback callback = [](int) {});
+ TaskRunnable runnable,
+ TaskCallback callback = [](int, std::shared_ptr<DataObject>) {},
+ DataObjectPtr data = nullptr);
/**
* @brief Destroy the Task object
@@ -76,19 +168,43 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
*/
virtual void Run();
+ /**
+ * @brief
+ *
+ * @return std::string
+ */
+ std::string GetUUID() const;
+
signals:
+ /**
+ * @brief
+ *
+ */
void SignalTaskFinished();
protected:
+ /**
+ * @brief Set the Finish After Run object
+ *
+ * @param finish_after_run
+ */
void SetFinishAfterRun(bool finish_after_run);
+ /**
+ * @brief
+ *
+ * @param rtn
+ */
void SetRTN(int rtn);
private:
- TaskCallback callback_; ///<
- TaskRunnable runnable_; ///<
- bool finish_after_run_ = true; ///<
- int rtn_ = 0; ///<
+ const std::string uuid_;
+ TaskCallback callback_; ///<
+ TaskRunnable runnable_; ///<
+ bool finish_after_run_ = true; ///<
+ int rtn_ = 0; ///<
+ QThread *callback_thread_ = nullptr; ///<
+ DataObjectPtr data_object_ = nullptr; ///<
/**
* @brief
@@ -107,6 +223,13 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
*
*/
virtual void run() override;
+
+ /**
+ * @brief
+ *
+ * @return std::string
+ */
+ static std::string generate_uuid();
};
} // namespace GpgFrontend::Thread
diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp
index 2223bdda..3b565abb 100644
--- a/src/core/thread/TaskRunner.cpp
+++ b/src/core/thread/TaskRunner.cpp
@@ -26,6 +26,8 @@
#include "core/thread/TaskRunner.h"
+#include <exception>
+
#include "core/thread/Task.h"
#include "easylogging++.h"
@@ -34,7 +36,9 @@ GpgFrontend::Thread::TaskRunner::TaskRunner() = default;
GpgFrontend::Thread::TaskRunner::~TaskRunner() = default;
void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) {
- LOG(INFO) << "called";
+ LOG(INFO) << "called"
+ << "Post Task" << task->GetUUID();
+
if (task == nullptr) return;
task->setParent(nullptr);
task->moveToThread(this);
@@ -46,13 +50,14 @@ void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) {
}
void GpgFrontend::Thread::TaskRunner::run() {
- LOG(INFO) << "called";
+ LOG(INFO) << "called"
+ << "thread id:" << QThread::currentThreadId();
while (true) {
if (tasks.empty()) {
- LOG(INFO) << "TaskRunner: No tasks to run";
+ LOG(INFO) << "TaskRunner: No tasks to run.";
exec();
} else {
- LOG(INFO) << "TaskRunner: Running task, queue size:" << tasks.size();
+ LOG(INFO) << "TaskRunner: Queue size:" << tasks.size();
Task* task = nullptr;
{
@@ -60,7 +65,20 @@ void GpgFrontend::Thread::TaskRunner::run() {
task = std::move(tasks.front());
tasks.pop();
}
- if (task != nullptr) task->run();
+
+ if (task != nullptr) {
+ // Run the task
+ LOG(INFO) << "TaskRunner: Running Task" << task->GetUUID();
+ try {
+ task->run();
+ } catch (const std::exception& e) {
+ LOG(ERROR) << "TaskRunner: Exception in Task" << task->GetUUID()
+ << "Exception: " << e.what();
+ } catch (...) {
+ LOG(ERROR) << "TaskRunner: Unknwon Exception in Task"
+ << task->GetUUID();
+ }
+ }
}
}
}
diff --git a/src/core/thread/ThreadingModel.h b/src/core/thread/ThreadingModel.h
new file mode 100644
index 00000000..ceb2b053
--- /dev/null
+++ b/src/core/thread/ThreadingModel.h
@@ -0,0 +1,34 @@
+/**
+ * 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_THREADINGMODEL_H
+#define GPGFRONTEND_THREADINGMODEL_H
+
+#include "core/thread/Task.h"
+#include "core/thread/TaskRunner.h"
+#include "core/thread/TaskRunnerGetter.h"
+
+#endif // GPGFRONTEND_THREADINGMODEL_H \ No newline at end of file
diff --git a/src/ui/GpgFrontendUI.h b/src/ui/GpgFrontendUI.h
index b355ec85..9fa9e3a7 100644
--- a/src/ui/GpgFrontendUI.h
+++ b/src/ui/GpgFrontendUI.h
@@ -44,7 +44,7 @@
#include "GpgFrontend.h"
#include "core/GpgFrontendCore.h"
#include "core/GpgModel.h"
-
+#include "core/Thread/ThreadingModel.h"
#include "ui/GpgFrontendUIExport.h"
/**
diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp
index 65c55c8f..adcbd6ff 100644
--- a/src/ui/UserInterfaceUtils.cpp
+++ b/src/ui/UserInterfaceUtils.cpp
@@ -114,21 +114,29 @@ void process_result_analyse(TextEdit *edit, InfoBoardWidget *info_board,
}
void process_operation(QWidget *parent, const std::string &waiting_title,
- const std::function<void()> &func) {
+ const Thread::Task::TaskRunnable func,
+ const Thread::Task::TaskCallback callback,
+ Thread::Task::DataObjectPtr data_object) {
auto *dialog =
new WaitingDialog(QString::fromStdString(waiting_title), parent);
- auto thread = QThread::create(func);
- QApplication::connect(thread, &QThread::finished, thread,
- &QThread::deleteLater);
- QApplication::connect(thread, &QThread::finished, dialog, &QDialog::close);
- QApplication::connect(thread, &QThread::finished, dialog,
- &QDialog::deleteLater);
+ auto *process_task =
+ new Thread::Task(std::move(func), std::move(callback), data_object);
+
+ QApplication::connect(process_task, &Thread::Task::SignalTaskFinished, dialog,
+ &QDialog::close);
QEventLoop looper;
- QApplication::connect(dialog, &QDialog::finished, &looper, &QEventLoop::quit);
+ QApplication::connect(process_task, &Thread::Task::SignalTaskFinished,
+ &looper, &QEventLoop::quit);
- thread->start();
+ // post process task to task runner
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG)
+ ->PostTask(process_task);
+
+ // block until task finished
+ // this is to keep reference vaild until task finished
looper.exec();
}
@@ -350,7 +358,7 @@ void CommonUtils::SlotImportKeyFromKeyServer(
void CommonUtils::slot_update_key_status() {
LOG(INFO) << "called";
- auto refresh_task = new Thread::Task([]() -> int {
+ auto refresh_task = new Thread::Task([](Thread::Task::DataObjectPtr) -> int {
// flush key cache for all GpgKeyGetter Intances.
for (const auto &channel_id : GpgKeyGetter::GetAllChannelId()) {
GpgKeyGetter::GetInstance(channel_id).FlushKeyCache();
diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h
index 85ef012b..bfd8a3ae 100644
--- a/src/ui/UserInterfaceUtils.h
+++ b/src/ui/UserInterfaceUtils.h
@@ -101,8 +101,11 @@ void process_result_analyse(TextEdit* edit, InfoBoardWidget* info_board,
* @param waiting_title
* @param func
*/
-void process_operation(QWidget* parent, const std::string& waiting_title,
- const std::function<void()>& func);
+void process_operation(
+ QWidget* parent, const std::string& waiting_title,
+ GpgFrontend::Thread::Task::TaskRunnable func,
+ GpgFrontend::Thread::Task::TaskCallback callback = nullptr,
+ Thread::Task::DataObjectPtr data_object = nullptr);
/**
* @brief
diff --git a/src/ui/main_window/MainWindowFileSlotFunction.cpp b/src/ui/main_window/MainWindowFileSlotFunction.cpp
index d1288a1b..4ab23a22 100644
--- a/src/ui/main_window/MainWindowFileSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowFileSlotFunction.cpp
@@ -31,6 +31,7 @@
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgFileOpera.h"
#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/thread/Task.h"
#include "ui/UserInterfaceUtils.h"
#include "ui/widgets/SignersPicker.h"
@@ -66,7 +67,6 @@ bool path_pre_check(QWidget* parent, const QString& path) {
*/
bool process_tarball_into_directory(QWidget* parent,
std::filesystem::path& path) {
-
LOG(INFO) << "Converting directory into tarball" << path;
auto selected_dir_path = std::filesystem::path(path);
@@ -85,14 +85,16 @@ bool process_tarball_into_directory(QWidget* parent,
<< target_path.u8string();
bool if_error = false;
- process_operation(parent, _("Extracting Tarball"), [&]() {
- try {
- GpgFrontend::ArchiveFileOperator::ExtractArchive(target_path,
- base_path);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- });
+ process_operation(parent, _("Extracting Tarball"),
+ [&](Thread::Task::DataObjectPtr) -> int {
+ try {
+ GpgFrontend::ArchiveFileOperator::ExtractArchive(
+ target_path, base_path);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ return 0;
+ });
if (if_error || !exists(target_path)) {
throw std::runtime_error("Decompress Failed");
@@ -112,7 +114,6 @@ bool process_tarball_into_directory(QWidget* parent,
* @param path the tarball to be converted
*/
bool process_directory_into_tarball(QWidget* parent, QString& path) {
-
#ifdef WINDOWS
std::filesystem::path selected_dir_path = path.toStdU16String();
#else
@@ -128,14 +129,16 @@ bool process_directory_into_tarball(QWidget* parent, QString& path) {
<< target_path << "selected_dir_path" << selected_dir_path;
bool if_error = false;
- process_operation(parent, _("Making Tarball"), [&]() {
- try {
- GpgFrontend::ArchiveFileOperator::CreateArchive(base_path, target_path,
- 0, {selected_dir_path});
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- });
+ process_operation(parent, _("Making Tarball"),
+ [&](Thread::Task::DataObjectPtr) -> int {
+ try {
+ GpgFrontend::ArchiveFileOperator::CreateArchive(
+ base_path, target_path, 0, {selected_dir_path});
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ return 0;
+ });
if (if_error || !exists(target_path)) {
throw std::runtime_error("Compress Failed");
@@ -223,14 +226,17 @@ void MainWindow::SlotFileEncrypt() {
if (ret == QMessageBox::Cancel) return;
- process_operation(this, _("Symmetrically Encrypting"), [&]() {
- try {
- error = GpgFrontend::GpgFileOpera::EncryptFileSymmetric(
- path.toStdString(), out_path.toStdString(), result, _channel);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- });
+ process_operation(
+ this, _("Symmetrically Encrypting"),
+ [&](Thread::Task::DataObjectPtr) -> int {
+ try {
+ error = GpgFrontend::GpgFileOpera::EncryptFileSymmetric(
+ path.toStdString(), out_path.toStdString(), result, _channel);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ return 0;
+ });
} else {
auto p_keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
@@ -248,15 +254,17 @@ void MainWindow::SlotFileEncrypt() {
}
}
- process_operation(this, _("Encrypting"), [&]() {
- try {
- error =
- GpgFileOpera::EncryptFile(std::move(p_keys), path.toStdString(),
- out_path.toStdString(), result, _channel);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- });
+ process_operation(this, _("Encrypting"),
+ [&](Thread::Task::DataObjectPtr) -> int {
+ try {
+ error = GpgFileOpera::EncryptFile(
+ std::move(p_keys), path.toStdString(),
+ out_path.toStdString(), result, _channel);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ return 0;
+ });
}
// remove xxx.tar and only left xxx.tar.gpg
@@ -310,14 +318,16 @@ void MainWindow::SlotFileDecrypt() {
GpgDecrResult result = nullptr;
gpgme_error_t error;
bool if_error = false;
- process_operation(this, _("Decrypting"), [&]() {
- try {
- error = GpgFileOpera::DecryptFile(path.toStdString(), out_path.u8string(),
- result);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- });
+ process_operation(this, _("Decrypting"),
+ [&](Thread::Task::DataObjectPtr) -> int {
+ try {
+ error = GpgFileOpera::DecryptFile(
+ path.toStdString(), out_path.u8string(), result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ return 0;
+ });
if (!if_error) {
auto resultAnalyse = GpgDecryptResultAnalyse(error, std::move(result));
@@ -349,7 +359,6 @@ void MainWindow::SlotFileDecrypt() {
}
}
}
-
}
void MainWindow::SlotFileSign() {
@@ -419,14 +428,17 @@ void MainWindow::SlotFileSign() {
gpgme_error_t error;
bool if_error = false;
- process_operation(this, _("Signing"), [&]() {
- try {
- error = GpgFileOpera::SignFile(std::move(keys), in_path.u8string(),
- sig_file_path.u8string(), result, _channel);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- });
+ process_operation(
+ this, _("Signing"), [&](Thread::Task::DataObjectPtr) -> int {
+ try {
+ error = GpgFileOpera::SignFile(std::move(keys), in_path.u8string(),
+ sig_file_path.u8string(), result,
+ _channel);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ return 0;
+ });
if (!if_error) {
auto resultAnalyse = GpgSignResultAnalyse(error, std::move(result));
@@ -480,9 +492,9 @@ void MainWindow::SlotFileVerify() {
if (in_path.extension() != ".gpg") {
bool ok;
- QString text = QInputDialog::getText(this, _("Origin file to verify"),
- _("Filepath"), QLineEdit::Normal,
- data_file_path.u8string().c_str(), &ok);
+ QString text = QInputDialog::getText(
+ this, _("Origin file to verify"), _("Filepath"), QLineEdit::Normal,
+ data_file_path.u8string().c_str(), &ok);
if (ok && !text.isEmpty()) {
data_file_path = text.toStdString();
} else {
@@ -505,14 +517,17 @@ void MainWindow::SlotFileVerify() {
GpgVerifyResult result = nullptr;
gpgme_error_t error;
bool if_error = false;
- process_operation(this, _("Verifying"), [&]() {
- try {
- error = GpgFileOpera::VerifyFile(
- data_file_path.u8string(), sign_file_path.u8string(), result, _channel);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- });
+ process_operation(
+ this, _("Verifying"), [&](Thread::Task::DataObjectPtr) -> int {
+ try {
+ error = GpgFileOpera::VerifyFile(data_file_path.u8string(),
+ sign_file_path.u8string(), result,
+ _channel);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ return 0;
+ });
if (!if_error) {
auto result_analyse = GpgVerifyResultAnalyse(error, result);
@@ -622,15 +637,18 @@ void MainWindow::SlotFileEncryptSign() {
gpgme_error_t error;
bool if_error = false;
- process_operation(this, _("Encrypting and Signing"), [&]() {
- try {
- error = GpgFileOpera::EncryptSignFile(
- std::move(p_keys), std::move(p_signer_keys), path.toStdString(),
- out_path.toStdString(), encr_result, sign_result, _channel);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- });
+ process_operation(this, _("Encrypting and Signing"),
+ [&](Thread::Task::DataObjectPtr) -> int {
+ try {
+ error = GpgFileOpera::EncryptSignFile(
+ std::move(p_keys), std::move(p_signer_keys),
+ path.toStdString(), out_path.toStdString(),
+ encr_result, sign_result, _channel);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ return 0;
+ });
if (!if_error) {
auto encrypt_result =
@@ -656,7 +674,6 @@ void MainWindow::SlotFileEncryptSign() {
std::filesystem::remove(target_path);
}
}
-
}
void MainWindow::SlotFileDecryptVerify() {
@@ -694,14 +711,17 @@ void MainWindow::SlotFileDecryptVerify() {
GpgVerifyResult v_result = nullptr;
gpgme_error_t error;
bool if_error = false;
- process_operation(this, _("Decrypting and Verifying"), [&]() {
- try {
- error = GpgFileOpera::DecryptVerifyFile(
- path.toStdString(), out_path.u8string(), d_result, v_result);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- });
+ process_operation(this, _("Decrypting and Verifying"),
+ [&](Thread::Task::DataObjectPtr) -> int {
+ try {
+ error = GpgFileOpera::DecryptVerifyFile(
+ path.toStdString(), out_path.u8string(), d_result,
+ v_result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ return 0;
+ });
if (!if_error) {
auto decrypt_res = GpgDecryptResultAnalyse(error, std::move(d_result));
@@ -741,7 +761,6 @@ void MainWindow::SlotFileDecryptVerify() {
}
}
}
-
}
} // namespace GpgFrontend::UI
diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp
index a1db4d61..910a7bf2 100644
--- a/src/ui/main_window/MainWindowSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowSlotFunction.cpp
@@ -26,11 +26,20 @@
*
*/
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <utility>
+
#include "MainWindow.h"
+#include "core/GpgConstants.h"
+#include "core/GpgModel.h"
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgBasicOperator.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/function/gpg/GpgKeyImportExporter.h"
+#include "core/model/GpgKey.h"
+#include "core/thread/TaskRunner.h"
#include "ui/UserInterfaceUtils.h"
#include "ui/help/AboutDialog.h"
#include "ui/widgets/SignersPicker.h"
@@ -47,10 +56,41 @@ void MainWindow::slot_encrypt() {
auto key_ids = m_key_list_->GetChecked();
- GpgEncrResult result = nullptr;
- GpgError error;
- bool if_error = false;
- auto tmp = std::make_unique<ByteArray>();
+ // data to transfer into task
+ auto data_object = std::make_shared<Thread::Task::DataObject>();
+
+ // set input buffer
+ auto buffer =
+ edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString();
+ data_object->AppendObject(std::move(buffer));
+
+ // the callback function
+ auto result_callback = [this](int rtn,
+ Thread::Task::DataObjectPtr data_object) {
+ if (!rtn) {
+ if (data_object->GetObjectSize() != 3)
+ throw std::runtime_error("Invalid data object size");
+ auto error = data_object->PopObject<GpgError>();
+ auto result = data_object->PopObject<GpgEncrResult>();
+ auto tmp = data_object->PopObject<std::unique_ptr<ByteArray>>();
+
+ auto resultAnalyse = GpgEncryptResultAnalyse(error, std::move(result));
+ resultAnalyse.Analyse();
+ process_result_analyse(edit_, info_board_, resultAnalyse);
+
+ if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
+ edit_->SlotFillTextEditWithText(QString::fromStdString(*tmp));
+ info_board_->ResetOptionActionsMenu();
+ } else {
+ QMessageBox::critical(this, _("Error"),
+ _("An error occurred during operation."));
+ return;
+ }
+ };
+
+ Thread::Task::TaskRunnable encrypt_runner = nullptr;
+
+ std::string encrypt_type = "";
if (key_ids->empty()) {
// Symmetric Encrypt
@@ -62,16 +102,26 @@ void MainWindow::slot_encrypt() {
if (ret == QMessageBox::Cancel) return;
- process_operation(this, _("Symmetrically Encrypting"), [&]() {
+ encrypt_type = _("Symmetrically Encrypting");
+ encrypt_runner = [](Thread::Task::DataObjectPtr data_object) -> int {
+ if (data_object == nullptr || data_object->GetObjectSize() != 1)
+ throw std::runtime_error("Invalid data object size");
+ auto buffer = data_object->PopObject<std::string>();
try {
- auto buffer =
- edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString();
- error = GpgFrontend::GpgBasicOperator::GetInstance().EncryptSymmetric(
- buffer, tmp, result);
+ GpgEncrResult result = nullptr;
+ auto tmp = std::make_unique<ByteArray>();
+ GpgError error =
+ GpgFrontend::GpgBasicOperator::GetInstance().EncryptSymmetric(
+ buffer, tmp, result);
+ data_object->AppendObject(std::move(tmp));
+ data_object->AppendObject(std::move(result));
+ data_object->AppendObject(std::move(error));
} catch (const std::runtime_error& e) {
- if_error = true;
+ return -1;
}
- });
+ return 0;
+ };
+
} else {
auto& key_getter = GpgFrontend::GpgKeyGetter::GetInstance();
auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
@@ -88,32 +138,36 @@ void MainWindow::slot_encrypt() {
}
}
- process_operation(this, _("Encrypting"), [&]() {
+ // push the keys into data object
+ data_object->AppendObject(std::move(keys));
+
+ // Asymmetric Encrypt
+ encrypt_type = _("Encrypting");
+ encrypt_runner = [](Thread::Task::DataObjectPtr data_object) -> int {
+ // check the size of the data object
+ if (data_object == nullptr || data_object->GetObjectSize() != 2)
+ throw std::runtime_error("Invalid data object size");
+
+ auto keys = data_object->PopObject<KeyListPtr>();
+ auto buffer = data_object->PopObject<std::string>();
try {
- auto buffer =
- edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString();
- error = GpgFrontend::GpgBasicOperator::GetInstance().Encrypt(
+ GpgEncrResult result = nullptr;
+ auto tmp = std::make_unique<ByteArray>();
+ GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().Encrypt(
std::move(keys), buffer, tmp, result);
+
+ data_object->AppendObject(std::move(tmp));
+ data_object->AppendObject(std::move(result));
+ data_object->AppendObject(std::move(error));
} catch (const std::runtime_error& e) {
- if_error = true;
+ return -1;
}
- });
- }
-
- if (!if_error) {
- LOG(INFO) << "result" << result.get();
- auto resultAnalyse = GpgEncryptResultAnalyse(error, std::move(result));
- resultAnalyse.Analyse();
- process_result_analyse(edit_, info_board_, resultAnalyse);
-
- if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
- edit_->SlotFillTextEditWithText(QString::fromStdString(*tmp));
- info_board_->ResetOptionActionsMenu();
- } else {
- QMessageBox::critical(this, _("Error"),
- _("An error occurred during operation."));
- return;
+ return 0;
+ };
}
+ // Do the task
+ process_operation(this, _("Encrypting"), std::move(encrypt_runner),
+ std::move(result_callback), data_object);
}
void MainWindow::slot_sign() {
@@ -145,38 +199,61 @@ void MainWindow::slot_sign() {
}
}
- auto tmp = std::make_unique<ByteArray>();
+ // data to transfer into task
+ auto data_object = std::make_shared<Thread::Task::DataObject>();
- GpgSignResult result = nullptr;
- gpgme_error_t error;
- bool if_error = false;
+ // set input buffer
+ auto buffer =
+ edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString();
+ data_object->AppendObject(std::move(buffer));
+
+ // push the keys into data object
+ data_object->AppendObject(std::move(keys));
+
+ auto sign_ruunner = [](Thread::Task::DataObjectPtr data_object) -> int {
+ // check the size of the data object
+ if (data_object == nullptr || data_object->GetObjectSize() != 2)
+ throw std::runtime_error("Invalid data object size");
- process_operation(this, _("Signing"), [&]() {
+ auto keys = data_object->PopObject<KeyListPtr>();
+ auto buffer = data_object->PopObject<std::string>();
try {
- auto buffer = edit_->CurTextPage()
- ->GetTextPage()
- ->toPlainText()
- .toUtf8()
- .toStdString();
- error = GpgFrontend::GpgBasicOperator::GetInstance().Sign(
+ GpgSignResult result = nullptr;
+ auto tmp = std::make_unique<ByteArray>();
+ GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().Sign(
std::move(keys), buffer, tmp, GPGME_SIG_MODE_CLEAR, result);
+ data_object->AppendObject(std::move(tmp));
+ data_object->AppendObject(std::move(result));
+ data_object->AppendObject(std::move(error));
} catch (const std::runtime_error& e) {
- if_error = true;
+ return -1;
}
- });
-
- if (!if_error) {
- auto resultAnalyse = GpgSignResultAnalyse(error, std::move(result));
- resultAnalyse.Analyse();
- process_result_analyse(edit_, info_board_, resultAnalyse);
+ return 0;
+ };
+
+ auto result_callback = [this](int rtn,
+ Thread::Task::DataObjectPtr data_object) {
+ if (!rtn) {
+ if (data_object == nullptr || data_object->GetObjectSize() != 3)
+ throw std::runtime_error("Invalid data object size");
+ auto error = data_object->PopObject<GpgError>();
+ auto result = data_object->PopObject<GpgSignResult>();
+ auto tmp = data_object->PopObject<std::unique_ptr<ByteArray>>();
+ auto resultAnalyse = GpgSignResultAnalyse(error, std::move(result));
+ resultAnalyse.Analyse();
+ process_result_analyse(edit_, info_board_, resultAnalyse);
+
+ if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
+ edit_->SlotFillTextEditWithText(QString::fromStdString(*tmp));
+ } else {
+ QMessageBox::critical(this, _("Error"),
+ _("An error occurred during operation."));
+ return;
+ }
+ };
- if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
- edit_->SlotFillTextEditWithText(QString::fromStdString(*tmp));
- } else {
- QMessageBox::critical(this, _("Error"),
- _("An error occurred during operation."));
- return;
- }
+ process_operation(this, _("Signing"), std::move(sign_ruunner),
+ std::move(result_callback), data_object);
}
void MainWindow::slot_decrypt() {
@@ -185,7 +262,6 @@ void MainWindow::slot_decrypt() {
return;
}
- auto decrypted = std::make_unique<ByteArray>();
QByteArray text = edit_->CurTextPage()->GetTextPage()->toPlainText().toUtf8();
if (text.trimmed().startsWith(GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) {
@@ -195,31 +271,57 @@ void MainWindow::slot_decrypt() {
return;
}
- GpgDecrResult result = nullptr;
- gpgme_error_t error;
- bool if_error = false;
- process_operation(this, _("Decrypting"), [&]() {
+ // data to transfer into task
+ auto data_object = std::make_shared<Thread::Task::DataObject>();
+
+ // set input buffer
+ auto buffer =
+ edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString();
+ data_object->AppendObject(std::move(buffer));
+
+ auto decrypt_runner = [](Thread::Task::DataObjectPtr data_object) -> int {
+ // check the size of the data object
+ if (data_object == nullptr || data_object->GetObjectSize() != 1)
+ throw std::runtime_error("Invalid data object size");
+
+ auto buffer = data_object->PopObject<std::string>();
try {
- auto buffer = text.toStdString();
- error = GpgFrontend::GpgBasicOperator::GetInstance().Decrypt(
+ GpgDecrResult result = nullptr;
+ auto decrypted = std::make_unique<ByteArray>();
+ GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().Decrypt(
buffer, decrypted, result);
+ data_object->AppendObject(std::move(decrypted));
+ data_object->AppendObject(std::move(result));
+ data_object->AppendObject(std::move(error));
} catch (const std::runtime_error& e) {
- if_error = true;
+ return -1;
}
- });
-
- if (!if_error) {
- auto resultAnalyse = GpgDecryptResultAnalyse(error, std::move(result));
- resultAnalyse.Analyse();
- process_result_analyse(edit_, info_board_, resultAnalyse);
+ return 0;
+ };
+
+ auto result_callback = [this](int rtn,
+ Thread::Task::DataObjectPtr data_object) {
+ if (!rtn) {
+ if (data_object == nullptr || data_object->GetObjectSize() != 3)
+ throw std::runtime_error("Invalid data object size");
+ auto error = data_object->PopObject<GpgError>();
+ auto result = data_object->PopObject<GpgDecrResult>();
+ auto decrypted = data_object->PopObject<std::unique_ptr<ByteArray>>();
+ auto resultAnalyse = GpgDecryptResultAnalyse(error, std::move(result));
+ resultAnalyse.Analyse();
+ process_result_analyse(edit_, info_board_, resultAnalyse);
+
+ if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
+ edit_->SlotFillTextEditWithText(QString::fromStdString(*decrypted));
+ } else {
+ QMessageBox::critical(this, _("Error"),
+ _("An error occurred during operation."));
+ return;
+ }
+ };
- if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
- edit_->SlotFillTextEditWithText(QString::fromStdString(*decrypted));
- } else {
- QMessageBox::critical(this, _("Error"),
- _("An error occurred during operation."));
- return;
- }
+ process_operation(this, _("Decrypting"), std::move(decrypt_runner),
+ std::move(result_callback), data_object);
}
void MainWindow::slot_find() {
@@ -249,15 +351,17 @@ void MainWindow::slot_verify() {
GpgVerifyResult result = nullptr;
GpgError error;
bool if_error = false;
- process_operation(this, _("Verifying"), [&]() {
- try {
- auto buffer = text.toStdString();
- error = GpgFrontend::GpgBasicOperator::GetInstance().Verify(
- buffer, sig_buffer, result);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- });
+ process_operation(
+ this, _("Verifying"), [&](Thread::Task::DataObjectPtr) -> int {
+ try {
+ auto buffer = text.toStdString();
+ error = GpgFrontend::GpgBasicOperator::GetInstance().Verify(
+ buffer, sig_buffer, result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ return 0;
+ });
if (!if_error) {
auto result_analyse = GpgVerifyResultAnalyse(error, result);
@@ -325,20 +429,23 @@ void MainWindow::slot_encrypt_sign() {
bool if_error = false;
auto tmp = std::make_unique<ByteArray>();
- process_operation(this, _("Encrypting and Signing"), [&]() {
- try {
- auto buffer = edit_->CurTextPage()
- ->GetTextPage()
- ->toPlainText()
- .toUtf8()
- .toStdString();
- error = GpgFrontend::GpgBasicOperator::GetInstance().EncryptSign(
- std::move(keys), std::move(signer_keys), buffer, tmp, encr_result,
- sign_result);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- });
+ process_operation(
+ this, _("Encrypting and Signing"),
+ [&](Thread::Task::DataObjectPtr) -> int {
+ try {
+ auto buffer = edit_->CurTextPage()
+ ->GetTextPage()
+ ->toPlainText()
+ .toUtf8()
+ .toStdString();
+ error = GpgFrontend::GpgBasicOperator::GetInstance().EncryptSign(
+ std::move(keys), std::move(signer_keys), buffer, tmp, encr_result,
+ sign_result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ return 0;
+ });
if (!if_error) {
#ifdef ADVANCE_SUPPORT
@@ -401,8 +508,9 @@ void MainWindow::slot_decrypt_verify() {
// Automatically import public keys that are not stored locally
if (settings.value("advanced/autoPubkeyExchange").toBool()) {
gpgme_verify_result_t tmp_v_result = nullptr;
- auto thread =
- QThread::create([&]() { mCtx->verify(&text, nullptr, &tmp_v_result); });
+ auto thread = QThread::create([&](Thread::Task::DataObjectPtr) -> int {
+ mCtx->verify(&text, nullptr, &tmp_v_result);
+ });
thread->start();
while (thread->isRunning()) QApplication::processEvents();
auto* checker = new UnknownSignersChecker(mCtx, tmp_v_result);
@@ -411,15 +519,17 @@ void MainWindow::slot_decrypt_verify() {
}
#endif
auto decrypted = std::make_unique<ByteArray>();
- process_operation(this, _("Decrypting and Verifying"), [&]() {
- try {
- auto buffer = text.toStdString();
- error = GpgBasicOperator::GetInstance().DecryptVerify(buffer, decrypted,
- d_result, v_result);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- });
+ process_operation(this, _("Decrypting and Verifying"),
+ [&](Thread::Task::DataObjectPtr) -> int {
+ try {
+ auto buffer = text.toStdString();
+ error = GpgBasicOperator::GetInstance().DecryptVerify(
+ buffer, decrypted, d_result, v_result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ return 0;
+ });
if (!if_error) {
auto decrypt_res = GpgDecryptResultAnalyse(error, std::move(d_result));