aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/model/GpgSignResult.cpp5
-rw-r--r--src/core/model/GpgSignResult.h2
-rw-r--r--src/sdk/GFSDKBasic.cpp2
-rw-r--r--src/sdk/GFSDKExtra.cpp2
-rw-r--r--src/sdk/GFSDKGpg.cpp90
-rw-r--r--src/sdk/GFSDKGpg.h50
-rw-r--r--src/sdk/GFSDKModule.cpp2
-rw-r--r--src/sdk/GFSDKUI.cpp78
-rw-r--r--src/sdk/GFSDKUI.h19
-rw-r--r--src/sdk/private/GFSDKPrivat.cpp (renamed from src/sdk/private/CommonUtils.cpp)37
-rw-r--r--src/sdk/private/GFSDKPrivat.h (renamed from src/sdk/private/CommonUtils.h)29
-rw-r--r--src/ui/GpgFrontendUIInit.cpp2
-rw-r--r--src/ui/UIModuleManager.cpp15
-rw-r--r--src/ui/UIModuleManager.h21
-rw-r--r--src/ui/UserInterfaceUtils.cpp14
-rw-r--r--src/ui/UserInterfaceUtils.h9
-rw-r--r--src/ui/main_window/GeneralMainWindow.cpp16
-rw-r--r--src/ui/main_window/GeneralMainWindow.h17
-rw-r--r--src/ui/main_window/MainWindow.cpp4
-rw-r--r--src/ui/main_window/MainWindow.h25
-rw-r--r--src/ui/main_window/MainWindowSlotFunction.cpp32
-rw-r--r--src/ui/main_window/MainWindowSlotUI.cpp57
-rw-r--r--src/ui/main_window/MainWindowUI.cpp40
-rw-r--r--src/ui/widgets/EMailEditorPage.cpp43
-rw-r--r--src/ui/widgets/EMailEditorPage.h46
-rw-r--r--src/ui/widgets/FilePage.cpp7
-rw-r--r--src/ui/widgets/KeyList.cpp11
-rw-r--r--src/ui/widgets/KeyList.h7
-rw-r--r--src/ui/widgets/PlainTextEditorPage.h4
-rw-r--r--src/ui/widgets/TextEdit.cpp91
-rw-r--r--src/ui/widgets/TextEdit.h36
-rw-r--r--src/ui/widgets/TextEditTabWidget.cpp69
-rw-r--r--src/ui/widgets/TextEditTabWidget.h25
33 files changed, 755 insertions, 152 deletions
diff --git a/src/core/model/GpgSignResult.cpp b/src/core/model/GpgSignResult.cpp
index 1819c22b..b7fd2e45 100644
--- a/src/core/model/GpgSignResult.cpp
+++ b/src/core/model/GpgSignResult.cpp
@@ -62,4 +62,9 @@ auto GpgSignResult::InvalidSigners()
}
return result;
}
+
+auto GpgSignResult::HashAlgo() -> QString {
+ if (result_ref_->signatures == nullptr) return {};
+ return gpgme_hash_algo_name(result_ref_->signatures->hash_algo);
+}
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgSignResult.h b/src/core/model/GpgSignResult.h
index a7356c65..3881c86f 100644
--- a/src/core/model/GpgSignResult.h
+++ b/src/core/model/GpgSignResult.h
@@ -39,6 +39,8 @@ class GPGFRONTEND_CORE_EXPORT GpgSignResult {
auto GetRaw() -> gpgme_sign_result_t;
+ auto HashAlgo() -> QString;
+
auto InvalidSigners() -> std::vector<std::tuple<QString, GpgError>>;
explicit GpgSignResult(gpgme_sign_result_t);
diff --git a/src/sdk/GFSDKBasic.cpp b/src/sdk/GFSDKBasic.cpp
index ed734bbe..1c7816d2 100644
--- a/src/sdk/GFSDKBasic.cpp
+++ b/src/sdk/GFSDKBasic.cpp
@@ -32,7 +32,7 @@
#include "core/function/SecureMemoryAllocator.h"
#include "core/function/gpg/GpgCommandExecutor.h"
#include "core/utils/BuildInfoUtils.h"
-#include "sdk/private/CommonUtils.h"
+#include "private/GFSDKPrivat.h"
#include "ui/UIModuleManager.h"
auto GFAllocateMemory(uint32_t size) -> void* {
diff --git a/src/sdk/GFSDKExtra.cpp b/src/sdk/GFSDKExtra.cpp
index 6a95a8f9..1c755389 100644
--- a/src/sdk/GFSDKExtra.cpp
+++ b/src/sdk/GFSDKExtra.cpp
@@ -31,7 +31,7 @@
#include <core/utils/BuildInfoUtils.h>
#include <core/utils/CommonUtils.h>
-#include "sdk/private/CommonUtils.h"
+#include "private/GFSDKPrivat.h"
auto GFCompareSoftwareVersion(const char *current_version,
const char *latest_version) -> int {
diff --git a/src/sdk/GFSDKGpg.cpp b/src/sdk/GFSDKGpg.cpp
index 88162ffa..ae467b7b 100644
--- a/src/sdk/GFSDKGpg.cpp
+++ b/src/sdk/GFSDKGpg.cpp
@@ -24,4 +24,92 @@
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
- */ \ No newline at end of file
+ */
+
+#include "GFSDKGpg.h"
+
+#include "GFSDKBasic.h"
+#include "core/function/gpg/GpgBasicOperator.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/function/gpg/GpgKeyImportExporter.h"
+#include "core/model/DataObject.h"
+#include "core/model/GpgSignResult.h"
+#include "core/typedef/GpgTypedef.h"
+
+//
+#include "core/utils/GpgUtils.h"
+#include "private/GFSDKPrivat.h"
+
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFGpgSignData(int channel, char** key_ids,
+ int key_ids_size, char* data,
+ int sign_mode, int ascii,
+ GFGpgSignResult** ps) -> int {
+ auto singer_ids = CharArrayToQList(key_ids, key_ids_size);
+
+ GpgFrontend::KeyArgsList signer_keys;
+ for (const auto& signer_id : singer_ids) {
+ auto key =
+ GpgFrontend::GpgKeyGetter::GetInstance(channel).GetKey(signer_id);
+ if (key.IsGood()) signer_keys.push_back(key);
+ }
+
+ if (signer_keys.empty()) return -1;
+
+ auto in_buffer = GpgFrontend::GFBuffer(GFUnStrDup(data).toUtf8());
+
+ auto gpg_sign_mode =
+ sign_mode == 0 ? GPGME_SIG_MODE_NORMAL : GPGME_SIG_MODE_DETACH;
+
+ auto [err, data_object] =
+ GpgFrontend::GpgBasicOperator::GetInstance(channel).SignSync(
+ signer_keys, in_buffer, gpg_sign_mode, ascii != 0);
+
+ if (GpgFrontend::CheckGpgError(err) != GPG_ERR_NO_ERROR) return -1;
+
+ auto result =
+ GpgFrontend::ExtractParams<GpgFrontend::GpgSignResult>(data_object, 0);
+ auto out_buffer =
+ GpgFrontend::ExtractParams<GpgFrontend::GFBuffer>(data_object, 1);
+
+ *ps =
+ static_cast<GFGpgSignResult*>(GFAllocateMemory(sizeof(GFGpgSignResult)));
+ auto* s = *ps;
+ s->signature = GFStrDup(out_buffer.ConvertToQByteArray());
+ s->hash_algo = GFStrDup(result.HashAlgo());
+ return 0;
+}
+
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFGpgPublicKey(int channel, char* key_id,
+ int ascii) -> char* {
+ auto key = GpgFrontend::GpgKeyGetter::GetInstance(channel).GetKey(
+ GFUnStrDup(key_id));
+
+ if (!key.IsGood()) return nullptr;
+
+ auto [err, buffer] =
+ GpgFrontend::GpgKeyImportExporter::GetInstance(channel).ExportKey(
+ key, false, ascii != 0, true);
+
+ if (GpgFrontend::CheckGpgError(err) != GPG_ERR_NO_ERROR) return nullptr;
+
+ return GFStrDup(buffer.ConvertToQByteArray());
+}
+
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFGpgKeyPrimaryUID(int channel, char* key_id,
+ GFGpgKeyUID** ps) -> int {
+ auto key = GpgFrontend::GpgKeyGetter::GetInstance(channel).GetKey(
+ GFUnStrDup(key_id));
+
+ if (!key.IsGood()) return -1;
+
+ auto uids = key.GetUIDs();
+ auto& primary_uid = uids->front();
+
+ *ps = static_cast<GFGpgKeyUID*>(GFAllocateMemory(sizeof(GFGpgKeyUID)));
+
+ auto* s = *ps;
+ s->name = GFStrDup(primary_uid.GetName());
+ s->email = GFStrDup(primary_uid.GetEmail());
+ s->comment = GFStrDup(primary_uid.GetComment());
+ return 0;
+}
diff --git a/src/sdk/GFSDKGpg.h b/src/sdk/GFSDKGpg.h
index 1bbf5914..b7b40324 100644
--- a/src/sdk/GFSDKGpg.h
+++ b/src/sdk/GFSDKGpg.h
@@ -28,4 +28,52 @@
#pragma once
-extern "C" {} \ No newline at end of file
+#include "GFSDKExport.h"
+
+extern "C" {
+
+struct GFGpgSignResult {
+ char* signature;
+ char* hash_algo;
+};
+
+struct GFGpgKeyUID {
+ char* name;
+ char* email;
+ char* comment;
+};
+
+/**
+ * @brief
+ *
+ * @param key_id
+ * @param data
+ * @param mode
+ * @return const char*
+ */
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFGpgSignData(int channel, char** key_ids,
+ int key_ids_size, char* data,
+ int sign_mode, int ascii,
+ GFGpgSignResult**) -> int;
+
+/**
+ * @brief
+ *
+ * @param key_id
+ * @param data
+ * @param mode
+ * @return const char*
+ */
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFGpgPublicKey(int channel, char* key_id,
+ int ascii) -> char*;
+
+/**
+ * @brief
+ *
+ * @param channel
+ * @param key_id
+ * @return GpgKeyUID
+ */
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFGpgKeyPrimaryUID(int channel, char* key_id,
+ GFGpgKeyUID**) -> int;
+} \ No newline at end of file
diff --git a/src/sdk/GFSDKModule.cpp b/src/sdk/GFSDKModule.cpp
index 5435b0a1..e76847d2 100644
--- a/src/sdk/GFSDKModule.cpp
+++ b/src/sdk/GFSDKModule.cpp
@@ -29,9 +29,9 @@
#include "GFSDKModule.h"
#include <core/module/ModuleManager.h>
-#include <sdk/private/CommonUtils.h>
#include "GFSDKBasic.h"
+#include "private/GFSDKPrivat.h"
void GFModuleListenEvent(const char *module_id, const char *event_id) {
return GpgFrontend::Module::ModuleManager::GetInstance().ListenEvent(
diff --git a/src/sdk/GFSDKUI.cpp b/src/sdk/GFSDKUI.cpp
index 54716209..cc08705c 100644
--- a/src/sdk/GFSDKUI.cpp
+++ b/src/sdk/GFSDKUI.cpp
@@ -31,9 +31,10 @@
#include <core/utils/CommonUtils.h>
#include <QMap>
+#include <QObject>
#include <QString>
-#include "sdk/private/CommonUtils.h"
+#include "private/GFSDKPrivat.h"
#include "ui/UIModuleManager.h"
auto MetaDataArrayToQMap(MetaData** meta_data_array,
@@ -53,7 +54,7 @@ auto MetaDataArrayToQMap(MetaData** meta_data_array,
}
auto GFUIMountEntry(const char* id, MetaData** meta_data_array,
- int meta_data_array_size, EntryFactory factory) -> int {
+ int meta_data_array_size, QObjectFactory factory) -> int {
if (id == nullptr || factory == nullptr) return -1;
auto meta_data = MetaDataArrayToQMap(meta_data_array, meta_data_array_size);
@@ -69,3 +70,76 @@ auto GFUIMountEntry(const char* id, MetaData** meta_data_array,
return 0;
}
+
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFUIMainWindowPtr() -> void* {
+ return GpgFrontend::UI::UIModuleManager::GetInstance().GetQObject(
+ "main_window");
+}
+
+auto GPGFRONTEND_MODULE_SDK_EXPORT
+GFUIShowDialog(void* dialog_raw_ptr, void* parent_raw_ptr) -> bool {
+ if (dialog_raw_ptr == nullptr) {
+ LOG_E() << "dialog raw ptr is nullptr";
+ return false;
+ }
+
+ auto* q_obj = static_cast<QObject*>(dialog_raw_ptr);
+ QPointer<QDialog> dialog = qobject_cast<QDialog*>(q_obj);
+
+ if (dialog == nullptr) {
+ LOG_E() << "convert dialog raw ptr to qdialog failed";
+ return false;
+ }
+
+ QPointer<QWidget> parent = nullptr;
+ if (parent_raw_ptr != nullptr) {
+ auto* qp_obj = static_cast<QObject*>(parent_raw_ptr);
+ parent = qobject_cast<QWidget*>(qp_obj);
+
+ if (parent == nullptr) {
+ LOG_E() << "convert parent raw ptr to qwidget failed";
+ return false;
+ }
+ }
+
+ auto* main_thread = QApplication::instance()->thread();
+
+ LOG_D() << "before entering into main thread, current thread id:"
+ << QThread::currentThreadId()
+ << ", dialog thread: " << dialog->thread()
+ << "main thread: " << main_thread;
+
+ if (dialog->thread() != main_thread) {
+ LOG_E() << "dialog must be created on main thread";
+ return false;
+ }
+
+ QMetaObject::invokeMethod(
+ parent == nullptr ? QPointer<QObject>(QApplication::instance()) : parent,
+ [dialog, parent]() -> int {
+ LOG_D() << "show qdialog, current thread id:"
+ << QThread::currentThreadId();
+ dialog->setParent(parent);
+ dialog->show();
+ return 0;
+ });
+
+ return true;
+}
+
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFUICreateGUIObject(QObjectFactory factory,
+ void* data) -> void* {
+ QEventLoop loop;
+ void* object = nullptr;
+
+ QMetaObject::invokeMethod(QApplication::instance(), [&]() -> int {
+ LOG_D() << "create gui object, current thread id:"
+ << QThread::currentThreadId();
+ object = factory(data);
+ loop.quit();
+ return 0;
+ });
+
+ loop.exec();
+ return object;
+}
diff --git a/src/sdk/GFSDKUI.h b/src/sdk/GFSDKUI.h
index bf4c3721..f9307cee 100644
--- a/src/sdk/GFSDKUI.h
+++ b/src/sdk/GFSDKUI.h
@@ -32,15 +32,24 @@
extern "C" {
-using EntryFactory = void* (*)(const char*);
+using QObjectFactory = void* (*)(void*);
struct MetaData {
const char* key;
const char* value;
};
-auto GPGFRONTEND_MODULE_SDK_EXPORT GFUIMountEntry(const char* id,
- MetaData** meta_data_array,
- int meta_data_array_size,
- EntryFactory factory) -> int;
+auto GPGFRONTEND_MODULE_SDK_EXPORT
+GFUIMountEntry(const char* id, MetaData** meta_data_array,
+ int meta_data_array_size, QObjectFactory factory) -> int;
+
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFUICreateGUIObject(QObjectFactory factory,
+ void* data) -> void*;
+
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFUIMainWindowPtr() -> void*;
+
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFUIActiveWindowPtr() -> void*;
+
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFUIShowDialog(void* dialog,
+ void* parent) -> bool;
} \ No newline at end of file
diff --git a/src/sdk/private/CommonUtils.cpp b/src/sdk/private/GFSDKPrivat.cpp
index 68afcb5f..71136535 100644
--- a/src/sdk/private/CommonUtils.cpp
+++ b/src/sdk/private/GFSDKPrivat.cpp
@@ -26,7 +26,7 @@
*
*/
-#include "CommonUtils.h"
+#include "GFSDKPrivat.h"
#include <core/utils/MemoryUtils.h>
@@ -34,6 +34,8 @@
#include "GFSDKModule.h"
+Q_LOGGING_CATEGORY(sdk, "sdk")
+
auto GFStrDup(const QString& str) -> char* {
auto utf8_str = str.toUtf8();
auto* c_str = static_cast<char*>(
@@ -58,9 +60,10 @@ auto CharArrayToQMap(char** char_array, int size) -> QMap<QString, QString> {
QMap<QString, QString> map;
for (int i = 0; i < size; i += 2) {
QString const key = GFUnStrDup(char_array[i]);
- QString const value = QString::fromUtf8(char_array[i + 1]);
+ QString const value = GFUnStrDup(char_array[i + 1]);
map.insert(key, value);
}
+
return map;
}
@@ -100,4 +103,32 @@ auto ConvertEventParamsToMap(GFModuleEventParam* params)
}
return param_map;
-} \ No newline at end of file
+}
+
+auto CharArrayToQList(char** char_array, int size) -> QStringList {
+ QStringList list;
+ for (int i = 0; i < size; ++i) {
+ if (char_array[i] != nullptr) {
+ QString value = GFUnStrDup(char_array[i]);
+ list.append(value);
+ }
+ }
+ GpgFrontend::SecureFree(char_array);
+ return list;
+}
+
+auto QListToCharArray(const QStringList& list) -> char** {
+ char** char_array = static_cast<char**>(
+ GpgFrontend::SecureMalloc(list.size() * sizeof(char*)));
+
+ int index = 0;
+ for (const QString& item : list) {
+ QByteArray value = item.toUtf8();
+ char_array[index] =
+ static_cast<char*>(GpgFrontend::SecureMalloc(value.size() + 1));
+ std::strcpy(char_array[index], value.constData());
+ index++;
+ }
+
+ return char_array;
+}
diff --git a/src/sdk/private/CommonUtils.h b/src/sdk/private/GFSDKPrivat.h
index 9539befe..7cfa2c76 100644
--- a/src/sdk/private/CommonUtils.h
+++ b/src/sdk/private/GFSDKPrivat.h
@@ -28,6 +28,15 @@
#pragma once
+// declare logging category
+Q_DECLARE_LOGGING_CATEGORY(sdk)
+
+#define LOG_D() qCDebug(sdk)
+#define LOG_I() qCInfo(sdk)
+#define LOG_W() qCWarning(sdk)
+#define LOG_E() qCCritical(sdk)
+#define LOG_F() qCFatal(sdk)
+
struct GFModuleEventParam;
/**
@@ -77,4 +86,22 @@ auto QMapToCharArray(const QMap<QString, QString> &map, int &size) -> char **;
* @return QMap<QString, QString>
*/
auto ConvertEventParamsToMap(GFModuleEventParam *params)
- -> QMap<QString, QString>; \ No newline at end of file
+ -> QMap<QString, QString>;
+
+/**
+ * @brief
+ *
+ * @param char_array
+ * @param size
+ * @return QStringList
+ */
+auto CharArrayToQList(char **char_array, int size) -> QStringList;
+
+/**
+ * @brief
+ *
+ * @param list
+ * @param size
+ * @return char**
+ */
+auto QListToCharArray(const QStringList &list) -> char **; \ No newline at end of file
diff --git a/src/ui/GpgFrontendUIInit.cpp b/src/ui/GpgFrontendUIInit.cpp
index 0baa1fbb..bc41f5f7 100644
--- a/src/ui/GpgFrontendUIInit.cpp
+++ b/src/ui/GpgFrontendUIInit.cpp
@@ -220,7 +220,7 @@ auto RunGpgFrontendUI(QApplication* app) -> int {
auto main_window = SecureCreateUniqueObject<GpgFrontend::UI::MainWindow>();
// pre-check, if application need to restart
- if (CommonUtils::GetInstance()->isApplicationNeedRestart()) {
+ if (CommonUtils::GetInstance()->IsApplicationNeedRestart()) {
FLOG_D("application need to restart, before main window init.");
return kDeepRestartCode;
}
diff --git a/src/ui/UIModuleManager.cpp b/src/ui/UIModuleManager.cpp
index ed18f473..ba6172a4 100644
--- a/src/ui/UIModuleManager.cpp
+++ b/src/ui/UIModuleManager.cpp
@@ -61,7 +61,7 @@ auto UIModuleManager::DeclareMountPoint(
auto UIModuleManager::MountEntry(const QString& id,
QMap<QString, QString> meta_data,
- EntryFactory factory) -> bool {
+ QObjectFactory factory) -> bool {
if (id.isEmpty() || !mount_points_.contains(id)) return false;
if (factory == nullptr) return false;
@@ -82,7 +82,7 @@ auto UIModuleManager::QueryMountedEntries(QString id) -> QList<MountedUIEntry> {
}
auto MountedUIEntry::GetWidget() const -> QWidget* {
- return qobject_cast<QWidget*>(static_cast<QObject*>(factory_(id_.toUtf8())));
+ return qobject_cast<QWidget*>(static_cast<QObject*>(factory_(nullptr)));
}
auto MountedUIEntry::GetMetaDataByDefault(
@@ -176,4 +176,15 @@ void UIModuleManager::TranslateAllModulesParams() {
#endif
}
+auto UIModuleManager::RegisterQObject(const QString& id, QObject* p) -> bool {
+ if (id.isEmpty() || registered_qobjects_.contains(id)) return false;
+
+ registered_qobjects_[id] = p;
+ return true;
+}
+
+auto UIModuleManager::GetQObject(const QString& id) -> QObject* {
+ return registered_qobjects_.value(id, nullptr);
+}
+
} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/UIModuleManager.h b/src/ui/UIModuleManager.h
index 15f80030..7f23fc78 100644
--- a/src/ui/UIModuleManager.h
+++ b/src/ui/UIModuleManager.h
@@ -41,7 +41,7 @@ struct MountedUIEntry {
QString id_;
QMap<QString, QString> meta_data_;
QMap<QString, QString> meta_data_translated_;
- EntryFactory factory_;
+ QObjectFactory factory_;
MountedUIEntry() = default;
@@ -92,7 +92,7 @@ class GPGFRONTEND_UI_EXPORT UIModuleManager
* @return false
*/
auto MountEntry(const QString& id, QMap<QString, QString> meta_data,
- EntryFactory factory) -> bool;
+ QObjectFactory factory) -> bool;
/**
* @brief
@@ -113,6 +113,22 @@ class GPGFRONTEND_UI_EXPORT UIModuleManager
/**
* @brief
*
+ * @param id
+ * @return auto
+ */
+ auto RegisterQObject(const QString& id, QObject*) -> bool;
+
+ /**
+ * @brief
+ *
+ * @param id
+ * @return auto
+ */
+ auto GetQObject(const QString& id) -> QObject*;
+
+ /**
+ * @brief
+ *
*/
void RegisterAllModuleTranslators();
@@ -128,6 +144,7 @@ class GPGFRONTEND_UI_EXPORT UIModuleManager
QMap<QString, ModuleTranslatorInfo> translator_data_readers_;
QList<QTranslator*> registered_translators_;
QList<QByteArray> read_translator_data_list_;
+ QMap<QString, QPointer<QObject>> registered_qobjects_;
};
} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp
index b8fc9961..d8c0059b 100644
--- a/src/ui/UserInterfaceUtils.cpp
+++ b/src/ui/UserInterfaceUtils.cpp
@@ -55,8 +55,8 @@
namespace GpgFrontend::UI {
-std::unique_ptr<GpgFrontend::UI::CommonUtils>
- GpgFrontend::UI::CommonUtils::instance_ = nullptr;
+QScopedPointer<CommonUtils> CommonUtils::instance =
+ QScopedPointer<CommonUtils>(nullptr);
void show_verify_details(QWidget *parent, int channel,
InfoBoardWidget *info_board, GpgError error,
@@ -121,10 +121,10 @@ void process_operation(QWidget *parent, const QString &waiting_title,
}
auto CommonUtils::GetInstance() -> CommonUtils * {
- if (instance_ == nullptr) {
- instance_ = std::make_unique<CommonUtils>();
+ if (!instance) {
+ instance.reset(new CommonUtils());
}
- return instance_.get();
+ return instance.get();
}
CommonUtils::CommonUtils() : QWidget(nullptr) {
@@ -373,7 +373,7 @@ void CommonUtils::SlotExecuteGpgCommand(
void CommonUtils::SlotImportKeyFromKeyServer(
int channel, const KeyIdArgsList &key_ids,
- const ImportCallbackFunctiopn &callback) {
+ const ImportCallbackFunction &callback) {
auto target_keyserver =
KeyServerSO(SettingsObject("key_server")).GetTargetServer();
if (target_keyserver.isEmpty()) {
@@ -554,7 +554,7 @@ void CommonUtils::SlotRestartApplication(int code) {
}
}
-auto CommonUtils::isApplicationNeedRestart() -> bool {
+auto CommonUtils::IsApplicationNeedRestart() -> bool {
return application_need_to_restart_at_once_;
}
diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h
index dab442dd..6aae75ba 100644
--- a/src/ui/UserInterfaceUtils.h
+++ b/src/ui/UserInterfaceUtils.h
@@ -89,7 +89,7 @@ class CommonUtils : public QWidget {
* @brief
*
*/
- using ImportCallbackFunctiopn =
+ using ImportCallbackFunction =
std::function<void(const QString&, const QString&, size_t, size_t)>;
/**
@@ -131,7 +131,7 @@ class CommonUtils : public QWidget {
* @brief
*
*/
- auto isApplicationNeedRestart() -> bool;
+ auto IsApplicationNeedRestart() -> bool;
/**
* @brief
@@ -238,7 +238,7 @@ class CommonUtils : public QWidget {
*/
static void SlotImportKeyFromKeyServer(
int channel, const GpgFrontend::KeyIdArgsList& key_ids,
- const GpgFrontend::UI::CommonUtils::ImportCallbackFunctiopn& callback);
+ const CommonUtils::ImportCallbackFunction& callback);
/**
* @brief
@@ -282,7 +282,8 @@ class CommonUtils : public QWidget {
std::shared_ptr<GpgImportInformation>);
private:
- static std::unique_ptr<CommonUtils> instance_; ///<
+ static QScopedPointer<CommonUtils> instance; ///<
+
bool application_need_to_restart_at_once_ = false;
};
diff --git a/src/ui/main_window/GeneralMainWindow.cpp b/src/ui/main_window/GeneralMainWindow.cpp
index 1cdb44e0..76eda3fc 100644
--- a/src/ui/main_window/GeneralMainWindow.cpp
+++ b/src/ui/main_window/GeneralMainWindow.cpp
@@ -29,6 +29,7 @@
#include "GeneralMainWindow.h"
#include "core/model/SettingsObject.h"
+#include "ui/UIModuleManager.h"
#include "ui/struct/settings_object/AppearanceSO.h"
#include "ui/struct/settings_object/WindowStateSO.h"
@@ -36,9 +37,10 @@ namespace GpgFrontend::UI {
class GeneralWindowState {};
-GpgFrontend::UI::GeneralMainWindow::GeneralMainWindow(QString name,
+GpgFrontend::UI::GeneralMainWindow::GeneralMainWindow(QString id,
QWidget *parent)
- : QMainWindow(parent), name_(std::move(name)) {
+ : QMainWindow(parent), id_(std::move(id)) {
+ UIModuleManager::GetInstance().RegisterQObject(id_, this);
slot_restore_settings();
}
@@ -51,7 +53,7 @@ void GpgFrontend::UI::GeneralMainWindow::closeEvent(QCloseEvent *event) {
void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept {
try {
- WindowStateSO window_state(SettingsObject(name_ + "_state"));
+ WindowStateSO window_state(SettingsObject(id_ + "_state"));
if (!window_state.window_state_data.isEmpty()) {
// state sets pos & size of dock-widgets
@@ -112,13 +114,13 @@ void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept {
icon_style_ = toolButtonStyle();
} catch (...) {
- LOG_W() << "general main window: " << name_ << ", caught exception";
+ LOG_W() << "general main window: " << id_ << ", caught exception";
}
}
void GpgFrontend::UI::GeneralMainWindow::slot_save_settings() noexcept {
try {
- SettingsObject general_windows_state(name_ + "_state");
+ SettingsObject general_windows_state(id_ + "_state");
// update geo of current dialog
size_ = this->size();
@@ -134,7 +136,7 @@ void GpgFrontend::UI::GeneralMainWindow::slot_save_settings() noexcept {
general_windows_state.Store(window_state.Json());
} catch (...) {
- LOG_W() << "general main window: " << name_ << ", caught exception";
+ LOG_W() << "general main window: " << id_ << ", caught exception";
}
}
@@ -197,4 +199,6 @@ void GeneralMainWindow::update_rect_cache() {
this->parent_rect_ = QRect{0, 0, 0, 0};
}
}
+
+auto GeneralMainWindow::GetId() const -> QString { return id_; }
} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/main_window/GeneralMainWindow.h b/src/ui/main_window/GeneralMainWindow.h
index 7ef1234f..d7d28930 100644
--- a/src/ui/main_window/GeneralMainWindow.h
+++ b/src/ui/main_window/GeneralMainWindow.h
@@ -41,13 +41,20 @@ class GeneralMainWindow : public QMainWindow {
*
* @param name
*/
- explicit GeneralMainWindow(QString name, QWidget* parent = nullptr);
+ explicit GeneralMainWindow(QString id, QWidget* parent = nullptr);
/**
*
*/
~GeneralMainWindow() override;
+ /**
+ * @brief Get the Id object
+ *
+ * @return QString
+ */
+ [[nodiscard]] auto GetId() const -> QString;
+
protected:
/**
*
@@ -66,7 +73,7 @@ class GeneralMainWindow : public QMainWindow {
*/
void movePosition2CenterOfParent();
- QSize icon_size_{}; ///<
+ QSize icon_size_; ///<
int font_size_{}; ///<
Qt::ToolButtonStyle icon_style_; ///<
@@ -88,9 +95,9 @@ class GeneralMainWindow : public QMainWindow {
void update_rect_cache();
private:
- QString name_; ///<
- QPoint pos_; ///<
- QSize size_; ///<
+ QString id_; ///<
+ QPoint pos_; ///<
+ QSize size_; ///<
QRect rect_;
QRect screen_rect_;
QRect parent_rect_;
diff --git a/src/ui/main_window/MainWindow.cpp b/src/ui/main_window/MainWindow.cpp
index 47e7487b..1fcb14df 100644
--- a/src/ui/main_window/MainWindow.cpp
+++ b/src/ui/main_window/MainWindow.cpp
@@ -29,9 +29,7 @@
#include "MainWindow.h"
#include "core/function/CacheManager.h"
-#include "core/function/CoreSignalStation.h"
#include "core/function/GlobalSettingStation.h"
-#include "core/model/GpgPassphraseContext.h"
#include "core/model/SettingsObject.h"
#include "core/module/ModuleManager.h"
#include "ui/UISignalStation.h"
@@ -74,7 +72,7 @@ void MainWindow::Init() noexcept {
attachment_dock_created_ = false;
/* Variable containing if restart is needed */
- this->SlotSetRestartNeeded(false);
+ this->SlotSetRestartNeeded(0);
// init menu bar
this->setMenuBar(new QMenuBar());
diff --git a/src/ui/main_window/MainWindow.h b/src/ui/main_window/MainWindow.h
index ef3fda13..6c6886d4 100644
--- a/src/ui/main_window/MainWindow.h
+++ b/src/ui/main_window/MainWindow.h
@@ -63,7 +63,6 @@ class MainWindow : public GeneralMainWindow {
static constexpr OperationType kVerify = 1 << 3;
static constexpr OperationType kEncryptAndSign = 1 << 4;
static constexpr OperationType kDecryptAndVerify = 1 << 5;
- static constexpr OperationType kVerifyEMail = 1 << 6;
};
/**
@@ -178,6 +177,12 @@ class MainWindow : public GeneralMainWindow {
void SlotDecryptEML();
/**
+ * @brief
+ *
+ */
+ void SlotSignEML();
+
+ /**
* @details decrypt and verify the text of currently active textedit-page
* with the currently checked keys
*/
@@ -299,18 +304,6 @@ class MainWindow : public GeneralMainWindow {
*/
void SlotGeneralDecryptVerify(bool);
- /**
- * @brief
- *
- */
- void SlotGeneralDecryptEMail(bool);
-
- /**
- * @brief
- *
- */
- void SlotGeneralVerifyEMail(bool);
-
private slots:
/**
@@ -601,7 +594,6 @@ class MainWindow : public GeneralMainWindow {
QMenu* key_menu_{}; ///< Submenu for key-operations
QMenu* view_menu_{}; ///< Submenu for view operations
QMenu* import_key_menu_{}; ///< Submenu for import operations
- QMenu* email_menu_{}; ///< Submenu for email operations
QToolBar* crypt_tool_bar_{}; ///< Toolbar holding crypt actions
QToolBar* file_tool_bar_{}; ///< Toolbar holding file actions
@@ -609,7 +601,6 @@ class MainWindow : public GeneralMainWindow {
QToolBar*
special_edit_tool_bar_{}; ///< Toolbar holding special edit actions
QToolBar* key_tool_bar_{}; ///< Toolbar holding key operations
- QToolBar* email_tool_bar_{};
QToolButton*
import_button_{}; ///< Tool button for import dropdown menu in toolbar
QDockWidget* key_list_dock_{}; ///< Encrypt Dock
@@ -617,6 +608,7 @@ class MainWindow : public GeneralMainWindow {
QDockWidget* info_board_dock_{};
QAction* new_tab_act_{}; ///< Action to create new tab
+ QAction* new_email_tab_act_{}; ///< Action to create email tab
QAction* switch_tab_up_act_{}; ///< Action to switch tab up
QAction* switch_tab_down_act_{}; ///< Action to switch tab down
QAction* open_act_{}; ///< Action to open file
@@ -681,9 +673,6 @@ class MainWindow : public GeneralMainWindow {
QAction* import_key_from_clipboard_act_{}; ///<
QAction* import_key_from_key_server_act_{}; ///<
- QAction* verify_email_by_eml_data_act_{}; ///<
- QAction* decrypt_email_by_eml_data_act_{};
-
QLabel* status_bar_icon_{}; ///<
KeyList* m_key_list_{}; ///<
diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp
index c7579ff9..8bfb4289 100644
--- a/src/ui/main_window/MainWindowSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowSlotFunction.cpp
@@ -689,4 +689,36 @@ void MainWindow::slot_decrypt_email_by_eml_data_result_helper(
});
}
+void MainWindow::SlotSignEML() {
+ if (edit_->TabCount() == 0 || edit_->CurEMailPage() == nullptr) return;
+ if (m_key_list_->GetCheckedKeys().isEmpty()) return;
+
+ auto buffer = edit_->CurPlainText().toUtf8();
+
+ Module::TriggerEvent(
+ "EMAIL_EXPORT_EML_DATA",
+ {
+ {"body_data", QString::fromLatin1(buffer.toBase64())},
+ {"channel",
+ QString::number(m_key_list_->GetCurrentGpgContextChannel())},
+ {"sign_key", m_key_list_->GetCheckedKeys().front()},
+ },
+ [=](Module::EventIdentifier i, Module::Event::ListenerIdentifier ei,
+ Module::Event::Params p) {
+ LOG_D() << "EMAIL_DECRYPT_EML_DATA callback: " << i << ei;
+ if (p["ret"] != "0" || !p["err"].isEmpty()) {
+ LOG_E() << "An error occurred trying to decrypt email, "
+ << "error message: " << p["err"];
+
+ return;
+ }
+
+ if (!p["eml_data"].isEmpty()) {
+ edit_->SlotSetText2CurEMailPage(p.value("eml_data", ""));
+ }
+
+ LOG_E() << "mime or signature data is missing";
+ });
+}
+
} // namespace GpgFrontend::UI
diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp
index 105a2374..d99325ec 100644
--- a/src/ui/main_window/MainWindowSlotUI.cpp
+++ b/src/ui/main_window/MainWindowSlotUI.cpp
@@ -80,11 +80,6 @@ void MainWindow::slot_switch_menu_control_mode(int index) {
decrypt_act_->setDisabled(disable);
decrypt_verify_act_->setDisabled(disable);
- if (Module::IsModuleActivate(kEmailModuleID)) {
- verify_email_by_eml_data_act_->setDisabled(disable);
- decrypt_email_by_eml_data_act_->setDisabled(disable);
- }
-
redo_act_->setDisabled(disable);
undo_act_->setDisabled(disable);
zoom_out_act_->setDisabled(disable);
@@ -189,11 +184,6 @@ void MainWindow::SlotUpdateCryptoMenuStatus(unsigned int type) {
decrypt_act_->setDisabled(true);
decrypt_verify_act_->setDisabled(true);
- if (Module::IsModuleActivate(kEmailModuleID)) {
- verify_email_by_eml_data_act_->setDisabled(true);
- decrypt_email_by_eml_data_act_->setDisabled(true);
- }
-
// gnupg operations
if ((opera_type & MainWindow::OperationMenu::kVerify) != 0U) {
verify_act_->setDisabled(false);
@@ -213,12 +203,6 @@ void MainWindow::SlotUpdateCryptoMenuStatus(unsigned int type) {
if ((opera_type & MainWindow::OperationMenu::kDecryptAndVerify) != 0U) {
decrypt_verify_act_->setDisabled(false);
}
-
- // email operations
- if (Module::IsModuleActivate(kEmailModuleID) &&
- (opera_type & MainWindow::OperationMenu::kVerifyEMail) != 0U) {
- verify_email_by_eml_data_act_->setDisabled(false);
- }
}
void MainWindow::SlotGeneralEncrypt(bool) {
@@ -254,6 +238,12 @@ void MainWindow::SlotGeneralDecrypt(bool) {
}
}
}
+
+ if (edit_->CurEMailPage() != nullptr) {
+ this->SlotDecryptEML();
+ return;
+ }
+
if (edit_->SlotCurPageTextEdit() != nullptr) {
this->SlotDecrypt();
}
@@ -267,6 +257,12 @@ void MainWindow::SlotGeneralSign(bool) {
const auto file_info = QFileInfo(path);
if (file_info.isFile()) this->SlotFileSign(path);
}
+
+ if (edit_->CurEMailPage() != nullptr) {
+ this->SlotSignEML();
+ return;
+ }
+
if (edit_->SlotCurPageTextEdit() != nullptr) this->SlotSign();
}
@@ -278,6 +274,12 @@ void MainWindow::SlotGeneralVerify(bool) {
const auto file_info = QFileInfo(path);
if (file_info.isFile()) this->SlotFileVerify(path);
}
+
+ if (edit_->CurEMailPage() != nullptr) {
+ this->SlotVerifyEML();
+ return;
+ }
+
if (edit_->SlotCurPageTextEdit() != nullptr) this->SlotVerify();
}
@@ -314,22 +316,12 @@ void MainWindow::SlotGeneralDecryptVerify(bool) {
}
}
}
+
if (edit_->SlotCurPageTextEdit() != nullptr) {
this->SlotDecryptVerify();
}
}
-void MainWindow::SlotGeneralVerifyEMail(bool) {
- if (edit_->SlotCurPageFileTreeView() != nullptr) {
- const auto* file_tree_view = edit_->SlotCurPageFileTreeView();
- const auto path = file_tree_view->GetSelected();
-
- const auto file_info = QFileInfo(path);
- if (file_info.isFile()) this->SlotFileVerifyEML(path);
- }
- if (edit_->SlotCurPageTextEdit() != nullptr) this->SlotVerifyEML();
-}
-
void MainWindow::slot_clean_gpg_password_cache(bool) {
GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache(
[=](int err, DataObjectPtr) {
@@ -376,15 +368,4 @@ void MainWindow::slot_restart_gpg_components(bool) {
});
}
-void MainWindow::SlotGeneralDecryptEMail(bool) {
- // if (edit_->SlotCurPageFileTreeView() != nullptr) {
- // const auto* file_tree_view = edit_->SlotCurPageFileTreeView();
- // const auto path = file_tree_view->GetSelected();
-
- // const auto file_info = QFileInfo(path);
- // if (file_info.isFile()) this->SlotFileVerify(path);
- // }
- if (edit_->SlotCurPageTextEdit() != nullptr) this->SlotDecryptEML();
-}
-
} // namespace GpgFrontend::UI
diff --git a/src/ui/main_window/MainWindowUI.cpp b/src/ui/main_window/MainWindowUI.cpp
index 9c2a5003..7728d0ae 100644
--- a/src/ui/main_window/MainWindowUI.cpp
+++ b/src/ui/main_window/MainWindowUI.cpp
@@ -260,17 +260,11 @@ void MainWindow::create_actions() {
* E-Mail Menu
*/
if (Module::IsModuleActivate(kEmailModuleID)) {
- verify_email_by_eml_data_act_ = create_action(
- "verify_email_by_eml_data", tr("Verify E-Mail"),
- ":/icons/email-check.png", tr("Verify RAW E-Mail Data (EML)"));
- connect(verify_email_by_eml_data_act_, &QAction::triggered, this,
- &MainWindow::SlotGeneralVerifyEMail);
-
- decrypt_email_by_eml_data_act_ = create_action(
- "decrypt_email_by_eml_data", tr("Decrypt E-Mail"),
- ":/icons/email-open.png", tr("Decrypt RAW E-Mail Data (EML)"));
- connect(decrypt_email_by_eml_data_act_, &QAction::triggered, this,
- &MainWindow::SlotGeneralDecryptEMail);
+ new_email_tab_act_ =
+ create_action("new_email_tab", tr("New E-Mail"), ":/icons/email.png",
+ tr("Create A New E-Mail Tab"));
+ connect(new_email_tab_act_, &QAction::triggered, edit_,
+ &TextEdit::SlotNewEMailTab);
}
/*
@@ -407,6 +401,11 @@ void MainWindow::create_actions() {
void MainWindow::create_menus() {
file_menu_ = menuBar()->addMenu(tr("File"));
file_menu_->addAction(new_tab_act_);
+
+ if (Module::IsModuleActivate(kEmailModuleID)) {
+ file_menu_->addAction(new_email_tab_act_);
+ }
+
file_menu_->addAction(browser_act_);
file_menu_->addAction(open_act_);
file_menu_->addSeparator();
@@ -465,12 +464,6 @@ void MainWindow::create_menus() {
advance_menu_->addAction(gnupg_controller_open_act_);
advance_menu_->addAction(module_controller_open_act_);
- if (Module::IsModuleActivate(kEmailModuleID)) {
- email_menu_ = menuBar()->addMenu(tr("E-Mail"));
- email_menu_->addAction(verify_email_by_eml_data_act_);
- email_menu_->addAction(decrypt_email_by_eml_data_act_);
- }
-
view_menu_ = menuBar()->addMenu(tr("View"));
help_menu_ = menuBar()->addMenu(tr("Help"));
@@ -494,6 +487,11 @@ void MainWindow::create_tool_bars() {
file_tool_bar_ = addToolBar(tr("File"));
file_tool_bar_->setObjectName("fileToolBar");
file_tool_bar_->addAction(new_tab_act_);
+
+ if (Module::IsModuleActivate(kEmailModuleID)) {
+ file_tool_bar_->addAction(new_email_tab_act_);
+ }
+
file_tool_bar_->addAction(open_act_);
file_tool_bar_->addAction(browser_act_);
view_menu_->addAction(file_tool_bar_->toggleViewAction());
@@ -530,14 +528,6 @@ void MainWindow::create_tool_bars() {
special_edit_tool_bar_->hide();
view_menu_->addAction(special_edit_tool_bar_->toggleViewAction());
- if (Module::IsModuleActivate(kEmailModuleID)) {
- email_tool_bar_ = addToolBar(tr("E-Mail"));
- email_tool_bar_->setObjectName("emailToolBar");
- email_tool_bar_->addAction(verify_email_by_eml_data_act_);
- email_tool_bar_->addAction(decrypt_email_by_eml_data_act_);
- view_menu_->addAction(email_tool_bar_->toggleViewAction());
- }
-
// Add dropdown menu for key import to keytoolbar
import_button_ = new QToolButton();
import_button_->setMenu(import_key_menu_);
diff --git a/src/ui/widgets/EMailEditorPage.cpp b/src/ui/widgets/EMailEditorPage.cpp
new file mode 100644
index 00000000..e37695be
--- /dev/null
+++ b/src/ui/widgets/EMailEditorPage.cpp
@@ -0,0 +1,43 @@
+/**
+ * Copyright (C) 2021-2024 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "EMailEditorPage.h"
+
+#include "ui_PlainTextEditor.h"
+
+namespace GpgFrontend::UI {
+
+EMailEditorPage::EMailEditorPage() {
+ this->ui_->encodingLabel->setText("E-Mail");
+}
+
+EMailEditorPage::EMailEditorPage(const QString& file_path, QWidget* parent)
+ : PlainTextEditorPage(file_path, parent) {
+ this->ui_->encodingLabel->setText("E-Mail");
+}
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/widgets/EMailEditorPage.h b/src/ui/widgets/EMailEditorPage.h
new file mode 100644
index 00000000..a5eb6f50
--- /dev/null
+++ b/src/ui/widgets/EMailEditorPage.h
@@ -0,0 +1,46 @@
+/**
+ * Copyright (C) 2021-2024 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <utility>
+
+#include "ui/GpgFrontendUI.h"
+#include "ui/widgets/PlainTextEditorPage.h"
+
+class Ui_FilePage;
+
+namespace GpgFrontend::UI {
+class EMailEditorPage : public PlainTextEditorPage {
+ Q_OBJECT
+ public:
+ EMailEditorPage();
+
+ EMailEditorPage(const QString& file_path, QWidget* parent);
+};
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/widgets/FilePage.cpp b/src/ui/widgets/FilePage.cpp
index 4d9ce26a..ea80cb58 100644
--- a/src/ui/widgets/FilePage.cpp
+++ b/src/ui/widgets/FilePage.cpp
@@ -156,14 +156,11 @@ void FilePage::update_main_basical_opera_menu(const QString& selected_path) {
}
if (info.isFile() && (info.suffix() == "sig" || info.suffix() == "gpg" ||
- info.suffix() == "pgp" || info.suffix() == "asc")) {
+ info.suffix() == "pgp" || info.suffix() == "asc" ||
+ info.suffix() == "eml")) {
operation_type |= MainWindow::OperationMenu::kVerify;
}
- if (info.isFile() && (info.suffix() == "eml")) {
- operation_type |= MainWindow::OperationMenu::kVerifyEMail;
- }
-
emit SignalMainWindowlUpdateBasicalOperaMenu(operation_type);
}
} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp
index 73328885..9498480e 100644
--- a/src/ui/widgets/KeyList.cpp
+++ b/src/ui/widgets/KeyList.cpp
@@ -328,6 +328,17 @@ auto KeyList::GetChecked() -> KeyIdArgsListPtr {
return ret;
}
+auto KeyList::GetCheckedKeys() -> QStringList {
+ auto* key_table = qobject_cast<KeyTable*>(ui_->keyGroupTab->currentWidget());
+ QStringList key_id_list;
+ for (int i = 0; i < key_table->GetRowCount(); i++) {
+ if (key_table->IsRowChecked(i)) {
+ key_id_list.append(key_table->GetKeyIdByRow(i));
+ }
+ }
+ return key_id_list;
+}
+
auto KeyList::GetAllPrivateKeys() -> KeyIdArgsListPtr {
auto* key_table = qobject_cast<KeyTable*>(ui_->keyGroupTab->currentWidget());
auto ret = std::make_unique<KeyIdArgsList>();
diff --git a/src/ui/widgets/KeyList.h b/src/ui/widgets/KeyList.h
index 18c9576e..4216eba8 100644
--- a/src/ui/widgets/KeyList.h
+++ b/src/ui/widgets/KeyList.h
@@ -145,6 +145,13 @@ class KeyList : public QWidget {
auto GetChecked() -> KeyIdArgsListPtr;
/**
+ * @brief Get the Checked Keys object
+ *
+ * @return QStringList
+ */
+ auto GetCheckedKeys() -> QStringList;
+
+ /**
* @brief Get the Checked object
*
* @param key_table
diff --git a/src/ui/widgets/PlainTextEditorPage.h b/src/ui/widgets/PlainTextEditorPage.h
index c4423378..86ec0a56 100644
--- a/src/ui/widgets/PlainTextEditorPage.h
+++ b/src/ui/widgets/PlainTextEditorPage.h
@@ -115,8 +115,10 @@ class PlainTextEditorPage : public QWidget {
*/
void SignalUIBytesDisplayed();
- private:
+ protected:
std::shared_ptr<Ui_PlainTextEditor> ui_; ///<
+
+ private:
QString full_file_path_; ///< The path to the file handled in the tab
bool sign_marked_{}; ///< true, if the signed header is marked, false if not
bool read_done_ = false; ///<
diff --git a/src/ui/widgets/TextEdit.cpp b/src/ui/widgets/TextEdit.cpp
index 2b1f4766..1ea96fde 100644
--- a/src/ui/widgets/TextEdit.cpp
+++ b/src/ui/widgets/TextEdit.cpp
@@ -126,18 +126,31 @@ void TextEdit::SlotOpen() {
}
void TextEdit::SlotSave() {
- if (tab_widget_->count() == 0 || SlotCurPageTextEdit() == 0) {
+ if (tab_widget_->count() == 0) {
return;
}
- QString file_name = SlotCurPageTextEdit()->GetFilePath();
+ if (CurEMailPage() != nullptr) {
+ QString file_name = CurEMailPage()->GetFilePath();
- if (file_name.isEmpty()) {
- // QString docname = tabWidget->tabText(tabWidget->currentIndex());
- // docname.remove(0,2);
- SlotSaveAs();
- } else {
- saveFile(file_name);
+ if (file_name.isEmpty()) {
+ SlotSaveAsEML();
+ } else {
+ saveEMLFile(file_name);
+ }
+ return;
+ }
+
+ if (CurTextPage() != nullptr) {
+ QString file_name = SlotCurPageTextEdit()->GetFilePath();
+
+ if (file_name.isEmpty()) {
+ // QString docname = tabWidget->tabText(tabWidget->currentIndex());
+ // docname.remove(0,2);
+ SlotSaveAs();
+ } else {
+ saveFile(file_name);
+ }
}
}
@@ -171,6 +184,38 @@ auto TextEdit::saveFile(const QString& file_name) -> bool {
return false;
}
+auto TextEdit::saveEMLFile(const QString& file_name) -> bool {
+ if (file_name.isEmpty()) return false;
+
+ PlainTextEditorPage* page = CurEMailPage();
+ if (page == nullptr) return false;
+
+ QFile file(file_name);
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ QMessageBox::warning(
+ this, tr("Warning"),
+ tr("Cannot read file %1:\n%2.").arg(file_name).arg(file.errorString()));
+ return false;
+ }
+
+ QTextStream output_stream(&file);
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ output_stream
+ << page->GetTextPage()->toPlainText().replace("\n", "\r\n").toLatin1();
+ QApplication::restoreOverrideCursor();
+ QTextDocument* document = page->GetTextPage()->document();
+
+ document->setModified(false);
+
+ int cur_index = tab_widget_->currentIndex();
+ tab_widget_->setTabText(cur_index, stripped_name(file_name));
+ page->SetFilePath(file_name);
+ page->NotifyFileSaved();
+
+ file.close();
+ return true;
+}
+
auto TextEdit::SlotSaveAs() -> bool {
if (tab_widget_->count() == 0 || SlotCurPageTextEdit() == nullptr) {
return true;
@@ -187,6 +232,22 @@ auto TextEdit::SlotSaveAs() -> bool {
return saveFile(QFileDialog::getSaveFileName(this, tr("Save file"), path));
}
+auto TextEdit::SlotSaveAsEML() -> bool {
+ if (tab_widget_->count() == 0 || CurEMailPage() == nullptr) {
+ return true;
+ }
+
+ PlainTextEditorPage* page = CurEMailPage();
+ QString path;
+ if (!page->GetFilePath().isEmpty()) {
+ path = page->GetFilePath();
+ } else {
+ path = tab_widget_->tabText(tab_widget_->currentIndex()).remove(0, 2);
+ }
+
+ return saveEMLFile(QFileDialog::getSaveFileName(this, tr("Save file"), path));
+}
+
void TextEdit::SlotCloseTab() {
slot_remove_tab(tab_widget_->currentIndex());
if (tab_widget_->count() != 0) {
@@ -321,6 +382,13 @@ auto TextEdit::MaybeSaveAnyTab() -> bool {
return false;
}
+void TextEdit::SlotSetText2CurEMailPage(const QString& text) {
+ if (CurTextPage() == nullptr) SlotNewEMailTab();
+ auto* edit = CurTextPage()->GetTextPage();
+ edit->clear();
+ edit->appendPlainText(text);
+}
+
void TextEdit::SlotAppendText2CurTextPage(const QString& text) {
if (CurTextPage() == nullptr) SlotNewTab();
CurTextPage()->GetTextPage()->appendPlainText(text);
@@ -554,4 +622,11 @@ auto TextEdit::CurPlainText() const -> QString {
}
auto TextEdit::TabWidget() const -> QTabWidget* { return tab_widget_; }
+
+auto TextEdit::CurEMailPage() const -> EMailEditorPage* {
+ return tab_widget_->CurEMailPage();
+}
+
+void TextEdit::SlotNewEMailTab() { tab_widget_->SlotNewEMailTab(); }
+
} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/TextEdit.h b/src/ui/widgets/TextEdit.h
index 30540569..68b648e5 100644
--- a/src/ui/widgets/TextEdit.h
+++ b/src/ui/widgets/TextEdit.h
@@ -29,6 +29,7 @@
#pragma once
#include "ui/dialog/QuitDialog.h"
+#include "ui/widgets/EMailEditorPage.h"
#include "ui/widgets/FilePage.h"
#include "ui/widgets/PlainTextEditorPage.h"
@@ -78,6 +79,13 @@ class TextEdit : public QWidget {
/**
* @brief
*
+ * @return EMailEditorPage*
+ */
+ [[nodiscard]] auto CurEMailPage() const -> EMailEditorPage*;
+
+ /**
+ * @brief
+ *
* @return FilePage*
*/
[[nodiscard]] auto CurFilePage() const -> FilePage*;
@@ -161,6 +169,12 @@ class TextEdit : public QWidget {
void SlotNewTab();
/**
+ * @details Adds a new tab with the title "untitled"+countpage+".eml"
+ * Sets the focus to the new tab. Increase Tab-Count by one
+ */
+ void SlotNewEMailTab();
+
+ /**
* @details
*
*/
@@ -260,6 +274,21 @@ class TextEdit : public QWidget {
*/
void SlotAppendText2CurTextPage(const QString& text);
+ /**
+ * @brief
+ *
+ * @param text
+ */
+ void SlotSetText2CurEMailPage(const QString& text);
+
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ auto SlotSaveAsEML() -> bool;
+
protected:
/**
* @brief Saves the content of currentTab to the file filename
@@ -268,6 +297,13 @@ class TextEdit : public QWidget {
*/
auto saveFile(const QString& file_name) -> bool;
+ /**
+ * @brief
+ *
+ * @return auto
+ */
+ auto saveEMLFile(const QString& file_name) -> bool;
+
private slots:
/**
diff --git a/src/ui/widgets/TextEditTabWidget.cpp b/src/ui/widgets/TextEditTabWidget.cpp
index 97826f03..8007eb85 100644
--- a/src/ui/widgets/TextEditTabWidget.cpp
+++ b/src/ui/widgets/TextEditTabWidget.cpp
@@ -31,8 +31,9 @@
#include "core/function/GlobalSettingStation.h"
#include "core/model/CacheObject.h"
#include "ui/UISignalStation.h"
+#include "ui/widgets/EMailEditorPage.h"
+#include "ui/widgets/FilePage.h"
#include "ui/widgets/PlainTextEditorPage.h"
-#include "widgets/FilePage.h"
namespace GpgFrontend::UI {
@@ -80,6 +81,11 @@ void TextEditTabWidget::dropEvent(QDropEvent* event) {
continue;
}
+ if (file_info.suffix() == "eml") {
+ SlotOpenEMLFile(local_file);
+ return;
+ }
+
SlotOpenFile(local_file);
}
@@ -125,29 +131,58 @@ void TextEditTabWidget::SlotOpenFile(const QString& path) {
file.close();
}
-void TextEditTabWidget::SlotShowModified(bool changed) {
+
+void TextEditTabWidget::SlotOpenEMLFile(const QString& path) {
+ QFile file(path);
+ auto result = file.open(QIODevice::ReadOnly | QIODevice::Text);
+ if (result) {
+ auto* page = new EMailEditorPage(path, this);
+
+ connect(page->GetTextPage(), &QPlainTextEdit::textChanged, this,
+ &TextEditTabWidget::SlotShowModified);
+ connect(page->GetTextPage(), &QPlainTextEdit::selectionChanged, this,
+ &TextEditTabWidget::slot_save_status_to_cache_for_recovery);
+
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ auto index = this->addTab(page, stripped_name(path));
+ this->setTabIcon(index, QIcon(":/icons/email.png"));
+ this->setCurrentIndex(this->count() - 1);
+ QApplication::restoreOverrideCursor();
+ page->GetTextPage()->setFocus();
+ page->ReadFile();
+ } else {
+ QMessageBox::warning(
+ this, tr("Warning"),
+ tr("Cannot read file %1:\n%2.").arg(path).arg(file.errorString()));
+ }
+
+ file.close();
+}
+
+void TextEditTabWidget::SlotShowModified() {
// get current tab
int index = this->currentIndex();
- QString title = this->tabText(index);
+ QString title = this->tabText(index).trimmed();
- // if changed
- if (!changed) {
- this->setTabText(index, title.remove(0, 2));
- return;
- }
+ if (title.startsWith("*")) return;
// if doc is modified now, add leading * to title,
// otherwise remove the leading * from the title
if (CurTextPage()->GetTextPage()->document()->isModified()) {
- this->setTabText(index, title.trimmed().prepend("* "));
+ this->setTabText(index, title.prepend("* "));
} else {
this->setTabText(index, title.remove(0, 2));
}
}
+
auto TextEditTabWidget::CurTextPage() const -> PlainTextEditorPage* {
return qobject_cast<PlainTextEditorPage*>(this->currentWidget());
}
+auto TextEditTabWidget::CurEMailPage() const -> EMailEditorPage* {
+ return qobject_cast<EMailEditorPage*>(this->currentWidget());
+}
+
auto TextEditTabWidget::SlotCurPageTextEdit() -> PlainTextEditorPage* {
auto* cur_page = qobject_cast<PlainTextEditorPage*>(this->currentWidget());
return cur_page;
@@ -228,6 +263,22 @@ void TextEditTabWidget::SlotNewTab() {
connect(page->GetTextPage()->document(), &QTextDocument::contentsChanged,
this, &TextEditTabWidget::slot_save_status_to_cache_for_recovery);
}
+
+void TextEditTabWidget::SlotNewEMailTab() {
+ QString header = tr("untitled") + QString::number(++count_page_) + ".eml";
+
+ auto* page = new EMailEditorPage();
+ auto index = this->addTab(page, header);
+ this->setTabIcon(index, QIcon(":/icons/email.png"));
+ this->setCurrentIndex(this->count() - 1);
+ page->GetTextPage()->setFocus();
+
+ connect(page->GetTextPage(), &QPlainTextEdit::textChanged, this,
+ &TextEditTabWidget::SlotShowModified);
+ connect(page->GetTextPage(), &QPlainTextEdit::selectionChanged, this,
+ &TextEditTabWidget::slot_save_status_to_cache_for_recovery);
+}
+
void TextEditTabWidget::SlotNewTabWithContent(QString title,
const QString& content) {
QString header = tr("untitled") + QString::number(++count_page_) + ".txt";
diff --git a/src/ui/widgets/TextEditTabWidget.h b/src/ui/widgets/TextEditTabWidget.h
index b0cafae2..13ed00f0 100644
--- a/src/ui/widgets/TextEditTabWidget.h
+++ b/src/ui/widgets/TextEditTabWidget.h
@@ -28,10 +28,11 @@
#pragma once
-#include "widgets/FilePage.h"
namespace GpgFrontend::UI {
class PlainTextEditorPage;
+class EMailEditorPage;
+class FilePage;
class TextEditTabWidget : public QTabWidget {
Q_OBJECT
@@ -49,6 +50,12 @@ class TextEditTabWidget : public QTabWidget {
/**
* @brief
*
+ */
+ void SlotNewEMailTab();
+
+ /**
+ * @brief
+ *
* @param title
* @param content
*/
@@ -62,6 +69,13 @@ class TextEditTabWidget : public QTabWidget {
/**
* @brief
*
+ * @param path
+ */
+ void SlotOpenEMLFile(const QString& path);
+
+ /**
+ * @brief
+ *
*/
void SlotOpenDirectory(const QString& target_directory);
@@ -69,7 +83,7 @@ class TextEditTabWidget : public QTabWidget {
* @details put a * in front of current tabs title, if current textedit is
* modified
*/
- void SlotShowModified(bool);
+ void SlotShowModified();
/**
* @brief
@@ -83,6 +97,13 @@ class TextEditTabWidget : public QTabWidget {
*
* @return PlainTextEditorPage*
*/
+ [[nodiscard]] auto CurEMailPage() const -> EMailEditorPage*;
+
+ /**
+ * @brief
+ *
+ * @return PlainTextEditorPage*
+ */
auto SlotCurPageTextEdit() -> PlainTextEditorPage*;
/**