diff options
Diffstat (limited to 'src/ui/widgets')
-rw-r--r-- | src/ui/widgets/InfoBoardWidget.cpp | 14 | ||||
-rw-r--r-- | src/ui/widgets/KeyList.cpp | 219 | ||||
-rw-r--r-- | src/ui/widgets/KeyList.h | 34 | ||||
-rw-r--r-- | src/ui/widgets/SignersPicker.cpp | 8 |
4 files changed, 182 insertions, 93 deletions
diff --git a/src/ui/widgets/InfoBoardWidget.cpp b/src/ui/widgets/InfoBoardWidget.cpp index 1b7dbda0..d46d5f92 100644 --- a/src/ui/widgets/InfoBoardWidget.cpp +++ b/src/ui/widgets/InfoBoardWidget.cpp @@ -37,7 +37,7 @@ InfoBoardWidget::InfoBoardWidget(QWidget* parent) ui->actionButtonLayout->addStretch(); ui->actionLabel->setText(_("InfoBoard's Actions Menu")); ui->copyButton->setText(_("Copy")); - ui->saveButton->setText(_("Save")); + ui->saveButton->setText(_("Save File")); ui->clearButton->setText(_("Clear")); connect(ui->copyButton, &QPushButton::clicked, this, @@ -102,18 +102,12 @@ void InfoBoardWidget::associateTextEdit(QTextEdit* edit) { } void InfoBoardWidget::associateTabWidget(QTabWidget* tab) { - if (mTextPage != nullptr) - disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset())); - if (mTabWidget != nullptr) { - disconnect(mTabWidget, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset())); - connect(mTabWidget, SIGNAL(tabCloseRequested(int)), this, - SLOT(slotReset())); - } - mTextPage = nullptr; mTabWidget = tab; connect(tab, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset())); connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(slotReset())); + // reset + this->slotReset(); } void InfoBoardWidget::addOptionalAction(const QString& name, @@ -169,6 +163,8 @@ void InfoBoardWidget::slotSave() { auto file_path = QFileDialog::getSaveFileName( this, _("Save Information Board's Content"), {}, tr("Text (*.txt)")); LOG(INFO) << "file path" << file_path.toStdString(); + if(file_path.isEmpty()) return; + QFile file(file_path); if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { file.write(ui->infoBoard->toPlainText().toUtf8()); diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp index 02a12e80..0e4c5bba 100644 --- a/src/ui/widgets/KeyList.cpp +++ b/src/ui/widgets/KeyList.cpp @@ -24,54 +24,65 @@ #include "ui/widgets/KeyList.h" +#include <boost/format.hpp> #include <utility> #include "gpg/function/GpgKeyGetter.h" #include "ui/SignalStation.h" +#include "ui/UserInterfaceUtils.h" +#include "ui/settings/GlobalSettingStation.h" +#include "ui_KeyList.h" namespace GpgFrontend::UI { -KeyList::KeyList(QWidget* parent) : QWidget(parent) { init(); } +int KeyList::key_list_id = 2048; -KeyList::KeyList(KeyListRow::KeyType selectType, - KeyListColumn::InfoType infoType, - const std::function<bool(const GpgKey&)>& filter, - QWidget* parent) - : QWidget(parent) { +KeyList::KeyList(bool menu, QWidget* parent) + : QWidget(parent), + _m_key_list_id(key_list_id++), + ui(std::make_shared<Ui_KeyList>()), + menu_status(menu) { init(); - addListGroupTab(_("Default"), selectType, infoType, filter); } void KeyList::init() { - mGroupTab = new QTabWidget(); - mGroupTab->setMovable(true); - mGroupTab->setTabsClosable(false); - mGroupTab->setDocumentMode(true); - - auto* layout = new QVBoxLayout; - layout->addWidget(mGroupTab); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(3); - setLayout(layout); + ui->setupUi(this); + ui->menuWidget->setHidden(!menu_status); + ui->keyGroupTab->clear(); popupMenu = new QMenu(this); // register key database refresh signal + connect(this, &KeyList::signalRefreshDatabase, SignalStation::GetInstance(), + &SignalStation::KeyDatabaseRefresh); connect(SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()), this, SLOT(slotRefresh())); + connect(ui->refreshKeyListButton, &QPushButton::clicked, this, + &KeyList::slotRefresh); + connect(ui->syncButton, &QPushButton::clicked, this, + &KeyList::slotSyncWithKeyServer); + connect(this, &KeyList::signalRefreshStatusBar, SignalStation::GetInstance(), + &SignalStation::signalRefreshStatusBar); setAcceptDrops(true); + + ui->keyListOperationsLabel->setText(_("Key List Menu: ")); + ui->refreshKeyListButton->setText(_("Refresh")); + ui->syncButton->setText(_("Sync Public Key")); + ui->syncButton->setToolTip(_("Sync public key with your default keyserver")); } void KeyList::addListGroupTab( const QString& name, KeyListRow::KeyType selectType, KeyListColumn::InfoType infoType, const std::function<bool(const GpgKey&)>& filter) { + LOG(INFO) << _("Called") << name.toStdString(); + auto key_list = new QTableWidget(this); if (mKeyList == nullptr) { mKeyList = key_list; } - mGroupTab->addTab(key_list, name); + ui->keyGroupTab->addTab(key_list, name); mKeyTables.emplace_back(key_list, selectType, infoType, filter); key_list->setColumnCount(7); @@ -120,17 +131,22 @@ void KeyList::addListGroupTab( connect(key_list, &QTableWidget::doubleClicked, this, &KeyList::slotDoubleClicked); - - // refresh - mKeyTables.back().Refresh(); } void KeyList::slotRefresh() { - LOG(INFO) << _("called"); - - for (auto& key_table : mKeyTables) { - key_table.Refresh(); - } + LOG(INFO) << _("Called") << "_m_key_list_id" << _m_key_list_id; + emit signalRefreshStatusBar(_("Refreshing Key List..."), 3000); + auto thread = QThread::create([this, _id = _m_key_list_id]() { + std::lock_guard<std::mutex> guard(buffered_key_list_mutex); + _buffered_keys_list = nullptr; + // buffered keys list + _buffered_keys_list = GpgKeyGetter::GetInstance(_id).FetchKey(); + }); + connect(thread, &QThread::finished, this, &KeyList::slotRefreshUI); + connect(thread, &QThread::finished, thread, &QThread::deleteLater); + ui->refreshKeyListButton->setDisabled(true); + ui->syncButton->setDisabled(true); + thread->start(); } KeyIdArgsListPtr KeyList::getChecked(const KeyTable& key_table) { @@ -144,9 +160,9 @@ KeyIdArgsListPtr KeyList::getChecked(const KeyTable& key_table) { } KeyIdArgsListPtr KeyList::getChecked() { - auto key_list = qobject_cast<QTableWidget*>(mGroupTab->currentWidget()); + auto key_list = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); const auto& buffered_keys = - mKeyTables[mGroupTab->currentIndex()].buffered_keys; + mKeyTables[ui->keyGroupTab->currentIndex()].buffered_keys; auto ret = std::make_unique<KeyIdArgsList>(); for (int i = 0; i < key_list->rowCount(); i++) { if (key_list->item(i, 0)->checkState() == Qt::Checked) { @@ -157,9 +173,9 @@ KeyIdArgsListPtr KeyList::getChecked() { } KeyIdArgsListPtr KeyList::getAllPrivateKeys() { - auto key_list = qobject_cast<QTableWidget*>(mGroupTab->currentWidget()); + auto key_list = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); const auto& buffered_keys = - mKeyTables[mGroupTab->currentIndex()].buffered_keys; + mKeyTables[ui->keyGroupTab->currentIndex()].buffered_keys; auto ret = std::make_unique<KeyIdArgsList>(); for (int i = 0; i < key_list->rowCount(); i++) { if (key_list->item(i, 1) && buffered_keys[i].is_private_key()) { @@ -171,11 +187,11 @@ KeyIdArgsListPtr KeyList::getAllPrivateKeys() { KeyIdArgsListPtr KeyList::getPrivateChecked() { auto ret = std::make_unique<KeyIdArgsList>(); - if (mGroupTab->size().isEmpty()) return ret; + if (ui->keyGroupTab->size().isEmpty()) return ret; - auto key_list = qobject_cast<QTableWidget*>(mGroupTab->currentWidget()); + auto key_list = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); const auto& buffered_keys = - mKeyTables[mGroupTab->currentIndex()].buffered_keys; + mKeyTables[ui->keyGroupTab->currentIndex()].buffered_keys; for (int i = 0; i < key_list->rowCount(); i++) { if ((key_list->item(i, 0)->checkState() == Qt::Checked) && @@ -199,10 +215,10 @@ void KeyList::setChecked(const KeyIdArgsListPtr& keyIds, } void KeyList::setChecked(const KeyIdArgsListPtr& keyIds) { - if (mGroupTab->size().isEmpty()) return; - auto key_list = qobject_cast<QTableWidget*>(mGroupTab->currentWidget()); + if (ui->keyGroupTab->size().isEmpty()) return; + auto key_list = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); const auto& buffered_keys = - mKeyTables[mGroupTab->currentIndex()].buffered_keys; + mKeyTables[ui->keyGroupTab->currentIndex()].buffered_keys; if (!keyIds->empty()) { for (int i = 0; i < key_list->rowCount(); i++) { @@ -216,11 +232,11 @@ void KeyList::setChecked(const KeyIdArgsListPtr& keyIds) { KeyIdArgsListPtr KeyList::getSelected() { auto ret = std::make_unique<KeyIdArgsList>(); - if (mGroupTab->size().isEmpty()) return ret; + if (ui->keyGroupTab->size().isEmpty()) return ret; - auto key_list = qobject_cast<QTableWidget*>(mGroupTab->currentWidget()); + auto key_list = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); const auto& buffered_keys = - mKeyTables[mGroupTab->currentIndex()].buffered_keys; + mKeyTables[ui->keyGroupTab->currentIndex()].buffered_keys; for (int i = 0; i < key_list->rowCount(); i++) { if (key_list->item(i, 0)->isSelected() == 1) { @@ -231,8 +247,8 @@ KeyIdArgsListPtr KeyList::getSelected() { } [[maybe_unused]] bool KeyList::containsPrivateKeys() { - if (mGroupTab->size().isEmpty()) return false; - mKeyList = qobject_cast<QTableWidget*>(mGroupTab->currentWidget()); + if (ui->keyGroupTab->size().isEmpty()) return false; + mKeyList = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); for (int i = 0; i < mKeyList->rowCount(); i++) { if (mKeyList->item(i, 1)) { @@ -243,15 +259,15 @@ KeyIdArgsListPtr KeyList::getSelected() { } void KeyList::setColumnWidth(int row, int size) { - if (mGroupTab->size().isEmpty()) return; - mKeyList = qobject_cast<QTableWidget*>(mGroupTab->currentWidget()); + if (ui->keyGroupTab->size().isEmpty()) return; + mKeyList = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); mKeyList->setColumnWidth(row, size); } void KeyList::contextMenuEvent(QContextMenuEvent* event) { - if (mGroupTab->size().isEmpty()) return; - mKeyList = qobject_cast<QTableWidget*>(mGroupTab->currentWidget()); + if (ui->keyGroupTab->size().isEmpty()) return; + mKeyList = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget()); if (mKeyList->selectedItems().length() > 0) { popupMenu->exec(event->globalPos()); @@ -275,8 +291,16 @@ void KeyList::dropEvent(QDropEvent* event) { // "always import keys"-CheckBox auto* checkBox = new QCheckBox(_("Always import without bothering.")); - if (settings.value("general/confirmImportKeys").toBool()) - checkBox->setCheckState(Qt::Unchecked); + + auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); + bool confirm_import_keys = true; + try { + confirm_import_keys = settings.lookup("general.confirm_import_keys"); + LOG(INFO) << "confirm_import_keys" << confirm_import_keys; + if (confirm_import_keys) checkBox->setCheckState(Qt::Checked); + } catch (...) { + LOG(ERROR) << _("Setting Operation Error") << _("confirm_import_keys"); + } // Buttons for ok and cancel auto* buttonBox = @@ -291,16 +315,21 @@ void KeyList::dropEvent(QDropEvent* event) { dialog->setLayout(vbox); - if (settings.value("general/confirmImportKeys", Qt::Checked).toBool()) { + if (confirm_import_keys) { dialog->exec(); - if (dialog->result() == QDialog::Rejected) { - return; - } - if (checkBox->isChecked()) { - settings.setValue("general/confirmImportKeys", false); - } else { - settings.setValue("general/confirmImportKeys", true); + if (dialog->result() == QDialog::Rejected) return; + + if (!settings.exists("general") || + settings.lookup("general").getType() != libconfig::Setting::TypeGroup) + settings.add("general", libconfig::Setting::TypeGroup); + auto& general = settings["general"]; + if (!general.exists("confirm_import_keys")) + general.add("confirm_import_keys", libconfig::Setting::TypeBoolean) = + checkBox->isChecked(); + else { + general["confirm_import_keys"] = checkBox->isChecked(); } + GlobalSettingStation::GetInstance().Sync(); } if (event->mimeData()->hasUrls()) { @@ -335,17 +364,18 @@ void KeyList::dragEnterEvent(QDragEnterEvent* event) { void KeyList::importKeys(const QByteArray& inBuffer) { auto std_buffer = std::make_unique<ByteArray>(inBuffer.toStdString()); GpgImportInformation result = - GpgKeyImportExportor::GetInstance().ImportKey(std::move(std_buffer)); + GpgKeyImportExportor::GetInstance(_m_key_list_id) + .ImportKey(std::move(std_buffer)); new KeyImportDetailDialog(result, false, this); } void KeyList::slotDoubleClicked(const QModelIndex& index) { - if (mGroupTab->size().isEmpty()) return; + if (ui->keyGroupTab->size().isEmpty()) return; const auto& buffered_keys = - mKeyTables[mGroupTab->currentIndex()].buffered_keys; + mKeyTables[ui->keyGroupTab->currentIndex()].buffered_keys; if (mAction != nullptr) { - const auto key = - GpgKeyGetter::GetInstance().GetKey(buffered_keys[index.row()].id()); + const auto key = GpgKeyGetter::GetInstance(_m_key_list_id) + .GetKey(buffered_keys[index.row()].id()); mAction(key, this); } } @@ -356,9 +386,9 @@ void KeyList::setDoubleClickedAction( } std::string KeyList::getSelectedKey() { - if (mGroupTab->size().isEmpty()) return {}; + if (ui->keyGroupTab->size().isEmpty()) return {}; const auto& buffered_keys = - mKeyTables[mGroupTab->currentIndex()].buffered_keys; + mKeyTables[ui->keyGroupTab->currentIndex()].buffered_keys; for (int i = 0; i < mKeyList->rowCount(); i++) { if (mKeyList->item(i, 0)->isSelected() == 1) { @@ -368,6 +398,55 @@ std::string KeyList::getSelectedKey() { return {}; } +void KeyList::slotRefreshUI() { + LOG(INFO) << _("Called") << _buffered_keys_list.get(); + if (_buffered_keys_list != nullptr) { + std::lock_guard<std::mutex> guard(buffered_key_list_mutex); + for (auto& key_table : mKeyTables) { + key_table.Refresh(GpgKeyGetter::GetKeysCopy(_buffered_keys_list)); + } + } + emit signalRefreshStatusBar(_("Key List Refreshed."), 1000); + ui->refreshKeyListButton->setDisabled(false); + ui->syncButton->setDisabled(false); +} + +void KeyList::slotSyncWithKeyServer() { + KeyIdArgsList key_ids; + { + std::lock_guard<std::mutex> guard(buffered_key_list_mutex); + for (const auto& key : *_buffered_keys_list) { + if (!(key.is_private_key() && key.has_master_key())) + key_ids.push_back(key.id()); + } + } + + ui->refreshKeyListButton->setDisabled(true); + ui->syncButton->setDisabled(true); + + emit signalRefreshStatusBar(_("Syncing Key List..."), 3000); + CommonUtils::slotImportKeyFromKeyServer( + _m_key_list_id, key_ids, + [=](const std::string& key_id, const std::string& status, + size_t current_index, size_t all_index) { + LOG(INFO) << _("Called") << key_id << status << current_index + << all_index; + auto key = GpgKeyGetter::GetInstance(_m_key_list_id).GetKey(key_id); + + boost::format status_str = boost::format(_("Sync [%1%/%2%] %3% %4%")) % + current_index % all_index % + key.uids()->front().uid() % status; + emit signalRefreshStatusBar(status_str.str().c_str(), 1500); + + if (current_index == all_index) { + ui->syncButton->setDisabled(false); + ui->refreshKeyListButton->setDisabled(false); + emit signalRefreshStatusBar(_("Key List Sync Done."), 3000); + emit signalRefreshDatabase(); + } + }); +} + KeyIdArgsListPtr KeyTable::GetChecked() { auto ret = std::make_unique<KeyIdArgsList>(); for (int i = 0; i < key_list->rowCount(); i++) { @@ -389,14 +468,22 @@ void KeyTable::SetChecked(const KeyIdArgsListPtr& key_ids) { } } -void KeyTable::Refresh() { +void KeyTable::Refresh(KeyLinkListPtr m_keys) { + LOG(INFO) << "Called"; + auto checked_key_list = GetChecked(); // while filling the table, sort enabled causes errors key_list->setSortingEnabled(false); key_list->clearContents(); - auto keys = GpgKeyGetter::GetInstance().FetchKey(); + // Optimization for copy + KeyLinkListPtr keys = nullptr; + if (m_keys == nullptr) + keys = GpgKeyGetter::GetInstance().FetchKey(); + else + keys = std::move(m_keys); + auto it = keys->begin(); int row_count = 0; @@ -425,7 +512,7 @@ void KeyTable::Refresh() { table_buffered_keys.clear(); while (it != keys->end()) { - table_buffered_keys.push_back(GpgKeyGetter::GetInstance().GetKey(it->id())); + table_buffered_keys.push_back(it->copy()); auto* tmp0 = new QTableWidgetItem(QString::number(row_index)); tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | @@ -491,5 +578,7 @@ void KeyTable::Refresh() { } SetChecked(checked_key_list); + + LOG(INFO) << "End"; } } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/KeyList.h b/src/ui/widgets/KeyList.h index f09ae2ac..617bb274 100644 --- a/src/ui/widgets/KeyList.h +++ b/src/ui/widgets/KeyList.h @@ -29,6 +29,9 @@ #include "gpg/GpgContext.h" #include "ui/KeyImportDetailDialog.h" + +class Ui_KeyList; + namespace GpgFrontend::UI { struct KeyListRow { @@ -68,7 +71,7 @@ struct KeyTable { info_type(_info_type), filter(std::move(_filter)) {} - void Refresh(); + void Refresh(KeyLinkListPtr m_keys = nullptr); KeyIdArgsListPtr GetChecked(); @@ -79,14 +82,7 @@ class KeyList : public QWidget { Q_OBJECT public: - explicit KeyList( - KeyListRow::KeyType selectType = KeyListRow::SECRET_OR_PUBLIC_KEY, - KeyListColumn::InfoType infoType = KeyListColumn::ALL, - const std::function<bool(const GpgKey&)>& filter = - [](const GpgKey&) -> bool { return true; }, - QWidget* parent = nullptr); - - explicit KeyList(QWidget* parent); + explicit KeyList(bool menu, QWidget* parent = nullptr); void addListGroupTab( const QString& name, @@ -116,6 +112,10 @@ class KeyList : public QWidget { [[maybe_unused]] bool containsPrivateKeys(); + signals: + void signalRefreshStatusBar(const QString& message, int timeout); + void signalRefreshDatabase(); + public slots: void slotRefresh(); @@ -124,22 +124,26 @@ class KeyList : public QWidget { void init(); void importKeys(const QByteArray& inBuffer); - QString appPath; - QSettings settings; + static int key_list_id; + int _m_key_list_id; + std::mutex buffered_key_list_mutex; - QTabWidget* mGroupTab{}; + std::shared_ptr<Ui_KeyList> ui; QTableWidget* mKeyList{}; - std::vector<KeyTable> mKeyTables; - QMenu* popupMenu{}; - + GpgFrontend::KeyLinkListPtr _buffered_keys_list; std::function<void(const GpgKey&, QWidget*)> mAction = nullptr; + bool menu_status = false; private slots: void slotDoubleClicked(const QModelIndex& index); + void slotRefreshUI(); + + void slotSyncWithKeyServer(); + protected: void contextMenuEvent(QContextMenuEvent* event) override; diff --git a/src/ui/widgets/SignersPicker.cpp b/src/ui/widgets/SignersPicker.cpp index 997ee27a..e769d05c 100644 --- a/src/ui/widgets/SignersPicker.cpp +++ b/src/ui/widgets/SignersPicker.cpp @@ -31,8 +31,9 @@ SignersPicker::SignersPicker(QWidget* parent) : QDialog(parent) { connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(accept())); /*Setup KeyList*/ - mKeyList = new KeyList( - KeyListRow::ONLY_SECRET_KEY, + mKeyList = new KeyList(false, this); + mKeyList->addListGroupTab( + _("Signers"), KeyListRow::ONLY_SECRET_KEY, KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage, [](const GpgKey& key) -> bool { if (!key.CanSignActual()) @@ -40,14 +41,13 @@ SignersPicker::SignersPicker(QWidget* parent) : QDialog(parent) { else return true; }); - mKeyList->slotRefresh(); auto* vbox2 = new QVBoxLayout(); vbox2->addWidget(new QLabel(QString(_("Select Signer(s)")) + ": ")); vbox2->addWidget(mKeyList); vbox2->addWidget(new QLabel( - _("Selecting Nothing will eventually use default key to sign."))); + _("If any key is selected, the default key will be used for signing."))); vbox2->addWidget(confirmButton); vbox2->addStretch(0); setLayout(vbox2); |