diff options
author | saturneric <[email protected]> | 2024-06-28 21:05:25 +0000 |
---|---|---|
committer | saturneric <[email protected]> | 2024-06-28 21:05:25 +0000 |
commit | d0333031c1f593998a501eff866f091ff2f036be (patch) | |
tree | 707a597c25b488955572601e87ba9e379df0a6ed | |
parent | feat: rewrite key list structure and logic (diff) | |
download | GpgFrontend-d0333031c1f593998a501eff866f091ff2f036be.tar.gz GpgFrontend-d0333031c1f593998a501eff866f091ff2f036be.zip |
feat: user can select shown columns at key table
-rw-r--r-- | gpgfrontend.qrc | 1 | ||||
-rw-r--r-- | resource/lfs/icons/filter.png | bin | 0 -> 4328 bytes | |||
-rw-r--r-- | src/core/model/GpgKeyTableModel.cpp | 25 | ||||
-rw-r--r-- | src/core/model/GpgKeyTableModel.h | 67 | ||||
-rw-r--r-- | src/core/model/GpgKeyTableProxyModel.cpp | 44 | ||||
-rw-r--r-- | src/core/model/GpgKeyTableProxyModel.h | 12 | ||||
-rw-r--r-- | src/ui/dialog/SignersPicker.cpp | 22 | ||||
-rw-r--r-- | src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp | 9 | ||||
-rw-r--r-- | src/ui/main_window/KeyMgmt.cpp | 40 | ||||
-rw-r--r-- | src/ui/main_window/MainWindow.cpp | 11 | ||||
-rw-r--r-- | src/ui/main_window/MainWindowUI.cpp | 26 | ||||
-rw-r--r-- | src/ui/widgets/HelpPage.cpp | 7 | ||||
-rw-r--r-- | src/ui/widgets/KeyList.cpp | 226 | ||||
-rw-r--r-- | src/ui/widgets/KeyList.h | 183 | ||||
-rw-r--r-- | src/ui/widgets/KeyTable.cpp | 136 | ||||
-rw-r--r-- | src/ui/widgets/KeyTable.h | 176 | ||||
-rw-r--r-- | ui/KeyList.ui | 17 |
17 files changed, 640 insertions, 362 deletions
diff --git a/gpgfrontend.qrc b/gpgfrontend.qrc index e311ed6a..a04c1819 100644 --- a/gpgfrontend.qrc +++ b/gpgfrontend.qrc @@ -97,6 +97,7 @@ <file alias="key.png">resource/lfs/icons/key.png</file> <file alias="stairs.png">resource/lfs/icons/stairs.png</file> <file alias="detail.png">resource/lfs/icons/detail.png</file> + <file alias="filter.png">resource/lfs/icons/filter.png</file> </qresource> <qresource prefix="/test/key"> <file alias="pv1.key">resource/lfs/test/data/pv1.key</file> diff --git a/resource/lfs/icons/filter.png b/resource/lfs/icons/filter.png Binary files differnew file mode 100644 index 00000000..a8480b48 --- /dev/null +++ b/resource/lfs/icons/filter.png diff --git a/src/core/model/GpgKeyTableModel.cpp b/src/core/model/GpgKeyTableModel.cpp index cff619cd..4d542c3f 100644 --- a/src/core/model/GpgKeyTableModel.cpp +++ b/src/core/model/GpgKeyTableModel.cpp @@ -36,9 +36,18 @@ namespace GpgFrontend { GpgKeyTableModel::GpgKeyTableModel(GpgKeyList keys, QObject *parent) : QAbstractTableModel(parent), buffered_keys_(keys), - column_headers_({tr("Select"), tr("Type"), tr("Name"), - tr("Email Address"), tr("Usage"), tr("Trust"), - tr("Key ID"), tr("Finger Print")}), + column_headers_({ + tr("Select"), + tr("Type"), + tr("Name"), + tr("Email Address"), + tr("Usage"), + tr("Trust"), + tr("Key ID"), + tr("Create Date"), + tr("Algorithm"), + tr("Subkey(s)"), + }), key_check_state_(buffered_keys_.size()) {} auto GpgKeyTableModel::rowCount(const QModelIndex & /*parent*/) const -> int { @@ -47,7 +56,7 @@ auto GpgKeyTableModel::rowCount(const QModelIndex & /*parent*/) const -> int { auto GpgKeyTableModel::columnCount(const QModelIndex & /*parent*/) const -> int { - return 8; + return 10; } auto GpgKeyTableModel::data(const QModelIndex &index, int role) const @@ -99,7 +108,13 @@ auto GpgKeyTableModel::data(const QModelIndex &index, int role) const return key.GetId(); } case 7: { - return key.GetFingerprint(); + return key.GetCreateTime(); + } + case 8: { + return key.GetKeyAlgo(); + } + case 9: { + return static_cast<int>(key.GetSubKeys()->size()); } default: return {}; diff --git a/src/core/model/GpgKeyTableModel.h b/src/core/model/GpgKeyTableModel.h index 047820a5..78289b41 100644 --- a/src/core/model/GpgKeyTableModel.h +++ b/src/core/model/GpgKeyTableModel.h @@ -38,58 +38,73 @@ namespace GpgFrontend { enum class GpgKeyTableColumn : unsigned int { - kNone = 0, - kType = 1 << 0, - kName = 1 << 1, - kEmailAddress = 1 << 2, - kUsage = 1 << 3, - kValidity = 1 << 4, - kFingerPrint = 1 << 5, - kKeyId = 1 << 6, - kOwnerTrust = 1 << 7, - kAll = ~0u + kNONE = 0, + kTYPE = 1 << 0, + kNAME = 1 << 1, + kEMAIL_ADDRESS = 1 << 2, + kUSAGE = 1 << 3, + kKEY_ID = 1 << 4, + kOWNER_TRUST = 1 << 5, + kCREATE_DATE = 1 << 6, + kALGO = 1 << 7, + kSUBKEYS_NUMBER = 1 << 8, + kALL = ~0U }; -inline GpgKeyTableColumn operator|(GpgKeyTableColumn lhs, - GpgKeyTableColumn rhs) { +inline auto operator|(GpgKeyTableColumn lhs, GpgKeyTableColumn rhs) + -> GpgKeyTableColumn { using T = std::underlying_type_t<GpgKeyTableColumn>; return static_cast<GpgKeyTableColumn>(static_cast<T>(lhs) | static_cast<T>(rhs)); } -inline GpgKeyTableColumn &operator|=(GpgKeyTableColumn &lhs, - GpgKeyTableColumn rhs) { +inline auto operator|=(GpgKeyTableColumn &lhs, GpgKeyTableColumn rhs) + -> GpgKeyTableColumn & { lhs = lhs | rhs; return lhs; } -inline bool operator&(GpgKeyTableColumn lhs, GpgKeyTableColumn rhs) { +inline auto operator&(GpgKeyTableColumn lhs, GpgKeyTableColumn rhs) + -> GpgKeyTableColumn { using T = std::underlying_type_t<GpgKeyTableColumn>; - return (static_cast<T>(lhs) & static_cast<T>(rhs)) != 0; + return static_cast<GpgKeyTableColumn>(static_cast<T>(lhs) & + static_cast<T>(rhs)); +} + +inline auto operator&=(GpgKeyTableColumn &lhs, GpgKeyTableColumn rhs) + -> GpgKeyTableColumn & { + lhs = lhs & rhs; + return lhs; +} + +inline auto operator~(GpgKeyTableColumn hs) -> GpgKeyTableColumn { + using T = std::underlying_type_t<GpgKeyTableColumn>; + return static_cast<GpgKeyTableColumn>(~static_cast<T>(hs)); } enum class GpgKeyTableDisplayMode : unsigned int { - kNone = 0, - kPublicKey = 1 << 0, - kPrivateKey = 1 << 1, - kFavorites = 1 << 2, - kAll = ~0u + kNONE = 0, + kPUBLIC_KEY = 1 << 0, + kPRIVATE_KEY = 1 << 1, + kFAVORITES = 1 << 2, + kALL = ~0U }; -inline GpgKeyTableDisplayMode operator|(GpgKeyTableDisplayMode lhs, - GpgKeyTableDisplayMode rhs) { +inline auto operator|(GpgKeyTableDisplayMode lhs, GpgKeyTableDisplayMode rhs) + -> GpgKeyTableDisplayMode { using T = std::underlying_type_t<GpgKeyTableDisplayMode>; return static_cast<GpgKeyTableDisplayMode>(static_cast<T>(lhs) | static_cast<T>(rhs)); } -inline GpgKeyTableDisplayMode &operator|=(GpgKeyTableDisplayMode &lhs, - GpgKeyTableDisplayMode rhs) { +inline auto operator|=(GpgKeyTableDisplayMode &lhs, GpgKeyTableDisplayMode rhs) + -> GpgKeyTableDisplayMode & { lhs = lhs | rhs; return lhs; } -inline bool operator&(GpgKeyTableDisplayMode lhs, GpgKeyTableDisplayMode rhs) { +inline auto operator&(GpgKeyTableDisplayMode lhs, GpgKeyTableDisplayMode rhs) + -> bool { using T = std::underlying_type_t<GpgKeyTableDisplayMode>; return (static_cast<T>(lhs) & static_cast<T>(rhs)) != 0; } diff --git a/src/core/model/GpgKeyTableProxyModel.cpp b/src/core/model/GpgKeyTableProxyModel.cpp index 7fdedff5..0ecd000f 100644 --- a/src/core/model/GpgKeyTableProxyModel.cpp +++ b/src/core/model/GpgKeyTableProxyModel.cpp @@ -48,6 +48,8 @@ GpgKeyTableProxyModel::GpgKeyTableProxyModel( connect(this, &GpgKeyTableProxyModel::SignalFavoritesChanged, this, &GpgKeyTableProxyModel::slot_update_favorites); + connect(this, &GpgKeyTableProxyModel::SignalColumnTypeChange, this, + &GpgKeyTableProxyModel::slot_update_column_type); emit SignalFavoritesChanged(); } @@ -58,19 +60,19 @@ auto GpgKeyTableProxyModel::filterAcceptsRow( auto key_id = sourceModel()->data(index).toString(); auto key = GpgKeyGetter::GetInstance().GetKey(key_id); - if (!(display_mode_ & GpgKeyTableDisplayMode::kPrivateKey) && + if (!(display_mode_ & GpgKeyTableDisplayMode::kPRIVATE_KEY) && key.IsPrivateKey()) { return false; } - if (!(display_mode_ & GpgKeyTableDisplayMode::kPublicKey) && + if (!(display_mode_ & GpgKeyTableDisplayMode::kPUBLIC_KEY) && !key.IsPrivateKey()) { return false; } if (!custom_filter_(key)) return false; - if (display_mode_ & GpgKeyTableDisplayMode::kFavorites && + if (display_mode_ & GpgKeyTableDisplayMode::kFAVORITES && !favorite_fingerprints_.contains(key.GetFingerprint())) { return false; } @@ -97,25 +99,40 @@ auto GpgKeyTableProxyModel::filterAcceptsColumn( return true; } case 1: { - return filter_columns_ & GpgKeyTableColumn::kType; + return (filter_columns_ & GpgKeyTableColumn::kTYPE) != + GpgKeyTableColumn::kNONE; } case 2: { - return filter_columns_ & GpgKeyTableColumn::kName; + return (filter_columns_ & GpgKeyTableColumn::kNAME) != + GpgKeyTableColumn::kNONE; } case 3: { - return filter_columns_ & GpgKeyTableColumn::kEmailAddress; + return (filter_columns_ & GpgKeyTableColumn::kEMAIL_ADDRESS) != + GpgKeyTableColumn::kNONE; } case 4: { - return filter_columns_ & GpgKeyTableColumn::kUsage; + return (filter_columns_ & GpgKeyTableColumn::kUSAGE) != + GpgKeyTableColumn::kNONE; } case 5: { - return filter_columns_ & GpgKeyTableColumn::kOwnerTrust; + return (filter_columns_ & GpgKeyTableColumn::kOWNER_TRUST) != + GpgKeyTableColumn::kNONE; } case 6: { - return filter_columns_ & GpgKeyTableColumn::kKeyId; + return (filter_columns_ & GpgKeyTableColumn::kKEY_ID) != + GpgKeyTableColumn::kNONE; } case 7: { - return filter_columns_ & GpgKeyTableColumn::kFingerPrint; + return (filter_columns_ & GpgKeyTableColumn::kCREATE_DATE) != + GpgKeyTableColumn::kNONE; + } + case 8: { + return (filter_columns_ & GpgKeyTableColumn::kALGO) != + GpgKeyTableColumn::kNONE; + } + case 9: { + return (filter_columns_ & GpgKeyTableColumn::kSUBKEYS_NUMBER) != + GpgKeyTableColumn::kNONE; } default: return false; @@ -139,4 +156,11 @@ void GpgKeyTableProxyModel::slot_update_favorites() { invalidateFilter(); } + +void GpgKeyTableProxyModel::slot_update_column_type( + GpgKeyTableColumn filter_columns) { + filter_columns_ = filter_columns; + invalidateColumnsFilter(); +} + } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/model/GpgKeyTableProxyModel.h b/src/core/model/GpgKeyTableProxyModel.h index 004fc87b..657b40cf 100644 --- a/src/core/model/GpgKeyTableProxyModel.h +++ b/src/core/model/GpgKeyTableProxyModel.h @@ -62,6 +62,12 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyTableProxyModel */ void SignalFavoritesChanged(); + /** + * @brief + * + */ + void SignalColumnTypeChange(GpgKeyTableColumn); + private slots: /** @@ -70,6 +76,12 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyTableProxyModel */ void slot_update_favorites(); + /** + * @brief + * + */ + void slot_update_column_type(GpgKeyTableColumn); + private: QSharedPointer<GpgKeyTableModel> model_; GpgKeyTableDisplayMode display_mode_; diff --git a/src/ui/dialog/SignersPicker.cpp b/src/ui/dialog/SignersPicker.cpp index 5ab33425..c6bbbbe7 100644 --- a/src/ui/dialog/SignersPicker.cpp +++ b/src/ui/dialog/SignersPicker.cpp @@ -44,23 +44,23 @@ SignersPicker::SignersPicker(QWidget* parent) connect(cancel_button, &QPushButton::clicked, this, &QDialog::reject); /*Setup KeyList*/ - key_list_ = new KeyList(0U, this); - key_list_->AddListGroupTab( - tr("Signers"), "signers", GpgKeyTableDisplayMode::kPrivateKey, - GpgKeyTableColumn::kName | GpgKeyTableColumn::kEmailAddress | - GpgKeyTableColumn::kUsage, - [](const GpgKey& key) -> bool { - return key.IsHasActualSigningCapability(); - }); + key_list_ = + new KeyList(KeyMenuAbility::SEARCH_BAR, + GpgKeyTableColumn::kNAME | GpgKeyTableColumn::kEMAIL_ADDRESS | + GpgKeyTableColumn::kKEY_ID | GpgKeyTableColumn::kUSAGE, + this); + key_list_->AddListGroupTab(tr("Signers"), "signers", + GpgKeyTableDisplayMode::kPRIVATE_KEY, + [](const GpgKey& key) -> bool { + return key.IsHasActualSigningCapability(); + }); key_list_->SlotRefresh(); auto* vbox2 = new QVBoxLayout(); vbox2->addWidget(new QLabel(tr("Select Signer(s)") + ": ")); vbox2->addWidget(key_list_); vbox2->addWidget(new QLabel( - QString( - tr("Please select one or more private keys you use for signing.")) + - "\n" + + tr("Please select one or more private keys you use for signing.") + "\n" + tr("If no key is selected, the default key will be used for signing."))); vbox2->addWidget(confirm_button); vbox2->addWidget(cancel_button); diff --git a/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp b/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp index f8d3d44b..4d96a945 100644 --- a/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp +++ b/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp @@ -41,10 +41,13 @@ KeyUIDSignDialog::KeyUIDSignDialog(const GpgKey& key, UIDArgsListPtr uid, m_uids_(std::move(uid)), m_key_(key) { const auto key_id = m_key_.GetId(); - m_key_list_ = new KeyList(KeyMenuAbility::NONE, this); + m_key_list_ = + new KeyList(KeyMenuAbility::SEARCH_BAR, + GpgKeyTableColumn::kNAME | GpgKeyTableColumn::kEMAIL_ADDRESS | + GpgKeyTableColumn::kKEY_ID, + this); m_key_list_->AddListGroupTab( - tr("Signers"), "signers", GpgKeyTableDisplayMode::kPrivateKey, - GpgKeyTableColumn::kName | GpgKeyTableColumn::kEmailAddress, + tr("Signers"), "signers", GpgKeyTableDisplayMode::kPRIVATE_KEY, [key_id](const GpgKey& key) -> bool { return !(key.IsDisabled() || !key.IsHasCertificationCapability() || !key.IsHasMasterKey() || key.IsExpired() || key.IsRevoked() || diff --git a/src/ui/main_window/KeyMgmt.cpp b/src/ui/main_window/KeyMgmt.cpp index 85671ab2..c45fd46f 100644 --- a/src/ui/main_window/KeyMgmt.cpp +++ b/src/ui/main_window/KeyMgmt.cpp @@ -52,40 +52,30 @@ namespace GpgFrontend::UI { KeyMgmt::KeyMgmt(QWidget* parent) : GeneralMainWindow("key_management", parent) { /* the list of Keys available*/ - key_list_ = new KeyList(KeyMenuAbility::ALL, this); + key_list_ = new KeyList(KeyMenuAbility::ALL, GpgKeyTableColumn::kALL, this); - key_list_->AddListGroupTab( - tr("All"), "all", - GpgKeyTableDisplayMode::kPublicKey | GpgKeyTableDisplayMode::kPrivateKey); + key_list_->AddListGroupTab(tr("All"), "all", + GpgKeyTableDisplayMode::kPUBLIC_KEY | + GpgKeyTableDisplayMode::kPRIVATE_KEY); key_list_->AddListGroupTab( tr("Only Public Key"), "only_public_key", - GpgKeyTableDisplayMode::kPublicKey, - GpgKeyTableColumn::kType | GpgKeyTableColumn::kName | - GpgKeyTableColumn::kEmailAddress | GpgKeyTableColumn::kUsage | - GpgKeyTableColumn::kValidity, - [](const GpgKey& key) -> bool { + GpgKeyTableDisplayMode::kPUBLIC_KEY, [](const GpgKey& key) -> bool { return !key.IsPrivateKey() && !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); }); key_list_->AddListGroupTab( tr("Has Private Key"), "has_private_key", - GpgKeyTableDisplayMode::kPrivateKey, - GpgKeyTableColumn::kType | GpgKeyTableColumn::kName | - GpgKeyTableColumn::kEmailAddress | GpgKeyTableColumn::kUsage | - GpgKeyTableColumn::kValidity, - [](const GpgKey& key) -> bool { + GpgKeyTableDisplayMode::kPRIVATE_KEY, [](const GpgKey& key) -> bool { return key.IsPrivateKey() && !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); }); key_list_->AddListGroupTab( tr("No Primary Key"), "no_primary_key", - GpgKeyTableDisplayMode::kPublicKey | GpgKeyTableDisplayMode::kPrivateKey, - GpgKeyTableColumn::kType | GpgKeyTableColumn::kName | - GpgKeyTableColumn::kEmailAddress | GpgKeyTableColumn::kUsage | - GpgKeyTableColumn::kValidity, + GpgKeyTableDisplayMode::kPUBLIC_KEY | + GpgKeyTableDisplayMode::kPRIVATE_KEY, [](const GpgKey& key) -> bool { return !key.IsHasMasterKey() && !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); @@ -93,18 +83,16 @@ KeyMgmt::KeyMgmt(QWidget* parent) key_list_->AddListGroupTab( tr("Revoked"), "revoked", - GpgKeyTableDisplayMode::kPublicKey | GpgKeyTableDisplayMode::kPrivateKey, - GpgKeyTableColumn::kType | GpgKeyTableColumn::kName | - GpgKeyTableColumn::kEmailAddress | GpgKeyTableColumn::kUsage | - GpgKeyTableColumn::kValidity, + GpgKeyTableDisplayMode::kPUBLIC_KEY | + GpgKeyTableDisplayMode::kPRIVATE_KEY, + [](const GpgKey& key) -> bool { return key.IsRevoked(); }); key_list_->AddListGroupTab( tr("Expired"), "expired", - GpgKeyTableDisplayMode::kPublicKey | GpgKeyTableDisplayMode::kPrivateKey, - GpgKeyTableColumn::kType | GpgKeyTableColumn::kName | - GpgKeyTableColumn::kEmailAddress | GpgKeyTableColumn::kUsage | - GpgKeyTableColumn::kValidity, + GpgKeyTableDisplayMode::kPUBLIC_KEY | + GpgKeyTableDisplayMode::kPRIVATE_KEY, + [](const GpgKey& key) -> bool { return key.IsExpired(); }); setCentralWidget(key_list_); diff --git a/src/ui/main_window/MainWindow.cpp b/src/ui/main_window/MainWindow.cpp index c50cfc5e..7e2bbe85 100644 --- a/src/ui/main_window/MainWindow.cpp +++ b/src/ui/main_window/MainWindow.cpp @@ -61,10 +61,13 @@ void MainWindow::Init() noexcept { setCentralWidget(edit_); /* the list of Keys available*/ - m_key_list_ = - new KeyList(KeyMenuAbility::REFRESH | KeyMenuAbility::UNCHECK_ALL | - KeyMenuAbility::SEARCH_BAR, - this); + m_key_list_ = new KeyList( + KeyMenuAbility::REFRESH | KeyMenuAbility::UNCHECK_ALL | + KeyMenuAbility::SEARCH_BAR, + GpgKeyTableColumn::kTYPE | GpgKeyTableColumn::kNAME | + GpgKeyTableColumn::kKEY_ID | GpgKeyTableColumn::kEMAIL_ADDRESS | + GpgKeyTableColumn::kUSAGE | GpgKeyTableColumn::kOWNER_TRUST, + this); info_board_ = new InfoBoardWidget(this); diff --git a/src/ui/main_window/MainWindowUI.cpp b/src/ui/main_window/MainWindowUI.cpp index f96cf595..c1189fa2 100644 --- a/src/ui/main_window/MainWindowUI.cpp +++ b/src/ui/main_window/MainWindowUI.cpp @@ -708,43 +708,31 @@ void MainWindow::create_dock_windows() { m_key_list_->AddListGroupTab( tr("Default"), "default", - GpgKeyTableDisplayMode::kPublicKey | GpgKeyTableDisplayMode::kPrivateKey, - GpgKeyTableColumn::kType | GpgKeyTableColumn::kName | - GpgKeyTableColumn::kEmailAddress | GpgKeyTableColumn::kUsage | - GpgKeyTableColumn::kValidity, + GpgKeyTableDisplayMode::kPUBLIC_KEY | + GpgKeyTableDisplayMode::kPRIVATE_KEY, [](const GpgKey& key) -> bool { return !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); }); m_key_list_->AddListGroupTab( tr("Favourite"), "favourite", - GpgKeyTableDisplayMode::kPublicKey | GpgKeyTableDisplayMode::kPrivateKey | - GpgKeyTableDisplayMode::kFavorites, - GpgKeyTableColumn::kType | GpgKeyTableColumn::kName | - GpgKeyTableColumn::kEmailAddress | GpgKeyTableColumn::kUsage | - GpgKeyTableColumn::kValidity, + GpgKeyTableDisplayMode::kPUBLIC_KEY | + GpgKeyTableDisplayMode::kPRIVATE_KEY | + GpgKeyTableDisplayMode::kFAVORITES, [](const GpgKey& key) -> bool { return CommonUtils::GetInstance()->KeyExistsinFavouriteList(key); }); m_key_list_->AddListGroupTab( tr("Only Public Key"), "only_public_key", - GpgKeyTableDisplayMode::kPublicKey, - GpgKeyTableColumn::kType | GpgKeyTableColumn::kName | - GpgKeyTableColumn::kEmailAddress | GpgKeyTableColumn::kUsage | - GpgKeyTableColumn::kValidity, - [](const GpgKey& key) -> bool { + GpgKeyTableDisplayMode::kPUBLIC_KEY, [](const GpgKey& key) -> bool { return !key.IsPrivateKey() && !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); }); m_key_list_->AddListGroupTab( tr("Has Private Key"), "has_private_key", - GpgKeyTableDisplayMode::kPrivateKey, - GpgKeyTableColumn::kType | GpgKeyTableColumn::kName | - GpgKeyTableColumn::kEmailAddress | GpgKeyTableColumn::kUsage | - GpgKeyTableColumn::kValidity, - [](const GpgKey& key) -> bool { + GpgKeyTableDisplayMode::kPRIVATE_KEY, [](const GpgKey& key) -> bool { return key.IsPrivateKey() && !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); }); diff --git a/src/ui/widgets/HelpPage.cpp b/src/ui/widgets/HelpPage.cpp index 78169944..cf56564c 100644 --- a/src/ui/widgets/HelpPage.cpp +++ b/src/ui/widgets/HelpPage.cpp @@ -28,6 +28,8 @@ #include "ui/widgets/HelpPage.h" +#include "core/function/GlobalSettingStation.h" + namespace GpgFrontend::UI { HelpPage::HelpPage(const QString& path, QWidget* parent) : QWidget(parent) { @@ -64,7 +66,10 @@ auto HelpPage::localized_help(const QUrl& url) -> QUrl { QStringList fileparts = filename.split("."); // QSettings settings; - QString lang = QSettings().value("int/lang", QLocale().name()).toString(); + QString lang = GlobalSettingStation::GetInstance() + .GetSettings() + .value("int/lang", QLocale().name()) + .toString(); if (lang.isEmpty()) { lang = QLocale().name(); } diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp index 4229a35f..5ebddbb5 100644 --- a/src/ui/widgets/KeyList.cpp +++ b/src/ui/widgets/KeyList.cpp @@ -29,7 +29,6 @@ #include "ui/widgets/KeyList.h" #include <cstddef> -#include <mutex> #include <utility> #include "core/function/GlobalSettingStation.h" @@ -41,11 +40,19 @@ namespace GpgFrontend::UI { -KeyList::KeyList(KeyMenuAbility::AbilityType menu_ability, QWidget* parent) +KeyList::KeyList(KeyMenuAbility::AbilityType menu_ability, + GpgKeyTableColumn fixed_columns_filter, QWidget* parent) : QWidget(parent), ui_(GpgFrontend::SecureCreateSharedObject<Ui_KeyList>()), menu_ability_(menu_ability), - model_(GpgKeyGetter::GetInstance().GetGpgKeyTableModel()) { + model_(GpgKeyGetter::GetInstance().GetGpgKeyTableModel()), + fixed_columns_filter_(fixed_columns_filter), + global_column_filter_(static_cast<GpgKeyTableColumn>( + GlobalSettingStation::GetInstance() + .GetSettings() + .value("keys/global_columns_filter", + static_cast<unsigned int>(GpgKeyTableColumn::kALL)) + .toUInt())) { init(); } @@ -59,6 +66,94 @@ void KeyList::init() { ui_->uncheckButton->setHidden(~menu_ability_ & KeyMenuAbility::UNCHECK_ALL); ui_->searchBarEdit->setHidden(~menu_ability_ & KeyMenuAbility::SEARCH_BAR); + auto* column_type_menu = new QMenu(); + + key_id_column_action_ = new QAction(tr("Key ID")); + key_id_column_action_->setCheckable(true); + key_id_column_action_->setChecked( + (global_column_filter_ & GpgKeyTableColumn::kKEY_ID) != + GpgKeyTableColumn::kNONE); + connect(key_id_column_action_, &QAction::toggled, this, [=](bool checked) { + UpdateKeyTableColumnType( + checked ? global_column_filter_ | GpgKeyTableColumn::kKEY_ID + : global_column_filter_ & ~GpgKeyTableColumn::kKEY_ID); + }); + + algo_column_action_ = new QAction(tr("Algorithm")); + algo_column_action_->setCheckable(true); + algo_column_action_->setChecked( + (global_column_filter_ & GpgKeyTableColumn::kALGO) != + GpgKeyTableColumn::kNONE); + connect(algo_column_action_, &QAction::toggled, this, [=](bool checked) { + UpdateKeyTableColumnType( + checked ? global_column_filter_ | GpgKeyTableColumn::kALGO + : global_column_filter_ & ~GpgKeyTableColumn::kALGO); + }); + + owner_trust_column_action_ = new QAction(tr("Owner Trust")); + owner_trust_column_action_->setCheckable(true); + owner_trust_column_action_->setChecked( + (global_column_filter_ & GpgKeyTableColumn::kOWNER_TRUST) != + GpgKeyTableColumn::kNONE); + connect( + owner_trust_column_action_, &QAction::toggled, this, [=](bool checked) { + UpdateKeyTableColumnType( + checked ? global_column_filter_ | GpgKeyTableColumn::kOWNER_TRUST + : global_column_filter_ & ~GpgKeyTableColumn::kOWNER_TRUST); + }); + + create_date_column_action_ = new QAction(tr("Create Date")); + create_date_column_action_->setCheckable(true); + create_date_column_action_->setChecked( + (global_column_filter_ & GpgKeyTableColumn::kCREATE_DATE) != + GpgKeyTableColumn::kNONE); + connect( + create_date_column_action_, &QAction::toggled, this, [=](bool checked) { + UpdateKeyTableColumnType( + checked ? global_column_filter_ | GpgKeyTableColumn::kCREATE_DATE + : global_column_filter_ & ~GpgKeyTableColumn::kCREATE_DATE); + }); + + subkeys_number_column_action_ = new QAction("Subkey(s)"); + subkeys_number_column_action_->setCheckable(true); + subkeys_number_column_action_->setChecked( + (global_column_filter_ & GpgKeyTableColumn::kSUBKEYS_NUMBER) != + GpgKeyTableColumn::kNONE); + connect( + subkeys_number_column_action_, &QAction::toggled, this, + [=](bool checked) { + UpdateKeyTableColumnType( + checked + ? global_column_filter_ | GpgKeyTableColumn::kSUBKEYS_NUMBER + : global_column_filter_ & ~GpgKeyTableColumn::kSUBKEYS_NUMBER); + }); + + if ((fixed_columns_filter_ & GpgKeyTableColumn::kKEY_ID) != + GpgKeyTableColumn::kNONE) { + column_type_menu->addAction(key_id_column_action_); + } + + if ((fixed_columns_filter_ & GpgKeyTableColumn::kALGO) != + GpgKeyTableColumn::kNONE) { + column_type_menu->addAction(algo_column_action_); + } + if ((fixed_columns_filter_ & GpgKeyTableColumn::kCREATE_DATE) != + GpgKeyTableColumn::kNONE) { + column_type_menu->addAction(create_date_column_action_); + } + + if ((fixed_columns_filter_ & GpgKeyTableColumn::kOWNER_TRUST) != + GpgKeyTableColumn::kNONE) { + column_type_menu->addAction(owner_trust_column_action_); + } + + if ((fixed_columns_filter_ & GpgKeyTableColumn::kSUBKEYS_NUMBER) != + GpgKeyTableColumn::kNONE) { + column_type_menu->addAction(subkeys_number_column_action_); + } + + ui_->columnTypeButton->setMenu(column_type_menu); + ui_->keyGroupTab->clear(); popup_menu_ = new QMenu(this); @@ -95,6 +190,11 @@ void KeyList::init() { connect(this, &KeyList::SignalRefreshStatusBar, UISignalStation::GetInstance(), &UISignalStation::SignalRefreshStatusBar); + connect(this, &KeyList::SignalColumnTypeChange, this, [=]() { + GlobalSettingStation::GetInstance().GetSettings().setValue( + "keys/global_columns_filter", + static_cast<unsigned int>(global_column_filter_)); + }); setAcceptDrops(true); @@ -114,14 +214,20 @@ void KeyList::init() { } void KeyList::AddListGroupTab(const QString& name, const QString& id, - GpgKeyTableDisplayMode select_type, - GpgKeyTableColumn info_type, - GpgKeyTableProxyModel::KeyFilter filter) { + GpgKeyTableDisplayMode display_mode, + GpgKeyTableProxyModel::KeyFilter search_filter, + GpgKeyTableColumn custom_columns_filter) { auto* key_table = - new KeyTable(this, model_, select_type, info_type, std::move(filter)); + new KeyTable(this, model_, display_mode, custom_columns_filter, + std::move(search_filter)); key_table->setObjectName(id); ui_->keyGroupTab->addTab(key_table, name); + + connect(this, &KeyList::SignalColumnTypeChange, key_table, + &KeyTable::SignalColumnTypeChange); + + UpdateKeyTableColumnType(global_column_filter_); } void KeyList::SlotRefresh() { @@ -347,12 +453,12 @@ void KeyList::dropEvent(QDropEvent* event) { if (!file.open(QIODevice::ReadOnly)) { GF_UI_LOG_ERROR("couldn't open file: {}", tmp.toString()); } - QByteArray in_buffer = file.readAll(); + auto in_buffer = file.readAll(); this->import_keys(in_buffer); file.close(); } } else { - QByteArray in_buffer(event->mimeData()->text().toUtf8()); + auto in_buffer(event->mimeData()->text().toUtf8()); this->import_keys(in_buffer); } } @@ -458,7 +564,6 @@ void KeyList::filter_by_keyword() { auto* key_table = qobject_cast<KeyTable*>(ui_->keyGroupTab->widget(i)); // refresh arguments key_table->SetFilterKeyword(keyword.toLower()); - key_table->SetMenuAbility(menu_ability_); } // refresh ui @@ -477,104 +582,9 @@ void KeyList::check_all() { key_table->CheckAll(); } -auto KeyTable::GetChecked() -> KeyIdArgsListPtr { - auto ret = std::make_unique<KeyIdArgsList>(); - for (size_t i = 0; i < GetRowCount(); i++) { - if (IsRowChecked(i)) ret->push_back(GetKeyIdByRow(i)); - } - return ret; -} - -KeyTable::KeyTable(QWidget* parent, QSharedPointer<GpgKeyTableModel> model, - GpgKeyTableDisplayMode select_type, - GpgKeyTableColumn info_type, - GpgKeyTableProxyModel::KeyFilter filter) - : QTableView(parent), - model_(std::move(model)), - proxy_model_(model_, select_type, info_type, std::move(filter), this) { - setModel(&proxy_model_); - - verticalHeader()->hide(); - horizontalHeader()->setStretchLastSection(false); - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - - setShowGrid(false); - sortByColumn(2, Qt::AscendingOrder); - setSelectionBehavior(QAbstractItemView::SelectRows); - setSelectionMode(QAbstractItemView::SingleSelection); - - // table items not editable - setEditTriggers(QAbstractItemView::NoEditTriggers); - - setFocusPolicy(Qt::NoFocus); - setAlternatingRowColors(true); - - connect(CommonUtils::GetInstance(), &CommonUtils::SignalFavoritesChanged, - &proxy_model_, &GpgKeyTableProxyModel::SignalFavoritesChanged); -} - -void KeyTable::SetMenuAbility(KeyMenuAbility::AbilityType ability) { - this->ability_ = ability; -} - -void KeyTable::SetFilterKeyword(const QString& keyword) { - proxy_model_.SetSearchKeywords(keyword); -} - -void KeyTable::RefreshModel(QSharedPointer<GpgKeyTableModel> model) { - model_ = std::move(model); - proxy_model_.setSourceModel(model_.get()); -} - -auto KeyTable::IsRowChecked(int row) const -> bool { - auto index = model()->index(row, 0); - return index.data(Qt::CheckStateRole).toInt() == Qt::Checked; -} - -auto KeyTable::GetRowCount() const -> int { return model()->rowCount(); } - -auto KeyTable::GetKeyIdByRow(int row) const -> QString { - if (row < 0 || row >= model()->rowCount()) return {}; - auto origin_row = model()->index(row, 0).data().toInt(); - return model_->GetKeyIDByRow(origin_row); -} - -auto KeyTable::IsPrivateKeyByRow(int row) const -> bool { - if (row < 0 || row >= model()->rowCount()) return false; - auto origin_row = model()->index(row, 0).data().toInt(); - return model_->IsPrivateKeyByRow(origin_row); -} - -auto KeyTable::IsPublicKeyByRow(int row) const -> bool { - if (row < 0 || row >= model()->rowCount()) return false; - auto origin_row = model()->index(row, 0).data().toInt(); - return !model_->IsPrivateKeyByRow(origin_row); -} - -void KeyTable::SetRowChecked(int row) const { - if (row < 0 || row >= model()->rowCount()) return; - model()->setData(model()->index(row, 0), Qt::Checked, Qt::CheckStateRole); -} - -void KeyTable::CheckAll() { - for (int row = 0; row < model()->rowCount(); ++row) { - auto index = model()->index(row, 0); - model()->setData(index, Qt::Checked, Qt::CheckStateRole); - } -} - -void KeyTable::UncheckAll() { - for (int row = 0; row < model()->rowCount(); ++row) { - auto index = model()->index(row, 0); - model()->setData(index, Qt::Unchecked, Qt::CheckStateRole); - } -} - -[[nodiscard]] auto KeyTable::GetRowSelected() const -> int { - auto selected_indexes = selectedIndexes(); - if (selected_indexes.empty()) return -1; - - return selected_indexes.first().row(); +void KeyList::UpdateKeyTableColumnType(GpgKeyTableColumn column_type) { + global_column_filter_ = column_type; + emit SignalColumnTypeChange(fixed_columns_filter_ & global_column_filter_); } } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/KeyList.h b/src/ui/widgets/KeyList.h index 70320519..1893a98a 100644 --- a/src/ui/widgets/KeyList.h +++ b/src/ui/widgets/KeyList.h @@ -28,9 +28,7 @@ #pragma once -#include "core/model/GpgKey.h" -#include "core/model/GpgKeyTableModel.h" -#include "core/model/GpgKeyTableProxyModel.h" +#include "ui/widgets/KeyTable.h" class Ui_KeyList; @@ -56,143 +54,6 @@ struct KeyMenuAbility { * @brief * */ -struct KeyTable : public QTableView { - Q_OBJECT - public: - using KeyTableFilter = std::function<bool(const GpgKey&, const KeyTable&)>; - - /** - * @brief Construct a new Key Table object - * - * @param _key_list - * @param _select_type - * @param _info_type - * @param _filter - */ - KeyTable( - QWidget* parent, QSharedPointer<GpgKeyTableModel> model, - GpgKeyTableDisplayMode _select_type, GpgKeyTableColumn _info_type, - GpgKeyTableProxyModel::KeyFilter _filter = [](const GpgKey&) -> bool { - return true; - }); - - /** - * @brief - * - * @param model - */ - void RefreshModel(QSharedPointer<GpgKeyTableModel> model); - - /** - * @brief Get the Checked object - * - * @return KeyIdArgsListPtr& - */ - auto GetChecked() -> KeyIdArgsListPtr; - - /** - * @brief - * - */ - void UncheckALL() const; - - /** - * @brief - * - */ - void CheckALL() const; - - /** - * @brief - * - */ - void SetMenuAbility(KeyMenuAbility::AbilityType ability); - - /** - * @brief - * - */ - void SetFilterKeyword(const QString& keyword); - - /** - * @brief - * - * @param row - * @return true - * @return false - */ - [[nodiscard]] auto IsRowChecked(int row) const -> bool; - - /** - * @brief Set the Row Checked object - * - * @param row - */ - void SetRowChecked(int row) const; - - /** - * @brief Set the Row Checked object - * - * @param row - */ - [[nodiscard]] auto GetRowSelected() const -> int; - - /** - * @brief Get the Row Count object - * - * @return auto - */ - [[nodiscard]] auto GetRowCount() const -> int; - - /** - * @brief Get the Key Id By Row object - * - * @param row - * @return QString - */ - [[nodiscard]] auto GetKeyIdByRow(int row) const -> QString; - - /** - * @brief - * - * @param row - * @return true - * @return false - */ - [[nodiscard]] auto IsPublicKeyByRow(int row) const -> bool; - - /** - * @brief - * - * @param row - * @return true - * @return false - */ - [[nodiscard]] auto IsPrivateKeyByRow(int row) const -> bool; - - /** - * @brief - * - */ - void CheckAll(); - - /** - * @brief - * - */ - void UncheckAll(); - - private: - KeyMenuAbility::AbilityType ability_; ///< - - QSharedPointer<GpgKeyTableModel> model_; - GpgKeyTableProxyModel proxy_model_; -}; - -/** - * @brief - * - */ class KeyList : public QWidget { Q_OBJECT @@ -203,8 +64,10 @@ class KeyList : public QWidget { * @param menu_ability * @param parent */ - explicit KeyList(KeyMenuAbility::AbilityType menu_ability, - QWidget* parent = nullptr); + explicit KeyList( + KeyMenuAbility::AbilityType menu_ability, + GpgKeyTableColumn fixed_column_filter = GpgKeyTableColumn::kALL, + QWidget* parent = nullptr); /** * @brief @@ -216,11 +79,11 @@ class KeyList : public QWidget { */ void AddListGroupTab( const QString& name, const QString& id, - GpgKeyTableDisplayMode selectType = GpgKeyTableDisplayMode::kPrivateKey, - GpgKeyTableColumn infoType = GpgKeyTableColumn::kAll, - GpgKeyTableProxyModel::KeyFilter filter = [](const GpgKey&) -> bool { - return true; - }); + GpgKeyTableDisplayMode display_mode = + GpgKeyTableDisplayMode::kPRIVATE_KEY, + GpgKeyTableProxyModel::KeyFilter search_filter = + [](const GpgKey&) -> bool { return true; }, + GpgKeyTableColumn custom_columns_filter = GpgKeyTableColumn::kALL); /** * @brief Set the Double Clicked Action object @@ -293,7 +156,7 @@ class KeyList : public QWidget { * @param keyIds * @param key_table */ - static void SetChecked(const KeyIdArgsListPtr& keyIds, + static void SetChecked(const KeyIdArgsListPtr& key_ids, const KeyTable& key_table); /** @@ -318,6 +181,12 @@ class KeyList : public QWidget { */ [[maybe_unused]] auto ContainsPrivateKeys() -> bool; + /** + * @brief + * + */ + void UpdateKeyTableColumnType(GpgKeyTableColumn); + signals: /** * @brief @@ -333,6 +202,14 @@ class KeyList : public QWidget { */ void SignalRefreshDatabase(); + signals: + + /** + * @brief + * + */ + void SignalColumnTypeChange(GpgKeyTableColumn); + public slots: /** @@ -359,7 +236,7 @@ class KeyList : public QWidget { * * @param inBuffer */ - void import_keys(const QByteArray& inBuffer); + void import_keys(const QByteArray& in_buffer); /** * @brief @@ -384,6 +261,14 @@ class KeyList : public QWidget { std::function<void(const GpgKey&, QWidget*)> m_action_ = nullptr; ///< KeyMenuAbility::AbilityType menu_ability_ = KeyMenuAbility::ALL; ///< QSharedPointer<GpgKeyTableModel> model_; + GpgKeyTableColumn fixed_columns_filter_; + GpgKeyTableColumn global_column_filter_; + + QAction* key_id_column_action_; + QAction* algo_column_action_; + QAction* create_date_column_action_; + QAction* owner_trust_column_action_; + QAction* subkeys_number_column_action_; private slots: diff --git a/src/ui/widgets/KeyTable.cpp b/src/ui/widgets/KeyTable.cpp new file mode 100644 index 00000000..fc6d083f --- /dev/null +++ b/src/ui/widgets/KeyTable.cpp @@ -0,0 +1,136 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "ui/widgets/KeyTable.h" + +#include "ui/UserInterfaceUtils.h" + +namespace GpgFrontend::UI { + +auto KeyTable::GetChecked() const -> KeyIdArgsListPtr { + auto ret = std::make_unique<KeyIdArgsList>(); + for (size_t i = 0; i < GetRowCount(); i++) { + if (IsRowChecked(i)) ret->push_back(GetKeyIdByRow(i)); + } + return ret; +} + +KeyTable::KeyTable(QWidget* parent, QSharedPointer<GpgKeyTableModel> model, + GpgKeyTableDisplayMode select_type, + GpgKeyTableColumn column_filter, + GpgKeyTableProxyModel::KeyFilter filter) + : QTableView(parent), + model_(std::move(model)), + proxy_model_(model_, select_type, column_filter, std::move(filter), this), + column_filter_(column_filter) { + setModel(&proxy_model_); + + verticalHeader()->hide(); + horizontalHeader()->setStretchLastSection(false); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + setShowGrid(false); + sortByColumn(2, Qt::AscendingOrder); + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::SingleSelection); + + // table items not editable + setEditTriggers(QAbstractItemView::NoEditTriggers); + + setFocusPolicy(Qt::NoFocus); + setAlternatingRowColors(true); + + connect(CommonUtils::GetInstance(), &CommonUtils::SignalFavoritesChanged, + &proxy_model_, &GpgKeyTableProxyModel::SignalFavoritesChanged); + connect(this, &KeyTable::SignalColumnTypeChange, this, + [=](GpgKeyTableColumn global_column_filter) { + emit(&proxy_model_) + ->SignalColumnTypeChange(column_filter_ & global_column_filter); + }); +} + +void KeyTable::SetFilterKeyword(const QString& keyword) { + proxy_model_.SetSearchKeywords(keyword); +} + +void KeyTable::RefreshModel(QSharedPointer<GpgKeyTableModel> model) { + model_ = std::move(model); + proxy_model_.setSourceModel(model_.get()); +} + +auto KeyTable::IsRowChecked(int row) const -> bool { + auto index = model()->index(row, 0); + return index.data(Qt::CheckStateRole).toInt() == Qt::Checked; +} + +auto KeyTable::GetRowCount() const -> int { return model()->rowCount(); } + +auto KeyTable::GetKeyIdByRow(int row) const -> QString { + if (row < 0 || row >= model()->rowCount()) return {}; + auto origin_row = model()->index(row, 0).data().toInt(); + return model_->GetKeyIDByRow(origin_row); +} + +auto KeyTable::IsPrivateKeyByRow(int row) const -> bool { + if (row < 0 || row >= model()->rowCount()) return false; + auto origin_row = model()->index(row, 0).data().toInt(); + return model_->IsPrivateKeyByRow(origin_row); +} + +auto KeyTable::IsPublicKeyByRow(int row) const -> bool { + if (row < 0 || row >= model()->rowCount()) return false; + auto origin_row = model()->index(row, 0).data().toInt(); + return !model_->IsPrivateKeyByRow(origin_row); +} + +void KeyTable::SetRowChecked(int row) const { + if (row < 0 || row >= model()->rowCount()) return; + model()->setData(model()->index(row, 0), Qt::Checked, Qt::CheckStateRole); +} + +void KeyTable::CheckAll() { + for (int row = 0; row < model()->rowCount(); ++row) { + auto index = model()->index(row, 0); + model()->setData(index, Qt::Checked, Qt::CheckStateRole); + } +} + +void KeyTable::UncheckAll() { + for (int row = 0; row < model()->rowCount(); ++row) { + auto index = model()->index(row, 0); + model()->setData(index, Qt::Unchecked, Qt::CheckStateRole); + } +} + +[[nodiscard]] auto KeyTable::GetRowSelected() const -> int { + auto selected_indexes = selectedIndexes(); + if (selected_indexes.empty()) return -1; + + return selected_indexes.first().row(); +} +} // namespace GpgFrontend::UI
\ No newline at end of file diff --git a/src/ui/widgets/KeyTable.h b/src/ui/widgets/KeyTable.h new file mode 100644 index 00000000..4ec8f687 --- /dev/null +++ b/src/ui/widgets/KeyTable.h @@ -0,0 +1,176 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include "core/model/GpgKey.h" +#include "core/model/GpgKeyTableModel.h" +#include "core/model/GpgKeyTableProxyModel.h" + +namespace GpgFrontend::UI { + +/** + * @brief + * + */ +struct KeyTable : public QTableView { + Q_OBJECT + public: + using KeyTableFilter = std::function<bool(const GpgKey&, const KeyTable&)>; + + /** + * @brief Construct a new Key Table object + * + * @param _key_list + * @param _select_type + * @param _info_type + * @param _filter + */ + KeyTable( + QWidget* parent, QSharedPointer<GpgKeyTableModel> model, + GpgKeyTableDisplayMode _select_type, GpgKeyTableColumn _info_type, + GpgKeyTableProxyModel::KeyFilter _filter = [](const GpgKey&) -> bool { + return true; + }); + + /** + * @brief + * + * @param model + */ + void RefreshModel(QSharedPointer<GpgKeyTableModel> model); + + /** + * @brief Get the Checked object + * + * @return KeyIdArgsListPtr& + */ + [[nodiscard]] auto GetChecked() const -> KeyIdArgsListPtr; + + /** + * @brief + * + */ + void UncheckALL() const; + + /** + * @brief + * + */ + void CheckALL() const; + + /** + * @brief + * + */ + void SetFilterKeyword(const QString& keyword); + + /** + * @brief + * + * @param row + * @return true + * @return false + */ + [[nodiscard]] auto IsRowChecked(int row) const -> bool; + + /** + * @brief Set the Row Checked object + * + * @param row + */ + void SetRowChecked(int row) const; + + /** + * @brief Set the Row Checked object + * + * @param row + */ + [[nodiscard]] auto GetRowSelected() const -> int; + + /** + * @brief Get the Row Count object + * + * @return auto + */ + [[nodiscard]] auto GetRowCount() const -> int; + + /** + * @brief Get the Key Id By Row object + * + * @param row + * @return QString + */ + [[nodiscard]] auto GetKeyIdByRow(int row) const -> QString; + + /** + * @brief + * + * @param row + * @return true + * @return false + */ + [[nodiscard]] auto IsPublicKeyByRow(int row) const -> bool; + + /** + * @brief + * + * @param row + * @return true + * @return false + */ + [[nodiscard]] auto IsPrivateKeyByRow(int row) const -> bool; + + /** + * @brief + * + */ + void CheckAll(); + + /** + * @brief + * + */ + void UncheckAll(); + + signals: + + /** + * @brief + * + */ + void SignalColumnTypeChange(GpgKeyTableColumn); + + private: + QSharedPointer<GpgKeyTableModel> model_; + GpgKeyTableProxyModel proxy_model_; + + GpgKeyTableColumn column_filter_; +}; + +} // namespace GpgFrontend::UI
\ No newline at end of file diff --git a/ui/KeyList.ui b/ui/KeyList.ui index afccdcf6..618b44fd 100644 --- a/ui/KeyList.ui +++ b/ui/KeyList.ui @@ -93,6 +93,23 @@ </widget> </item> <item> + <widget class="QToolButton" name="columnTypeButton"> + <property name="acceptDrops"> + <bool>false</bool> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="icon"> + <iconset resource="../gpgfrontend.qrc"> + <normaloff>:/icons/filter.png</normaloff>:/icons/filter.png</iconset> + </property> + <property name="popupMode"> + <enum>QToolButton::InstantPopup</enum> + </property> + </widget> + </item> + <item> <spacer name="horizontalSpacer"> <property name="orientation"> <enum>Qt::Horizontal</enum> |