aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/GpgContext.cpp4
-rw-r--r--src/core/GpgContext.h4
-rw-r--r--src/core/GpgCoreInit.cpp17
-rw-r--r--src/core/GpgFunctionObject.cpp143
-rw-r--r--src/core/GpgFunctionObject.h279
-rw-r--r--src/core/function/gpg/GpgKeyGetter.cpp84
-rw-r--r--src/core/function/gpg/GpgKeyGetter.h37
-rw-r--r--src/core/thread/CtxCheckThread.cpp4
-rw-r--r--src/main.cpp4
-rw-r--r--src/ui/GpgFrontendUIInit.cpp10
-rw-r--r--src/ui/GpgFrontendUIInit.h5
-rw-r--r--src/ui/SignalStation.cpp2
-rw-r--r--src/ui/SignalStation.h6
-rw-r--r--src/ui/UserInterfaceUtils.cpp165
-rw-r--r--src/ui/UserInterfaceUtils.h18
-rw-r--r--src/ui/import_export/KeyServerImportDialog.cpp20
-rw-r--r--src/ui/key_generate/KeygenDialog.cpp12
-rw-r--r--src/ui/key_generate/SubkeyGenerateDialog.cpp21
-rw-r--r--src/ui/keypair_details/KeyPairDetailTab.cpp12
-rw-r--r--src/ui/keypair_details/KeyPairSubkeyTab.cpp4
-rw-r--r--src/ui/keypair_details/KeyPairUIDTab.cpp4
-rw-r--r--src/ui/keypair_details/KeySetExpireDateDialog.cpp16
-rw-r--r--src/ui/main_window/MainWindowSlotFunction.cpp3
-rw-r--r--src/ui/widgets/KeyList.cpp24
24 files changed, 641 insertions, 257 deletions
diff --git a/src/core/GpgContext.cpp b/src/core/GpgContext.cpp
index 0da963ee..733354fc 100644
--- a/src/core/GpgContext.cpp
+++ b/src/core/GpgContext.cpp
@@ -224,4 +224,8 @@ gpgme_error_t GpgContext::test_status_cb(void *hook, const char *keyword,
return GPG_ERR_NO_ERROR;
}
+void GpgContext::_ctx_ref_deleter::operator()(gpgme_ctx_t _ctx) {
+ if (_ctx != nullptr) gpgme_release(_ctx);
+}
+
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/GpgContext.h b/src/core/GpgContext.h
index b148fcb5..e1f1bda4 100644
--- a/src/core/GpgContext.h
+++ b/src/core/GpgContext.h
@@ -116,9 +116,7 @@ class GPGFRONTEND_CORE_EXPORT GpgContext
*
*/
struct _ctx_ref_deleter {
- void operator()(gpgme_ctx_t _ctx) {
- if (_ctx != nullptr) gpgme_release(_ctx);
- }
+ void operator()(gpgme_ctx_t _ctx);
};
using CtxRefHandler =
diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp
index e9b8fcdc..41cf99cb 100644
--- a/src/core/GpgCoreInit.cpp
+++ b/src/core/GpgCoreInit.cpp
@@ -28,6 +28,9 @@
#include "GpgCoreInit.h"
+#include <memory>
+
+#include "GpgFunctionObject.h"
#include "core/GpgContext.h"
#include "core/function/GlobalSettingStation.h"
@@ -70,27 +73,25 @@ void init_logging() {
void init_gpgfrontend_core() {
// init default channel
GpgFrontend::GpgContext::CreateInstance(
- GPGFRONTEND_DEFAULT_CHANNEL,
- [&]() -> std::unique_ptr<GpgFrontend::GpgContext> {
+ GPGFRONTEND_DEFAULT_CHANNEL, [&]() -> std::unique_ptr<ChannelObject> {
GpgFrontend::GpgContextInitArgs args;
- return std::make_unique<GpgFrontend::GpgContext>(args);
+ return std::unique_ptr<ChannelObject>(new GpgContext(args));
});
// init non-ascii channel
GpgFrontend::GpgContext::CreateInstance(
- GPGFRONTEND_NON_ASCII_CHANNEL,
- [&]() -> std::unique_ptr<GpgFrontend::GpgContext> {
+ GPGFRONTEND_NON_ASCII_CHANNEL, [&]() -> std::unique_ptr<ChannelObject> {
GpgFrontend::GpgContextInitArgs args;
args.ascii = false;
- return std::make_unique<GpgFrontend::GpgContext>(args);
+ return std::unique_ptr<ChannelObject>(new GpgContext(args));
});
}
void new_default_settings_channel(int channel) {
GpgFrontend::GpgContext::CreateInstance(
- channel, [&]() -> std::unique_ptr<GpgFrontend::GpgContext> {
+ channel, [&]() -> std::unique_ptr<ChannelObject> {
GpgFrontend::GpgContextInitArgs args;
- return std::make_unique<GpgFrontend::GpgContext>(args);
+ return std::unique_ptr<ChannelObject>(new GpgContext(args));
});
}
diff --git a/src/core/GpgFunctionObject.cpp b/src/core/GpgFunctionObject.cpp
new file mode 100644
index 00000000..9fb55247
--- /dev/null
+++ b/src/core/GpgFunctionObject.cpp
@@ -0,0 +1,143 @@
+/**
+ * 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/GpgFunctionObject.h"
+
+#include <cassert>
+#include <functional>
+#include <memory>
+#include <mutex>
+#include <shared_mutex>
+
+#include "easylogging++.h"
+
+void GpgFrontend::ChannelObject::SetChannel(int channel) {
+ this->channel_ = channel;
+}
+
+int GpgFrontend::ChannelObject::GetChannel() const { return channel_; }
+
+int GpgFrontend::ChannelObject::GetDefaultChannel() { return _default_channel; }
+
+void GpgFrontend::SingletonStorage::ReleaseChannel(int channel) {
+ decltype(instances_map_.end()) _it;
+ {
+ std::shared_lock<std::shared_mutex> lock(instances_mutex_);
+ _it = instances_map_.find(channel);
+ }
+ if (_it != instances_map_.end()) instances_map_.erase(_it);
+ DLOG(INFO) << "channel" << channel << "released";
+}
+
+GpgFrontend::ChannelObject* GpgFrontend::SingletonStorage::FindObjectInChannel(
+ int channel) {
+ LOG(INFO) << "channel:" << channel << "instance address:" << &instances_map_;
+ // read instances_map_
+ decltype(instances_map_.end()) _it;
+ {
+ std::shared_lock<std::shared_mutex> lock(instances_mutex_);
+ _it = instances_map_.find(channel);
+ if (_it == instances_map_.end()) {
+ LOG(INFO) << "channel:" << channel << "not found";
+ return nullptr;
+ } else {
+ return _it->second.get();
+ }
+ }
+}
+
+std::vector<int> GpgFrontend::SingletonStorage::GetAllChannelId() {
+ std::vector<int> _channels;
+ for (const auto& [key, value] : instances_map_) {
+ _channels.push_back(key);
+ }
+ return _channels;
+}
+
+GpgFrontend::ChannelObject* GpgFrontend::SingletonStorage::SetObjectInChannel(
+ int channel, std::unique_ptr<ChannelObject> p_obj) {
+ {
+ LOG(INFO) << "channel:" << channel
+ << "instance address:" << &instances_map_;
+
+ assert(p_obj != nullptr);
+ if (p_obj == nullptr) return nullptr;
+
+ auto raw_obj = p_obj.get();
+ p_obj->SetChannel(channel);
+ {
+ std::unique_lock<std::shared_mutex> lock(instances_mutex_);
+ instances_map_.insert({channel, std::move(p_obj)});
+ }
+ return raw_obj;
+ }
+}
+
+GpgFrontend::SingletonStorage*
+GpgFrontend::SingletonStorageCollection::GetSingletonStorage(
+ const std::type_info& type_id) {
+ const auto hash = type_id.hash_code();
+ LOG(INFO) << "hash" << hash << "type_name:" << type_id.name();
+
+ while (true) {
+ decltype(storages_map_.end()) _it;
+ {
+ std::shared_lock<std::shared_mutex> lock(storages_mutex_);
+ _it = storages_map_.find(hash);
+ }
+ if (_it == storages_map_.end()) {
+ LOG(INFO) << "hash:" << hash << "not found";
+ {
+ std::unique_lock<std::shared_mutex> lock(storages_mutex_);
+ storages_map_.insert({hash, std::make_unique<SingletonStorage>()});
+ LOG(INFO) << "hash:" << hash << "created"
+ << "storage address:" << &storages_map_;
+ }
+ continue;
+ } else {
+ LOG(INFO) << "hash:" << hash << "found";
+ return _it->second.get();
+ }
+ }
+}
+
+GpgFrontend::SingletonStorageCollection*
+GpgFrontend::SingletonStorageCollection::GetInstance() {
+ static SingletonStorageCollection* instance = nullptr;
+ if (instance == nullptr) {
+ instance = new SingletonStorageCollection();
+ }
+ return instance;
+}
+
+GpgFrontend::ChannelObject::ChannelObject() noexcept = default;
+
+GpgFrontend::ChannelObject::ChannelObject(int channel) : channel_(channel) {
+ LOG(INFO) << "called"
+ << "channel:" << channel;
+}
diff --git a/src/core/GpgFunctionObject.h b/src/core/GpgFunctionObject.h
index 391b1585..f16e4cae 100644
--- a/src/core/GpgFunctionObject.h
+++ b/src/core/GpgFunctionObject.h
@@ -35,20 +35,144 @@
#include <shared_mutex>
#include <stdexcept>
#include <string>
+#include <typeinfo>
+#include <utility>
+#include <vector>
#include "GpgConstants.h"
+#include "easylogging++.h"
namespace GpgFrontend {
/**
+ * @brief object which in channel system
+ *
+ */
+class GPGFRONTEND_CORE_EXPORT ChannelObject {
+ public:
+ /**
+ * @brief Construct a new Default Channel Object object
+ *
+ */
+ ChannelObject() noexcept;
+
+ /**
+ * @brief Construct a new Channel Object object
+ *
+ * @param channel
+ */
+ ChannelObject(int channel);
+
+ /**
+ * @brief Get the Default Channel object
+ *
+ * @return int
+ */
+ static int GetDefaultChannel();
+
+ /**
+ * @brief Get the Channel object
+ *
+ * @return int
+ */
+ [[nodiscard]] int GetChannel() const;
+
+ /**
+ * @brief Set the Channel object
+ *
+ * @param channel
+ */
+ void SetChannel(int channel);
+
+ private:
+ int channel_ = _default_channel; ///< The channel id
+ static constexpr int _default_channel = 0; ///< The default channel id
+};
+
+class GPGFRONTEND_CORE_EXPORT SingletonStorage {
+ public:
+ /**
+ * @brief
+ *
+ * @param channel
+ */
+ void ReleaseChannel(int channel);
+
+ /**
+ * @brief
+ *
+ * @param channel
+ * @return T*
+ */
+ ChannelObject* FindObjectInChannel(int channel);
+
+ /**
+ * @brief Get all the channel ids
+ *
+ * @return std::vector<int>
+ */
+ std::vector<int> GetAllChannelId();
+
+ /**
+ * @brief Set a new object in channel object
+ *
+ * @param channel
+ * @param p_obj
+ * @return T*
+ */
+ ChannelObject* SetObjectInChannel(int channel,
+ std::unique_ptr<ChannelObject> p_obj);
+
+ private:
+ std::shared_mutex instances_mutex_; ///< mutex for _instances_map
+ std::map<int, std::unique_ptr<ChannelObject>>
+ instances_map_; ///< map of singleton instances
+};
+
+class GPGFRONTEND_CORE_EXPORT SingletonStorageCollection {
+ public:
+ /**
+ * @brief Get the Instance object
+ *
+ * @return SingletonStorageCollection*
+ */
+ static SingletonStorageCollection* GetInstance();
+
+ /**
+ * @brief Get the Singleton Storage object
+ *
+ * @param singleton_function_object
+ * @return SingletonStorage*
+ */
+ SingletonStorage* GetSingletonStorage(const std::type_info&);
+
+ private:
+ std::shared_mutex storages_mutex_; ///< mutex for storages_map_
+ std::map<size_t, std::unique_ptr<SingletonStorage>> storages_map_;
+};
+/**
* @brief
*
* @tparam T
*/
template <typename T>
-class SingletonFunctionObject {
+class SingletonFunctionObject : public ChannelObject {
public:
/**
+ * @brief prohibit copy
+ *
+ */
+ SingletonFunctionObject(const SingletonFunctionObject<T>&) = delete;
+
+ /**
+ * @brief prohibit copy
+ *
+ * @return SingletonFunctionObject&
+ */
+ SingletonFunctionObject& operator=(const SingletonFunctionObject<T>&) =
+ delete;
+
+ /**
* @brief Get the Instance object
*
* @param channel
@@ -59,10 +183,19 @@ class SingletonFunctionObject {
static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
"T not derived from SingletonFunctionObject<T>");
- auto _p_pbj = find_object_in_channel(channel);
- if (_p_pbj == nullptr)
- return *set_object_in_channel(channel, std::make_unique<T>(channel));
- else
+ auto p_storage =
+ SingletonStorageCollection::GetInstance()->GetSingletonStorage(
+ typeid(T));
+
+ auto* _p_pbj = (T*)(p_storage->FindObjectInChannel(channel));
+
+ LOG(INFO) << "object address" << _p_pbj;
+
+ if (_p_pbj == nullptr) {
+ auto new_obj = std::unique_ptr<ChannelObject>(new T(channel));
+ LOG(INFO) << "create new object";
+ return *(T*)(p_storage->SetObjectInChannel(channel, std::move(new_obj)));
+ } else
return *_p_pbj;
}
@@ -73,33 +206,22 @@ class SingletonFunctionObject {
* @param factory
* @return T&
*/
- static T& CreateInstance(int channel,
- std::function<std::unique_ptr<T>(void)> factory) {
+ static T& CreateInstance(
+ int channel,
+ std::function<std::unique_ptr<ChannelObject>(void)> factory) {
static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
"T not derived from SingletonFunctionObject<T>");
- auto _p_pbj = find_object_in_channel(channel);
- if (_p_pbj == nullptr)
- return *set_object_in_channel(channel, std::move(factory()));
- else
- return *_p_pbj;
- }
+ auto p_storage =
+ SingletonStorageCollection::GetInstance()->GetSingletonStorage(
+ typeid(T));
- /**
- * @brief Create a Instance object
- *
- * @param channel
- * @param p_obj
- * @return T&
- */
- static T& CreateInstance(int channel, std::unique_ptr<T> p_obj = nullptr) {
- static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
- "T not derived from SingletonFunctionObject<T>");
+ auto _p_pbj = (T*)(p_storage->FindObjectInChannel(channel));
- auto _p_pbj = find_object_in_channel(channel);
- if (_p_pbj == nullptr)
- return *set_object_in_channel(channel, std::move(p_obj));
- else
+ if (_p_pbj == nullptr) {
+ return *(
+ T*)(p_storage->SetObjectInChannel(channel, std::move(factory())));
+ } else
return *_p_pbj;
}
@@ -109,14 +231,10 @@ class SingletonFunctionObject {
* @param channel
* @return T&
*/
- static T& ReleaseChannel(int channel) {
- decltype(_instances_map.end()) _it;
- {
- std::shared_lock lock(_instances_mutex);
- _it = _instances_map.find(channel);
- }
- if (_it != _instances_map.end()) _instances_map.erase(_it);
- DLOG(INFO) << "channel" << channel << "released";
+ static void ReleaseChannel(int channel) {
+ SingletonStorageCollection::GetInstance()
+ ->GetSingletonStorage(typeid(T))
+ ->ReleaseChannel(channel);
}
/**
@@ -124,14 +242,25 @@ class SingletonFunctionObject {
*
* @return int
*/
- static int GetDefaultChannel() { return _default_channel; }
+ static int GetDefaultChannel() { return ChannelObject::GetDefaultChannel(); }
/**
* @brief Get the Channel object
*
* @return int
*/
- [[nodiscard]] int GetChannel() const { return channel_; }
+ [[nodiscard]] int GetChannel() const { return ChannelObject::GetChannel(); }
+
+ /**
+ * @brief Get all the channel ids
+ *
+ * @return std::vector<int>
+ */
+ static std::vector<int> GetAllChannelId() {
+ return SingletonStorageCollection::GetInstance()
+ ->GetSingletonStorage(typeid(T))
+ ->GetAllChannelId();
+ }
/**
* @brief Construct a new Singleton Function Object object
@@ -163,85 +292,17 @@ class SingletonFunctionObject {
*
* @param channel
*/
- explicit SingletonFunctionObject(int channel) : channel_(channel) {}
+ explicit SingletonFunctionObject(int channel) : ChannelObject(channel) {
+ LOG(INFO) << "called"
+ << "channel:" << channel;
+ }
/**
* @brief Destroy the Singleton Function Object object
*
*/
virtual ~SingletonFunctionObject() = default;
-
- /**
- * @brief Set the Channel object
- *
- * @param channel
- */
- void SetChannel(int channel) { this->channel_ = channel; }
-
- private:
- int channel_ = _default_channel; ///<
- static int _default_channel; ///<
- static std::mutex _instance_mutex; ///<
- static std::shared_mutex _instances_mutex; ///<
- static std::unique_ptr<T> _instance; ///<
- static std::map<int, std::unique_ptr<T>> _instances_map; ///<
-
- /**
- * @brief
- *
- * @param channel
- * @return T*
- */
- static T* find_object_in_channel(int channel) {
- // read _instances_map
- decltype(_instances_map.end()) _it;
- {
- std::shared_lock lock(_instances_mutex);
- _it = _instances_map.find(channel);
- if (_it == _instances_map.end())
- return nullptr;
- else
- return _it->second.get();
- }
- }
-
- /**
- * @brief Set the object in channel object
- *
- * @param channel
- * @param p_obj
- * @return T*
- */
- static T* set_object_in_channel(int channel, std::unique_ptr<T> p_obj) {
- {
- if (p_obj == nullptr) p_obj = std::make_unique<T>();
- T* obj = p_obj.get();
- obj->SetChannel(channel);
- {
- std::unique_lock lock(_instances_mutex);
- _instances_map.insert({channel, std::move(p_obj)});
- }
- return obj;
- }
- }
};
-
-template <typename T>
-int SingletonFunctionObject<T>::_default_channel =
- GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL;
-
-template <typename T>
-std::mutex SingletonFunctionObject<T>::_instance_mutex;
-
-template <typename T>
-std::shared_mutex SingletonFunctionObject<T>::_instances_mutex;
-
-template <typename T>
-std::unique_ptr<T> SingletonFunctionObject<T>::_instance = nullptr;
-
-template <typename T>
-std::map<int, std::unique_ptr<T>> SingletonFunctionObject<T>::_instances_map;
-
} // namespace GpgFrontend
#endif // GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
diff --git a/src/core/function/gpg/GpgKeyGetter.cpp b/src/core/function/gpg/GpgKeyGetter.cpp
index cbd40efc..9a7b505c 100644
--- a/src/core/function/gpg/GpgKeyGetter.cpp
+++ b/src/core/function/gpg/GpgKeyGetter.cpp
@@ -30,12 +30,32 @@
#include <gpg-error.h>
+#include <mutex>
+#include <shared_mutex>
+#include <utility>
+
#include "GpgConstants.h"
+#include "easylogging++.h"
+#include "model/GpgKey.h"
GpgFrontend::GpgKeyGetter::GpgKeyGetter(int channel)
- : SingletonFunctionObject<GpgKeyGetter>(channel) {}
+ : SingletonFunctionObject<GpgKeyGetter>(channel) {
+ LOG(INFO) << "called"
+ << "channel:" << channel;
+}
GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetKey(const std::string& fpr) {
+ LOG(INFO) << "called";
+
+ // find in cache first
+ {
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ if (keys_cache_.find(fpr) != keys_cache_.end()) {
+ std::lock_guard<std::mutex> lock(ctx_mutex_);
+ return keys_cache_[fpr].Copy();
+ }
+ }
+
gpgme_key_t _p_key = nullptr;
gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 1);
if (_p_key == nullptr) {
@@ -48,6 +68,15 @@ GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetKey(const std::string& fpr) {
GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetPubkey(
const std::string& fpr) {
+ // find in cache first
+ {
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ if (keys_cache_.find(fpr) != keys_cache_.end()) {
+ std::lock_guard<std::mutex> lock(ctx_mutex_);
+ return keys_cache_[fpr].Copy();
+ }
+ }
+
gpgme_key_t _p_key = nullptr;
gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 0);
if (_p_key == nullptr)
@@ -56,28 +85,59 @@ GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetPubkey(
}
GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::FetchKey() {
- gpgme_error_t err;
+ // get the lock
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+
+ LOG(INFO) << "GpgKeyGetter FetchKey"
+ << "channel id:" << GetChannel();
auto keys_list = std::make_unique<GpgKeyLinkList>();
- LOG(INFO) << "GpgKeyGetter FetchKey"
- << "ctx address" << ctx_;
+ LOG(INFO) << "cache address:" << &keys_cache_ << "object address" << this;
- err = gpgme_op_keylist_start(ctx_, nullptr, 0);
+ for (const auto& [key, value] : keys_cache_) {
+ LOG(INFO) << "FetchKey Id:" << value.GetId();
+ keys_list->push_back(value.Copy());
+ }
+ LOG(INFO) << "ended";
+ return keys_list;
+}
+
+void GpgFrontend::GpgKeyGetter::FlushKeyCache() {
+ LOG(INFO) << "called"
+ << "channel id: " << GetChannel();
+
+ // clear the keys cache
+ keys_cache_.clear();
+
+ // init
+ GpgError err = gpgme_op_keylist_start(ctx_, nullptr, 0);
+
+ // for debug
assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
- gpgme_key_t key;
- while ((err = gpgme_op_keylist_next(ctx_, &key)) == GPG_ERR_NO_ERROR) {
- keys_list->push_back(GetKey(key->fpr));
+ // return when error
+ if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) return;
+
+ {
+ // get the lock
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ gpgme_key_t key;
+ while ((err = gpgme_op_keylist_next(ctx_, &key)) == GPG_ERR_NO_ERROR) {
+ LOG(INFO) << "LoadKey Fpr:" << key->fpr << "Id:" << key->subkeys->keyid;
+ keys_cache_.insert({key->subkeys->keyid, GpgKey(std::move(key))});
+ }
}
+ LOG(INFO) << "cache address:" << &keys_cache_ << "object address" << this;
+
+ // for debug
assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_EOF);
err = gpgme_op_keylist_end(ctx_);
-
assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR);
- return keys_list;
+ LOG(INFO) << "ended";
}
GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeys(
@@ -89,6 +149,8 @@ GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeys(
GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy(
const GpgFrontend::KeyLinkListPtr& keys) {
+ // get the lock
+ std::lock_guard<std::mutex> lock(ctx_mutex_);
auto keys_copy = std::make_unique<GpgKeyLinkList>();
for (const auto& key : *keys) keys_copy->push_back(key.Copy());
return keys_copy;
@@ -96,6 +158,8 @@ GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy(
GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy(
const GpgFrontend::KeyListPtr& keys) {
+ // get the lock
+ std::lock_guard<std::mutex> lock(ctx_mutex_);
auto keys_copy = std::make_unique<KeyArgsList>();
for (const auto& key : *keys) keys_copy->push_back(key.Copy());
return keys_copy;
diff --git a/src/core/function/gpg/GpgKeyGetter.h b/src/core/function/gpg/GpgKeyGetter.h
index d63238f5..72cd777c 100644
--- a/src/core/function/gpg/GpgKeyGetter.h
+++ b/src/core/function/gpg/GpgKeyGetter.h
@@ -29,6 +29,9 @@
#ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
#define GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
+#include <mutex>
+#include <vector>
+
#include "core/GpgContext.h"
#include "core/GpgFunctionObject.h"
#include "core/GpgModel.h"
@@ -56,7 +59,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param fpr
* @return GpgKey
*/
- GpgKey GetKey(const std::string& fpr);
+ GpgKey GetKey(const std::string& id);
/**
* @brief Get the Keys object
@@ -72,22 +75,28 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param fpr
* @return GpgKey
*/
- GpgKey GetPubkey(const std::string& fpr);
+ GpgKey GetPubkey(const std::string& id);
/**
- * @brief
+ * @brief Get all the keys by receiving a linked list
*
* @return KeyLinkListPtr
*/
KeyLinkListPtr FetchKey();
/**
+ * @brief flush the keys in the cache
+ *
+ */
+ void FlushKeyCache();
+
+ /**
* @brief Get the Keys Copy object
*
* @param keys
* @return KeyListPtr
*/
- static KeyListPtr GetKeysCopy(const KeyListPtr& keys);
+ KeyListPtr GetKeysCopy(const KeyListPtr& keys);
/**
* @brief Get the Keys Copy object
@@ -95,7 +104,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param keys
* @return KeyLinkListPtr
*/
- static KeyLinkListPtr GetKeysCopy(const KeyLinkListPtr& keys);
+ KeyLinkListPtr GetKeysCopy(const KeyLinkListPtr& keys);
private:
/**
@@ -104,6 +113,24 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
*/
GpgContext& ctx_ =
GpgContext::GetInstance(SingletonFunctionObject::GetChannel());
+
+ /**
+ * @brief shared mutex for the keys cache
+ *
+ */
+ mutable std::mutex ctx_mutex_;
+
+ /**
+ * @brief cache the keys with key fpr
+ *
+ */
+ std::map<std::string, GpgKey> keys_cache_;
+
+ /**
+ * @brief shared mutex for the keys cache
+ *
+ */
+ mutable std::mutex keys_cache_mutex_;
};
} // namespace GpgFrontend
diff --git a/src/core/thread/CtxCheckThread.cpp b/src/core/thread/CtxCheckThread.cpp
index 77571dfd..edec8855 100644
--- a/src/core/thread/CtxCheckThread.cpp
+++ b/src/core/thread/CtxCheckThread.cpp
@@ -48,7 +48,7 @@ void GpgFrontend::CtxCheckThread::run() {
if (!GpgContext::GetInstance().good()) {
emit SignalGnupgNotInstall();
}
- // Try fetching key
+ // Try flushing key cache
else
- GpgFrontend::GpgKeyGetter::GetInstance().FetchKey();
+ GpgFrontend::GpgKeyGetter::GetInstance().FlushKeyCache();
}
diff --git a/src/main.cpp b/src/main.cpp
index 51d977b2..35204fd0 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -165,8 +165,8 @@ int main(int argc, char* argv[]) {
&QEventLoop::quit);
loop.exec();
- // init ui logging
- GpgFrontend::UI::init_logging();
+ // init ui library
+ GpgFrontend::UI::InitGpgFrontendUI();
/**
* internationalisation. loop to restart main window
diff --git a/src/ui/GpgFrontendUIInit.cpp b/src/ui/GpgFrontendUIInit.cpp
index 82746551..49f16ec5 100644
--- a/src/ui/GpgFrontendUIInit.cpp
+++ b/src/ui/GpgFrontendUIInit.cpp
@@ -28,6 +28,8 @@
#include "GpgFrontendUIInit.h"
+#include "SignalStation.h"
+#include "UserInterfaceUtils.h"
#include "core/function/GlobalSettingStation.h"
// init easyloggingpp library
@@ -35,6 +37,14 @@ INITIALIZE_EASYLOGGINGPP
namespace GpgFrontend::UI {
+extern void init_logging();
+
+void InitGpgFrontendUI() {
+ init_logging();
+ SignalStation::GetInstance();
+ CommonUtils::GetInstance();
+}
+
void init_logging() {
using namespace boost::posix_time;
using namespace boost::gregorian;
diff --git a/src/ui/GpgFrontendUIInit.h b/src/ui/GpgFrontendUIInit.h
index ddb791c3..6518256b 100644
--- a/src/ui/GpgFrontendUIInit.h
+++ b/src/ui/GpgFrontendUIInit.h
@@ -34,9 +34,10 @@
namespace GpgFrontend::UI {
/**
- * @brief
+ * @brief init the UI library
+ *
*/
-void init_logging();
+void InitGpgFrontendUI();
}; // namespace GpgFrontend::UI
diff --git a/src/ui/SignalStation.cpp b/src/ui/SignalStation.cpp
index 045b63f5..c1f1238f 100644
--- a/src/ui/SignalStation.cpp
+++ b/src/ui/SignalStation.cpp
@@ -28,6 +28,8 @@
#include "SignalStation.h"
+#include "UserInterfaceUtils.h"
+
namespace GpgFrontend::UI {
std::unique_ptr<SignalStation> SignalStation::_instance = nullptr;
diff --git a/src/ui/SignalStation.h b/src/ui/SignalStation.h
index dbf978be..eb7b3f74 100644
--- a/src/ui/SignalStation.h
+++ b/src/ui/SignalStation.h
@@ -60,6 +60,12 @@ class SignalStation : public QObject {
/**
* @brief
*
+ */
+ void SignalKeyDatabaseRefreshDone();
+
+ /**
+ * @brief
+ *
* @param text
* @param verify_label_status
*/
diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp
index 52b7eb28..9859ff65 100644
--- a/src/ui/UserInterfaceUtils.cpp
+++ b/src/ui/UserInterfaceUtils.cpp
@@ -29,10 +29,13 @@
#include "UserInterfaceUtils.h"
#include <utility>
+#include <vector>
#include "core/common/CoreCommonUtil.h"
#include "core/function/FileOperator.h"
#include "core/function/GlobalSettingStation.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "easylogging++.h"
#include "ui/SignalStation.h"
#include "ui/dialog/WaitingDialog.h"
#include "ui/widgets/TextEdit.h"
@@ -129,11 +132,24 @@ CommonUtils *CommonUtils::GetInstance() {
}
CommonUtils::CommonUtils() : QWidget(nullptr) {
+ LOG(INFO) << "common utils created";
+
connect(CoreCommonUtil::GetInstance(), &CoreCommonUtil::SignalGnupgNotInstall,
this, &CommonUtils::SignalGnupgNotInstall);
connect(this, &CommonUtils::SignalKeyStatusUpdated,
SignalStation::GetInstance(),
&SignalStation::SignalKeyDatabaseRefresh);
+ connect(this, &CommonUtils::SignalKeyDatabaseRefreshDone,
+ SignalStation::GetInstance(),
+ &SignalStation::SignalKeyDatabaseRefreshDone);
+
+ // directly connect to SignalKeyStatusUpdated
+ // to avoid the delay of signal emitting
+ // when the key database is refreshed
+ connect(SignalStation::GetInstance(),
+ &SignalStation::SignalKeyDatabaseRefresh, this,
+ &CommonUtils::slot_update_key_status);
+
connect(this, &CommonUtils::SignalGnupgNotInstall, this, []() {
QMessageBox::critical(
nullptr, _("ENV Loading Failed"),
@@ -227,8 +243,7 @@ void CommonUtils::SlotExecuteGpgCommand(
}
void CommonUtils::SlotImportKeyFromKeyServer(
- const KeyIdArgsList &key_ids,
- const ImportCallbackFunctiopn &callback) {
+ const KeyIdArgsList &key_ids, const ImportCallbackFunctiopn &callback) {
std::string target_keyserver;
if (target_keyserver.empty()) {
try {
@@ -248,71 +263,95 @@ void CommonUtils::SlotImportKeyFromKeyServer(
}
}
- auto thread =
- QThread::create([target_keyserver, key_ids, callback]() {
- QUrl target_keyserver_url(target_keyserver.c_str());
-
- auto network_manager = std::make_unique<QNetworkAccessManager>();
- // LOOP
- decltype(key_ids.size()) current_index = 1, all_index = key_ids.size();
- for (const auto &key_id : key_ids) {
- // New Req Url
- QUrl req_url(target_keyserver_url.scheme() + "://" +
- target_keyserver_url.host() +
- "/pks/lookup?op=get&search=0x" + key_id.c_str() +
- "&options=mr");
-
- LOG(INFO) << "request url" << req_url.toString().toStdString();
-
- // Waiting for reply
- QNetworkReply *reply = network_manager->get(QNetworkRequest(req_url));
- QEventLoop loop;
- connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
- loop.exec();
-
- // Get Data
- auto key_data = reply->readAll();
- auto key_data_ptr =
- std::make_unique<ByteArray>(key_data.data(), key_data.size());
-
- // Detect status
- std::string status;
- auto error = reply->error();
- if (error != QNetworkReply::NoError) {
- switch (error) {
- case QNetworkReply::ContentNotFoundError:
- status = _("Key Not Found");
- break;
- case QNetworkReply::TimeoutError:
- status = _("Timeout");
- break;
- case QNetworkReply::HostNotFoundError:
- status = _("Key Server Not Found");
- break;
- default:
- status = _("Connection Error");
- }
- }
-
- reply->deleteLater();
-
- // Try importing
- GpgImportInformation result =
- GpgKeyImportExporter::GetInstance()
- .ImportKey(std::move(key_data_ptr));
-
- if (result.imported == 1) {
- status = _("The key has been updated");
- } else {
- status = _("No need to update the key");
- }
- callback(key_id, status, current_index, all_index);
- current_index++;
+ auto thread = QThread::create([target_keyserver, key_ids, callback]() {
+ QUrl target_keyserver_url(target_keyserver.c_str());
+
+ auto network_manager = std::make_unique<QNetworkAccessManager>();
+ // LOOP
+ decltype(key_ids.size()) current_index = 1, all_index = key_ids.size();
+ for (const auto &key_id : key_ids) {
+ // New Req Url
+ QUrl req_url(
+ target_keyserver_url.scheme() + "://" + target_keyserver_url.host() +
+ "/pks/lookup?op=get&search=0x" + key_id.c_str() + "&options=mr");
+
+ LOG(INFO) << "request url" << req_url.toString().toStdString();
+
+ // Waiting for reply
+ QNetworkReply *reply = network_manager->get(QNetworkRequest(req_url));
+ QEventLoop loop;
+ connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+ loop.exec();
+
+ // Get Data
+ auto key_data = reply->readAll();
+ auto key_data_ptr =
+ std::make_unique<ByteArray>(key_data.data(), key_data.size());
+
+ // Detect status
+ std::string status;
+ auto error = reply->error();
+ if (error != QNetworkReply::NoError) {
+ switch (error) {
+ case QNetworkReply::ContentNotFoundError:
+ status = _("Key Not Found");
+ break;
+ case QNetworkReply::TimeoutError:
+ status = _("Timeout");
+ break;
+ case QNetworkReply::HostNotFoundError:
+ status = _("Key Server Not Found");
+ break;
+ default:
+ status = _("Connection Error");
}
- });
+ }
+
+ reply->deleteLater();
+
+ // Try importing
+ GpgImportInformation result =
+ GpgKeyImportExporter::GetInstance().ImportKey(
+ std::move(key_data_ptr));
+
+ if (result.imported == 1) {
+ status = _("The key has been updated");
+ } else {
+ status = _("No need to update the key");
+ }
+ callback(key_id, status, current_index, all_index);
+ current_index++;
+ }
+ });
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
+void CommonUtils::slot_update_key_status() {
+ LOG(INFO) << "called";
+
+ std::vector<QThread *> threads;
+
+ // flush key cache for all GpgKeyGetter Intances.
+ for (const auto &channel_id : GpgKeyGetter::GetAllChannelId()) {
+ // multi threading
+ auto *thread = QThread::create([channel_id]() {
+ LOG(INFO) << "thread start"
+ << "channel:" << channel_id;
+ GpgKeyGetter::GetInstance(channel_id).FlushKeyCache();
+ });
+ thread->start();
+ threads.push_back(thread);
+ }
+
+ for (auto *thread : threads) {
+ thread->wait();
+ thread->deleteLater();
+ }
+
+ emit SignalKeyDatabaseRefreshDone();
+ LOG(INFO) << "finished";
+}
+
} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h
index a7f20f10..85ef012b 100644
--- a/src/ui/UserInterfaceUtils.h
+++ b/src/ui/UserInterfaceUtils.h
@@ -59,8 +59,8 @@ void show_verify_details(QWidget* parent, InfoBoardWidget* info_board,
* @param parent
* @param verify_res
*/
-void import_unknown_key_from_keyserver(QWidget* parent,
- const GpgVerifyResultAnalyse& verify_res);
+void import_unknown_key_from_keyserver(
+ QWidget* parent, const GpgVerifyResultAnalyse& verify_res);
/**
* @brief
@@ -144,6 +144,12 @@ class CommonUtils : public QWidget {
*/
void SignalGnupgNotInstall();
+ /**
+ * @brief emit when the key database is refreshed
+ *
+ */
+ void SignalKeyDatabaseRefreshDone();
+
public slots:
/**
* @brief
@@ -195,6 +201,14 @@ class CommonUtils : public QWidget {
const QStringList& arguments,
const std::function<void(QProcess*)>& interact_func);
+ private slots:
+
+ /**
+ * @brief update the key status when signal is emitted
+ *
+ */
+ void slot_update_key_status();
+
private:
static std::unique_ptr<CommonUtils> instance_; ///<
};
diff --git a/src/ui/import_export/KeyServerImportDialog.cpp b/src/ui/import_export/KeyServerImportDialog.cpp
index c35e3db7..2d30c021 100644
--- a/src/ui/import_export/KeyServerImportDialog.cpp
+++ b/src/ui/import_export/KeyServerImportDialog.cpp
@@ -30,9 +30,9 @@
#include <utility>
+#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyImportExporter.h"
#include "ui/SignalStation.h"
-#include "core/function/GlobalSettingStation.h"
namespace GpgFrontend::UI {
@@ -47,12 +47,15 @@ KeyServerImportDialog::KeyServerImportDialog(bool automatic, QWidget* parent)
// Buttons
close_button_ = new QPushButton(_("Close"));
- connect(close_button_, &QPushButton::clicked, this, &KeyServerImportDialog::close);
+ connect(close_button_, &QPushButton::clicked, this,
+ &KeyServerImportDialog::close);
import_button_ = new QPushButton(_("Import ALL"));
- connect(import_button_, &QPushButton::clicked, this, &KeyServerImportDialog::slot_import);
+ connect(import_button_, &QPushButton::clicked, this,
+ &KeyServerImportDialog::slot_import);
import_button_->setDisabled(true);
search_button_ = new QPushButton(_("Search"));
- connect(search_button_, &QPushButton::clicked, this, &KeyServerImportDialog::slot_search);
+ connect(search_button_, &QPushButton::clicked, this,
+ &KeyServerImportDialog::slot_search);
// Line edits for search string
search_label_ = new QLabel(QString(_("Search String")) + _(": "));
@@ -139,11 +142,13 @@ KeyServerImportDialog::KeyServerImportDialog(bool automatic, QWidget* parent)
this->setModal(true);
- connect(this, &KeyServerImportDialog::SignalKeyImported, SignalStation::GetInstance(),
+ connect(this, &KeyServerImportDialog::SignalKeyImported,
+ SignalStation::GetInstance(),
&SignalStation::SignalKeyDatabaseRefresh);
// save window pos and size to configure file
- connect(this, &KeyServerImportDialog::finished, this, &KeyServerImportDialog::slot_save_window_state);
+ connect(this, &KeyServerImportDialog::finished, this,
+ &KeyServerImportDialog::slot_save_window_state);
}
QComboBox* KeyServerImportDialog::create_comboBox() {
@@ -222,7 +227,8 @@ void KeyServerImportDialog::slot_search() {
QNetworkReply* reply =
network_access_manager_->get(QNetworkRequest(url_from_remote));
- connect(reply, &QNetworkReply::finished, this, &KeyServerImportDialog::slot_search_finished);
+ connect(reply, &QNetworkReply::finished, this,
+ &KeyServerImportDialog::slot_search_finished);
set_loading(true);
this->search_button_->setDisabled(true);
diff --git a/src/ui/key_generate/KeygenDialog.cpp b/src/ui/key_generate/KeygenDialog.cpp
index 6df0bcf0..676539c7 100644
--- a/src/ui/key_generate/KeygenDialog.cpp
+++ b/src/ui/key_generate/KeygenDialog.cpp
@@ -28,10 +28,10 @@
#include "ui/key_generate/KeygenDialog.h"
-#include "dialog/WaitingDialog.h"
+#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyOpera.h"
+#include "dialog/WaitingDialog.h"
#include "ui/SignalStation.h"
-#include "core/function/GlobalSettingStation.h"
namespace GpgFrontend::UI {
@@ -144,15 +144,19 @@ void KeyGenDialog::slot_key_gen_accept() {
dialog->close();
+ LOG(INFO) << "generate done";
+
if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) {
- auto* msg_box = new QMessageBox(nullptr);
+ auto* msg_box = new QMessageBox((QWidget*)this->parent());
msg_box->setAttribute(Qt::WA_DeleteOnClose);
msg_box->setStandardButtons(QMessageBox::Ok);
msg_box->setWindowTitle(_("Success"));
msg_box->setText(_("The new key pair has been generated."));
- msg_box->setModal(false);
+ msg_box->setModal(true);
msg_box->open();
+ LOG(INFO) << "generate success";
+
emit SignalKeyGenerated();
this->close();
} else {
diff --git a/src/ui/key_generate/SubkeyGenerateDialog.cpp b/src/ui/key_generate/SubkeyGenerateDialog.cpp
index 4eb041aa..451c6521 100644
--- a/src/ui/key_generate/SubkeyGenerateDialog.cpp
+++ b/src/ui/key_generate/SubkeyGenerateDialog.cpp
@@ -26,11 +26,11 @@
#include "ui/key_generate/SubkeyGenerateDialog.h"
-#include "dialog/WaitingDialog.h"
+#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/function/gpg/GpgKeyOpera.h"
+#include "dialog/WaitingDialog.h"
#include "ui/SignalStation.h"
-#include "core/function/GlobalSettingStation.h"
namespace GpgFrontend::UI {
@@ -73,7 +73,8 @@ SubkeyGenerateDialog::SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent)
this->setLayout(vbox2);
this->setModal(true);
- connect(this, &SubkeyGenerateDialog::SignalSubKeyGenerated, SignalStation::GetInstance(),
+ connect(this, &SubkeyGenerateDialog::SignalSubKeyGenerated,
+ SignalStation::GetInstance(),
&SignalStation::SignalKeyDatabaseRefresh);
set_signal_slot();
@@ -156,8 +157,10 @@ QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() {
}
void SubkeyGenerateDialog::set_signal_slot() {
- connect(button_box_, &QDialogButtonBox::accepted, this, &SubkeyGenerateDialog::slot_key_gen_accept);
- connect(button_box_, &QDialogButtonBox::rejected, this, &SubkeyGenerateDialog::reject);
+ connect(button_box_, &QDialogButtonBox::accepted, this,
+ &SubkeyGenerateDialog::slot_key_gen_accept);
+ connect(button_box_, &QDialogButtonBox::rejected, this,
+ &SubkeyGenerateDialog::reject);
connect(expire_check_box_, &QCheckBox::stateChanged, this,
&SubkeyGenerateDialog::slot_expire_box_changed);
@@ -171,8 +174,8 @@ void SubkeyGenerateDialog::set_signal_slot() {
connect(key_usage_check_boxes_[3], &QCheckBox::stateChanged, this,
&SubkeyGenerateDialog::slot_authentication_box_changed);
- connect(key_type_combo_box_, qOverload<int>(&QComboBox::currentIndexChanged), this,
- &SubkeyGenerateDialog::slot_activated_key_type);
+ connect(key_type_combo_box_, qOverload<int>(&QComboBox::currentIndexChanged),
+ this, &SubkeyGenerateDialog::slot_activated_key_type);
}
void SubkeyGenerateDialog::slot_expire_box_changed() {
@@ -271,12 +274,12 @@ void SubkeyGenerateDialog::slot_key_gen_accept() {
dialog->close();
if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) {
- auto* msg_box = new QMessageBox(nullptr);
+ auto* msg_box = new QMessageBox((QWidget*)this->parent());
msg_box->setAttribute(Qt::WA_DeleteOnClose);
msg_box->setStandardButtons(QMessageBox::Ok);
msg_box->setWindowTitle(_("Success"));
msg_box->setText(_("The new subkey has been generated."));
- msg_box->setModal(false);
+ msg_box->setModal(true);
msg_box->open();
emit SignalSubKeyGenerated();
diff --git a/src/ui/keypair_details/KeyPairDetailTab.cpp b/src/ui/keypair_details/KeyPairDetailTab.cpp
index 6174e67b..76f316e9 100644
--- a/src/ui/keypair_details/KeyPairDetailTab.cpp
+++ b/src/ui/keypair_details/KeyPairDetailTab.cpp
@@ -26,9 +26,9 @@
#include "ui/keypair_details/KeyPairDetailTab.h"
-#include "dialog/WaitingDialog.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/function/gpg/GpgKeyImportExporter.h"
+#include "dialog/WaitingDialog.h"
#include "ui/SignalStation.h"
namespace GpgFrontend::UI {
@@ -152,7 +152,8 @@ KeyPairDetailTab::KeyPairDetailTab(const std::string& key_id, QWidget* parent)
mvbox->setContentsMargins(0, 0, 0, 0);
// when key database updated
- connect(SignalStation::GetInstance(), &SignalStation::SignalKeyDatabaseRefresh, this,
+ connect(SignalStation::GetInstance(),
+ &SignalStation::SignalKeyDatabaseRefreshDone, this,
&KeyPairDetailTab::slot_refresh_key);
slot_refresh_key_info();
@@ -169,11 +170,12 @@ void KeyPairDetailTab::slot_copy_fingerprint() {
void KeyPairDetailTab::slot_refresh_key_info() {
// Show the situation that primary key not exists.
- primary_key_exist_var_label_->setText(key_.IsHasMasterKey() ? _("Exists")
- : _("Not Exists"));
+ primary_key_exist_var_label_->setText(
+ key_.IsHasMasterKey() ? _("Exists") : _("Not Exists"));
if (!key_.IsHasMasterKey()) {
auto palette_expired = primary_key_exist_var_label_->palette();
- palette_expired.setColor(primary_key_exist_var_label_->foregroundRole(), Qt::red);
+ palette_expired.setColor(primary_key_exist_var_label_->foregroundRole(),
+ Qt::red);
primary_key_exist_var_label_->setPalette(palette_expired);
} else {
auto palette_valid = primary_key_exist_var_label_->palette();
diff --git a/src/ui/keypair_details/KeyPairSubkeyTab.cpp b/src/ui/keypair_details/KeyPairSubkeyTab.cpp
index 067ce110..46de550c 100644
--- a/src/ui/keypair_details/KeyPairSubkeyTab.cpp
+++ b/src/ui/keypair_details/KeyPairSubkeyTab.cpp
@@ -124,10 +124,10 @@ KeyPairSubkeyTab::KeyPairSubkeyTab(const std::string& key_id, QWidget* parent)
// key database refresh signal
connect(SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh, this,
+ &SignalStation::SignalKeyDatabaseRefreshDone, this,
&KeyPairSubkeyTab::slot_refresh_key_info);
connect(SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh, this,
+ &SignalStation::SignalKeyDatabaseRefreshDone, this,
&KeyPairSubkeyTab::slot_refresh_subkey_list);
baseLayout->setContentsMargins(0, 0, 0, 0);
diff --git a/src/ui/keypair_details/KeyPairUIDTab.cpp b/src/ui/keypair_details/KeyPairUIDTab.cpp
index 81d34684..4cc835a8 100644
--- a/src/ui/keypair_details/KeyPairUIDTab.cpp
+++ b/src/ui/keypair_details/KeyPairUIDTab.cpp
@@ -102,7 +102,7 @@ KeyPairUIDTab::KeyPairUIDTab(const std::string& key_id, QWidget* parent)
// Key Database Refresh
connect(SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh, this,
+ &SignalStation::SignalKeyDatabaseRefreshDone, this,
&KeyPairUIDTab::slot_refresh_key);
connect(this, &KeyPairUIDTab::SignalUpdateUIDInfo,
@@ -419,7 +419,7 @@ void KeyPairUIDTab::slot_set_primary_uid() {
if (ret == QMessageBox::Yes) {
if (!GpgUIDOperator::GetInstance().SetPrimaryUID(m_key_,
- selected_uids->front())) {
+ selected_uids->front())) {
QMessageBox::critical(nullptr, _("Operation Failed"),
_("An error occurred during the operation."));
} else {
diff --git a/src/ui/keypair_details/KeySetExpireDateDialog.cpp b/src/ui/keypair_details/KeySetExpireDateDialog.cpp
index 79325e8b..785dce14 100644
--- a/src/ui/keypair_details/KeySetExpireDateDialog.cpp
+++ b/src/ui/keypair_details/KeySetExpireDateDialog.cpp
@@ -30,10 +30,10 @@
#include <utility>
+#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/function/gpg/GpgKeyOpera.h"
#include "ui/SignalStation.h"
-#include "core/function/GlobalSettingStation.h"
#include "ui_ModifiedExpirationDateTime.h"
namespace GpgFrontend::UI {
@@ -72,21 +72,20 @@ void KeySetExpireDateDialog::slot_confirm() {
auto err = GpgKeyOpera::GetInstance().SetExpire(m_key_, m_subkey_, expires);
if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) {
- auto* msg_box = new QMessageBox(nullptr);
+ auto* msg_box = new QMessageBox((QWidget*)this->parent());
msg_box->setAttribute(Qt::WA_DeleteOnClose);
msg_box->setStandardButtons(QMessageBox::Ok);
msg_box->setWindowTitle(_("Success"));
msg_box->setText(_("The expire date of the key pair has been updated."));
- msg_box->setModal(false);
+ msg_box->setModal(true);
msg_box->open();
emit SignalKeyExpireDateUpdated();
+ this->close();
} else {
QMessageBox::critical(this, _("Failure"), _(gpgme_strerror(err)));
}
-
- this->close();
}
void KeySetExpireDateDialog::init() {
@@ -113,8 +112,11 @@ void KeySetExpireDateDialog::init() {
ui_->dateEdit->setMaximumDateTime(max_date_time);
ui_->dateEdit->setMinimumDateTime(min_date_time);
- ui_->dateEdit->setDateTime(max_date_time);
- ui_->timeEdit->setDateTime(max_date_time);
+ // set default date time to expire date time
+ auto current_expire_time =
+ QDateTime::fromTime_t(to_time_t(m_key_.GetExpireTime()));
+ ui_->dateEdit->setDateTime(current_expire_time);
+ ui_->timeEdit->setDateTime(current_expire_time);
connect(ui_->noExpirationCheckBox, &QCheckBox::stateChanged, this,
&KeySetExpireDateDialog::slot_non_expired_checked);
diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp
index 0a322f6a..a1db4d61 100644
--- a/src/ui/main_window/MainWindowSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowSlotFunction.cpp
@@ -27,7 +27,6 @@
*/
#include "MainWindow.h"
-
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgBasicOperator.h"
#include "core/function/gpg/GpgKeyGetter.h"
@@ -74,7 +73,7 @@ void MainWindow::slot_encrypt() {
}
});
} else {
- auto key_getter = GpgFrontend::GpgKeyGetter::GetInstance();
+ auto& key_getter = GpgFrontend::GpgKeyGetter::GetInstance();
auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
for (const auto& key : *keys) {
if (!key.IsHasActualEncryptionCapability()) {
diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp
index 6292c1a9..237576ad 100644
--- a/src/ui/widgets/KeyList.cpp
+++ b/src/ui/widgets/KeyList.cpp
@@ -29,6 +29,7 @@
#include "ui/widgets/KeyList.h"
#include <boost/format.hpp>
+#include <mutex>
#include <utility>
#include "core/GpgCoreInit.h"
@@ -63,7 +64,7 @@ void KeyList::init() {
connect(this, &KeyList::SignalRefreshDatabase, SignalStation::GetInstance(),
&SignalStation::SignalKeyDatabaseRefresh);
connect(SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh, this,
+ &SignalStation::SignalKeyDatabaseRefreshDone, this,
&KeyList::SlotRefresh);
connect(ui_->refreshKeyListButton, &QPushButton::clicked, this,
&KeyList::SlotRefresh);
@@ -154,19 +155,15 @@ void KeyList::AddListGroupTab(
}
void KeyList::SlotRefresh() {
- LOG(INFO) << _("Called");
- emit SignalRefreshStatusBar(_("Refreshing Key List..."), 3000);
- auto thread = QThread::create([this]() {
- std::lock_guard<std::mutex> guard(buffered_key_list_mutex_);
- buffered_keys_list_ = nullptr;
- // buffered keys list
- buffered_keys_list_ = GpgKeyGetter::GetInstance().FetchKey();
- });
- connect(thread, &QThread::finished, this, &KeyList::slot_refresh_ui);
- connect(thread, &QThread::finished, thread, &QThread::deleteLater);
+ LOG(INFO) << _("Called") << "address" << this;
+
ui_->refreshKeyListButton->setDisabled(true);
ui_->syncButton->setDisabled(true);
- thread->start();
+
+ emit SignalRefreshStatusBar(_("Refreshing Key List..."), 3000);
+
+ this->buffered_keys_list_ = GpgKeyGetter::GetInstance().FetchKey();
+ this->slot_refresh_ui();
}
KeyIdArgsListPtr KeyList::GetChecked(const KeyTable& key_table) {
@@ -424,7 +421,8 @@ void KeyList::slot_refresh_ui() {
if (buffered_keys_list_ != nullptr) {
std::lock_guard<std::mutex> guard(buffered_key_list_mutex_);
for (auto& key_table : m_key_tables_) {
- key_table.Refresh(GpgKeyGetter::GetKeysCopy(buffered_keys_list_));
+ key_table.Refresh(
+ GpgKeyGetter::GetInstance().GetKeysCopy(buffered_keys_list_));
}
}
emit SignalRefreshStatusBar(_("Key List Refreshed."), 1000);