Merge branch 'develop' of github.com:saturneric/GpgFrontend into develop-ci

This commit is contained in:
Saturneric 2021-12-06 13:58:52 +08:00
commit b86aa03e5f
28 changed files with 971 additions and 790 deletions

View File

@ -43,7 +43,6 @@ jobs:
- name: Git Sumbodule Update - name: Git Sumbodule Update
run: | run: |
git pull --recurse-submodules
git submodule update --init --recursive git submodule update --init --recursive
- name: Codesign Configuration (macOS) - name: Codesign Configuration (macOS)

View File

@ -42,6 +42,10 @@ jobs:
sudo apt-get -y install libgcrypt11-dev libnss3-dev libpci-dev libpulse-dev libudev-dev libxtst-dev gyp ninja-build sudo apt-get -y install libgcrypt11-dev libnss3-dev libpci-dev libpulse-dev libudev-dev libxtst-dev gyp ninja-build
sudo apt-get -y install libglu1-mesa-dev libfontconfig1-dev libx11-xcb-dev libicu-dev libxcb-image0 sudo apt-get -y install libglu1-mesa-dev libfontconfig1-dev libx11-xcb-dev libicu-dev libxcb-image0
sudo apt-get -y install libglu1-mesa-dev libfontconfig1-dev libx11-xcb-dev libicu-dev libxcb-* sudo apt-get -y install libglu1-mesa-dev libfontconfig1-dev libx11-xcb-dev libicu-dev libxcb-*
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 8
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 8
sudo update-alternatives --set gcc "/usr/bin/gcc-8"
sudo update-alternatives --set g++ "/usr/bin/g++-8"
if: matrix.os == 'ubuntu-18.04' if: matrix.os == 'ubuntu-18.04'
- name: Codesign Configuration (macOS) - name: Codesign Configuration (macOS)

View File

@ -25,7 +25,9 @@
<file alias="decrypted_verified.png">resource/icons/decrypted_verified.png</file> <file alias="decrypted_verified.png">resource/icons/decrypted_verified.png</file>
<file alias="exit.png">resource/icons/exit.png</file> <file alias="exit.png">resource/icons/exit.png</file>
<file alias="export_key_to_file.png">resource/icons/export_key_to_file.png</file> <file alias="export_key_to_file.png">resource/icons/export_key_to_file.png</file>
<file alias="file.png">resource/icons/file.png</file>
<file alias="fileencryption.png">resource/icons/fileencrytion.png</file> <file alias="fileencryption.png">resource/icons/fileencrytion.png</file>
<file alias="file-browser.png">resource/icons/file-browser.png</file>
<file alias="fileopen.png">resource/icons/fileopen.png</file> <file alias="fileopen.png">resource/icons/fileopen.png</file>
<file alias="fileprint.png">resource/icons/fileprint.png</file> <file alias="fileprint.png">resource/icons/fileprint.png</file>
<file alias="filesave.png">resource/icons/filesave.png</file> <file alias="filesave.png">resource/icons/filesave.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
resource/icons/file.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -24,6 +24,8 @@
#include "gpg/result_analyse/VerifyResultAnalyse.h" #include "gpg/result_analyse/VerifyResultAnalyse.h"
#include <boost/format.hpp>
#include "GpgFrontend.h" #include "GpgFrontend.h"
#include "gpg/GpgConstants.h" #include "gpg/GpgConstants.h"
#include "gpg/function/GpgKeyGetter.h" #include "gpg/function/GpgKeyGetter.h"
@ -59,14 +61,18 @@ void GpgFrontend::VerifyResultAnalyse::do_analyse() {
boost::posix_time::from_time_t(sign->timestamp)) boost::posix_time::from_time_t(sign->timestamp))
<< std::endl; << std::endl;
stream << std::endl << "[>] " << _("Signatures") << ":" << std::endl; stream << std::endl << "[>] " << _("Signatures List") << ":" << std::endl;
bool canContinue = true; bool canContinue = true;
int count = 1;
while (sign && canContinue) { while (sign && canContinue) {
stream << boost::format(_("Signature [%1%]:")) % count++ << std::endl;
switch (gpg_err_code(sign->status)) { switch (gpg_err_code(sign->status)) {
case GPG_ERR_BAD_SIGNATURE: case GPG_ERR_BAD_SIGNATURE:
stream << _("One or More Bad Signatures.") << std::endl; stream << _("A Bad Signature.") << std::endl;
print_signer(stream, sign);
stream << _("This Signature is invalid.") << std::endl;
canContinue = false; canContinue = false;
setStatus(-1); setStatus(-1);
break; break;
@ -173,14 +179,17 @@ bool GpgFrontend::VerifyResultAnalyse::print_signer(std::stringstream &stream,
stream << " " << _("Signed By") << ": " << key.uids()->front().uid() stream << " " << _("Signed By") << ": " << key.uids()->front().uid()
<< std::endl; << std::endl;
} }
stream << " " << _("Public Key Algo") << ": " if (sign->pubkey_algo)
<< gpgme_pubkey_algo_name(sign->pubkey_algo) << std::endl; stream << " " << _("Public Key Algo") << ": "
stream << " " << _("Hash Algo") << ": " << gpgme_pubkey_algo_name(sign->pubkey_algo) << std::endl;
<< gpgme_hash_algo_name(sign->hash_algo) << std::endl; if (sign->hash_algo)
stream << " " << _("Date & Time") << ": " stream << " " << _("Hash Algo") << ": "
<< boost::posix_time::to_iso_string( << gpgme_hash_algo_name(sign->hash_algo) << std::endl;
boost::posix_time::from_time_t(sign->timestamp)) if (sign->timestamp)
<< std::endl; stream << " " << _("Date & Time") << ": "
<< boost::posix_time::to_iso_string(
boost::posix_time::from_time_t(sign->timestamp))
<< std::endl;
stream << std::endl; stream << std::endl;
return keyFound; return keyFound;
} }

View File

@ -86,32 +86,43 @@ FileEncryptionDialog::FileEncryptionDialog(KeyIdArgsListPtr keyList,
groupBox1->setLayout(gLayout); groupBox1->setLayout(gLayout);
/*Setup KeyList*/ /*Setup KeyList*/
mKeyList = new KeyList(
KeyListRow::ONLY_SECRET_KEY,
KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage);
if (mAction == Verify)
mKeyList->setFilter([](const GpgKey& key) -> bool {
if (key.disabled() || key.expired() || key.revoked())
return false;
else
return true;
});
if (mAction == Encrypt) if (mAction == Verify) {
mKeyList->setFilter([](const GpgKey& key) -> bool { mKeyList =
if (!key.CanEncrActual()) new KeyList(KeyListRow::ONLY_SECRET_KEY,
return false; KeyListColumn::NAME | KeyListColumn::EmailAddress |
else KeyListColumn::Usage,
return true; [](const GpgKey& key) -> bool {
}); if (key.disabled() || key.expired() || key.revoked())
return false;
else
return true;
});
}
if (mAction == Sign) if (mAction == Encrypt) {
mKeyList->setFilter([](const GpgKey& key) -> bool { mKeyList = new KeyList(KeyListRow::ONLY_SECRET_KEY,
if (!key.CanSignActual()) KeyListColumn::NAME | KeyListColumn::EmailAddress |
return false; KeyListColumn::Usage,
else [](const GpgKey& key) -> bool {
return true; if (!key.CanEncrActual())
}); return false;
else
return true;
});
}
if (mAction == Encrypt) {
mKeyList = new KeyList(KeyListRow::ONLY_SECRET_KEY,
KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage,
[](const GpgKey& key) -> bool {
if (!key.CanSignActual())
return false;
else
return true;
});
}
if (mAction == Decrypt) mKeyList->setDisabled(true); if (mAction == Decrypt) mKeyList->setDisabled(true);

View File

@ -36,9 +36,49 @@
namespace GpgFrontend::UI { namespace GpgFrontend::UI {
KeyMgmt::KeyMgmt(QWidget* parent) : QMainWindow(parent) { KeyMgmt::KeyMgmt(QWidget* parent) : QMainWindow(parent) {
/* the list of Keys available*/ /* the list of Keys available*/
mKeyList = new KeyList(); mKeyList = new KeyList(this);
mKeyList->setColumnWidth(2, 250);
mKeyList->setColumnWidth(3, 250); mKeyList->addListGroupTab(_("All"), KeyListRow::SECRET_OR_PUBLIC_KEY);
mKeyList->addListGroupTab(
_("Only Public Key"), KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key) -> bool {
return !key.is_private_key() &&
!(key.revoked() || key.disabled() || key.expired());
});
mKeyList->addListGroupTab(
_("Has Private Key"), KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key) -> bool {
return key.is_private_key() &&
!(key.revoked() || key.disabled() || key.expired());
});
mKeyList->addListGroupTab(
_("No Master Key"), KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key) -> bool {
return !key.has_master_key() &&
!(key.revoked() || key.disabled() || key.expired());
});
mKeyList->addListGroupTab(
_("Revoked"), KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key) -> bool { return key.revoked(); });
mKeyList->addListGroupTab(
_("Expired"), KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key) -> bool { return key.expired(); });
setCentralWidget(mKeyList); setCentralWidget(mKeyList);
mKeyList->setDoubleClickedAction([this](const GpgKey& key, QWidget* parent) { mKeyList->setDoubleClickedAction([this](const GpgKey& key, QWidget* parent) {
new KeyDetailsDialog(key, parent); new KeyDetailsDialog(key, parent);

View File

@ -59,14 +59,7 @@ void MainWindow::init() noexcept {
setCentralWidget(edit); setCentralWidget(edit);
/* the list of Keys available*/ /* the list of Keys available*/
mKeyList = new KeyList(KeyListRow::SECRET_OR_PUBLIC_KEY, mKeyList = new KeyList(this);
KeyListColumn::TYPE | KeyListColumn::NAME |
KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
this);
mKeyList->setFilter([](const GpgKey& key) -> bool {
return !(key.revoked() || key.disabled() || key.expired());
});
mKeyList->slotRefresh(); mKeyList->slotRefresh();
@ -144,7 +137,6 @@ void MainWindow::init() noexcept {
&MainWindow::slotVersionUpgrade); &MainWindow::slotVersionUpgrade);
version_thread->start(); version_thread->start();
#endif #endif
} catch (...) { } catch (...) {
@ -244,7 +236,6 @@ void MainWindow::restoreSettings() {
// icons ize // icons ize
this->setIconSize(QSize(width, height)); this->setIconSize(QSize(width, height));
importButton->setIconSize(QSize(width, height)); importButton->setIconSize(QSize(width, height));
fileEncButton->setIconSize(QSize(width, height));
if (!settings.exists("keyserver") || if (!settings.exists("keyserver") ||
settings.lookup("keyserver").getType() != libconfig::Setting::TypeGroup) settings.lookup("keyserver").getType() != libconfig::Setting::TypeGroup)
@ -279,7 +270,6 @@ void MainWindow::restoreSettings() {
auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style); auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style);
this->setToolButtonStyle(icon_style); this->setToolButtonStyle(icon_style);
importButton->setToolButtonStyle(icon_style); importButton->setToolButtonStyle(icon_style);
fileEncButton->setToolButtonStyle(icon_style);
if (!settings.exists("general") || if (!settings.exists("general") ||
settings.lookup("general").getType() != libconfig::Setting::TypeGroup) settings.lookup("general").getType() != libconfig::Setting::TypeGroup)
@ -300,12 +290,12 @@ void MainWindow::restoreSettings() {
general.add("save_key_checked_key_ids", libconfig::Setting::TypeList); general.add("save_key_checked_key_ids", libconfig::Setting::TypeList);
} }
auto key_ids_ptr = std::make_unique<KeyIdArgsList>(); auto key_ids_ptr = std::make_unique<KeyIdArgsList>();
;
auto& save_key_checked_key_ids = general["save_key_checked_key_ids"]; auto& save_key_checked_key_ids = general["save_key_checked_key_ids"];
const auto key_ids_size = const auto key_ids_size =
general.lookup("save_key_checked_key_ids").getLength(); general.lookup("save_key_checked_key_ids").getLength();
for (auto i = 0; i < key_ids_size; i++) { for (auto i = 0; i < key_ids_size; i++) {
std::string key_id = save_key_checked_key_ids[i]; std::string key_id = save_key_checked_key_ids[i];
LOG(INFO) << "get checked key id" << key_id;
key_ids_ptr->push_back(key_id); key_ids_ptr->push_back(key_id);
} }
mKeyList->setChecked(key_ids_ptr); mKeyList->setChecked(key_ids_ptr);

View File

@ -24,6 +24,8 @@
#include "SignalStation.h" #include "SignalStation.h"
namespace GpgFrontend::UI {
std::unique_ptr<SignalStation> SignalStation::_instance = nullptr; std::unique_ptr<SignalStation> SignalStation::_instance = nullptr;
SignalStation* SignalStation::GetInstance() { SignalStation* SignalStation::GetInstance() {
@ -32,3 +34,5 @@ SignalStation* SignalStation::GetInstance() {
} }
return _instance.get(); return _instance.get();
} }
} // namespace GpgFrontend::UI

View File

@ -26,6 +26,9 @@
#define GPGFRONTEND_SIGNALSTATION_H #define GPGFRONTEND_SIGNALSTATION_H
#include "ui/GpgFrontendUI.h" #include "ui/GpgFrontendUI.h"
#include "ui/widgets/InfoBoardWidget.h"
namespace GpgFrontend::UI {
class SignalStation : public QObject { class SignalStation : public QObject {
Q_OBJECT Q_OBJECT
@ -36,6 +39,11 @@ class SignalStation : public QObject {
signals: signals:
void KeyDatabaseRefresh(); void KeyDatabaseRefresh();
void signalRefreshInfoBoard(const QString& text,
InfoBoardStatus verify_label_status);
}; };
} // namespace GpgFrontend::UI
#endif // GPGFRONTEND_SIGNALSTATION_H #endif // GPGFRONTEND_SIGNALSTATION_H

View File

@ -50,7 +50,6 @@ void refresh_info_board(InfoBoardWidget* info_board, int status,
void process_result_analyse(TextEdit* edit, InfoBoardWidget* info_board, void process_result_analyse(TextEdit* edit, InfoBoardWidget* info_board,
const ResultAnalyse& result_analyse) { const ResultAnalyse& result_analyse) {
info_board->associateTabWidget(edit->tabWidget); info_board->associateTabWidget(edit->tabWidget);
info_board->associateFileTreeView(edit->curFilePage());
refresh_info_board(info_board, result_analyse.getStatus(), refresh_info_board(info_board, result_analyse.getStatus(),
result_analyse.getResultReport()); result_analyse.getResultReport());
} }
@ -61,8 +60,7 @@ void process_result_analyse(TextEdit* edit, InfoBoardWidget* info_board,
LOG(INFO) << "process_result_analyse Started"; LOG(INFO) << "process_result_analyse Started";
info_board->associateTabWidget(edit->tabWidget); info_board->associateTabWidget(edit->tabWidget);
info_board->associateFileTreeView(edit->curFilePage());
refresh_info_board( refresh_info_board(
info_board, info_board,
std::min(result_analyse_a.getStatus(), result_analyse_b.getStatus()), std::min(result_analyse_a.getStatus(), result_analyse_b.getStatus()),

View File

@ -104,73 +104,17 @@ IntroPage::IntroPage(QWidget* parent) : QWizardPage(parent) {
"system, GpgFrontend will automatically set it.")); "system, GpgFrontend will automatically set it."));
langLabel->setWordWrap(true); langLabel->setWordWrap(true);
languages = SettingsDialog::listLanguages();
auto* langSelectBox = new QComboBox();
for (const auto& l : languages) {
langSelectBox->addItem(l);
}
// selected entry from config
// auto lang = "";
// auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
// try {
// lang = settings.lookup("general.lang");
// } catch (...) {
// LOG(INFO) << "Read for general.lang failed";
// }
//
// QString langKey = lang;
// QString langValue = languages.value(langKey);
// LOG(INFO) << "lang key" << langKey.toStdString() << "lang value"
// << langValue.toStdString();
// langSelectBox->setCurrentIndex(langSelectBox->findText(langValue));
// connect(langSelectBox, SIGNAL(currentIndexChanged(QString)), this,
// SLOT(slotLangChange(QString)));
// set layout and add widgets // set layout and add widgets
auto* layout = new QVBoxLayout; auto* layout = new QVBoxLayout;
layout->addWidget(topLabel); layout->addWidget(topLabel);
layout->addStretch(); layout->addStretch();
#ifdef MULTI_LANG_SUPPORT
layout->addWidget(langLabel); layout->addWidget(langLabel);
// layout->addWidget(langSelectBox); #endif
setLayout(layout); setLayout(layout);
} }
// void IntroPage::slotLangChange(const QString& lang) {
// auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
//
// if (!settings.exists("general") ||
// settings.lookup("general").getType() != libconfig::Setting::TypeGroup)
// settings.add("general", libconfig::Setting::TypeGroup);
//
// auto& general = settings["general"];
// if (!general.exists("lang"))
// general.add("lang", libconfig::Setting::TypeString) =
// languages.key(lang).toStdString();
// else {
// general["lang"] = languages.key(lang).toStdString();
// }
//
// if (!settings.exists("wizard") ||
// settings.lookup("wizard").getType() != libconfig::Setting::TypeGroup)
// settings.add("wizard", libconfig::Setting::TypeGroup);
//
// auto& wizard = settings["wizard"];
// if (!wizard.exists("next_page"))
// wizard.add("next_page", libconfig::Setting::TypeInt) =
// this->wizard()->currentId();
// else {
// wizard["next_page"] = this->wizard()->currentId();
// }
//
// GlobalSettingStation::GetInstance().Sync();
//
// qApp->exit(RESTART_CODE);
// }
int IntroPage::nextId() const { return Wizard::Page_Choose; } int IntroPage::nextId() const { return Wizard::Page_Choose; }
ChoosePage::ChoosePage(QWidget* parent) : QWizardPage(parent) { ChoosePage::ChoosePage(QWidget* parent) : QWizardPage(parent) {

View File

@ -40,14 +40,12 @@ class Wizard : public QWizard {
public: public:
enum WizardPages { Page_Intro, Page_Choose, Page_GenKey, Page_Conclusion }; enum WizardPages { Page_Intro, Page_Choose, Page_GenKey, Page_Conclusion };
Wizard(QWidget* parent = nullptr); explicit Wizard(QWidget* parent = nullptr);
private slots: private slots:
void slotWizardAccepted(); void slotWizardAccepted();
signals: signals:
void signalOpenHelp(QString page); void signalOpenHelp(QString page);
}; };
@ -57,14 +55,7 @@ class IntroPage : public QWizardPage {
public: public:
explicit IntroPage(QWidget* parent = nullptr); explicit IntroPage(QWidget* parent = nullptr);
QHash<QString, QString> languages;
[[nodiscard]] int nextId() const override; [[nodiscard]] int nextId() const override;
private:
private slots:
// void slotLangChange(const QString& lang);
}; };
class ChoosePage : public QWizardPage { class ChoosePage : public QWizardPage {

View File

@ -33,18 +33,18 @@ namespace GpgFrontend::UI {
KeyUIDSignDialog::KeyUIDSignDialog(const GpgKey& key, UIDArgsListPtr uid, KeyUIDSignDialog::KeyUIDSignDialog(const GpgKey& key, UIDArgsListPtr uid,
QWidget* parent) QWidget* parent)
: QDialog(parent), mUids(std::move(uid)), mKey(key) { : QDialog(parent), mUids(std::move(uid)), mKey(key) {
mKeyList = const auto key_id = mKey.id();
new KeyList(KeyListRow::ONLY_SECRET_KEY, mKeyList = new KeyList(
KeyListColumn::NAME | KeyListColumn::EmailAddress, this); KeyListRow::ONLY_SECRET_KEY,
KeyListColumn::NAME | KeyListColumn::EmailAddress,
mKeyList->setFilter([](const GpgKey& key) -> bool { [key_id](const GpgKey& key) -> bool {
if (key.disabled() || !key.can_certify() || !key.has_master_key() || if (key.disabled() || !key.can_certify() || !key.has_master_key() ||
key.expired() || key.revoked()) key.expired() || key.revoked() || key_id == key.id())
return false; return false;
else else
return true; return true;
}); },
mKeyList->setExcludeKeys({key.id()}); this);
mKeyList->slotRefresh(); mKeyList->slotRefresh();
signKeyButton = new QPushButton("Sign"); signKeyButton = new QPushButton("Sign");

View File

@ -164,15 +164,6 @@ void MainWindow::slotFileSign() {
if (!file_pre_check(this, path)) return; if (!file_pre_check(this, path)) return;
if (QFile::exists(path + ".sig")) {
auto ret = QMessageBox::warning(
this, _("Warning"),
_("The target file already exists, do you need to overwrite it?"),
QMessageBox::Ok | QMessageBox::Cancel);
if (ret == QMessageBox::Cancel) return;
}
auto key_ids = mKeyList->getChecked(); auto key_ids = mKeyList->getChecked();
auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids); auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
@ -193,6 +184,18 @@ void MainWindow::slotFileSign() {
} }
} }
auto sig_file_path = boost::filesystem::path(path.toStdString() + ".sig");
if (QFile::exists(sig_file_path.string().c_str())) {
auto ret = QMessageBox::warning(
this, _("Warning"),
QString(_("The signature file \"%1\" exists, "
"do you need to overwrite it?"))
.arg(sig_file_path.filename().string().c_str()),
QMessageBox::Ok | QMessageBox::Cancel);
if (ret == QMessageBox::Cancel) return;
}
GpgSignResult result = nullptr; GpgSignResult result = nullptr;
gpgme_error_t error; gpgme_error_t error;
bool if_error = false; bool if_error = false;
@ -242,12 +245,22 @@ void MainWindow::slotFileVerify() {
signFilePath = path + ".sig"; signFilePath = path + ".sig";
} }
bool ok;
QString text =
QInputDialog::getText(this, _("Origin file to verify"), _("Filepath"),
QLineEdit::Normal, dataFilePath, &ok);
if (ok && !text.isEmpty()) {
dataFilePath = text;
} else {
return;
}
QFileInfo dataFileInfo(dataFilePath), signFileInfo(signFilePath); QFileInfo dataFileInfo(dataFilePath), signFileInfo(signFilePath);
if (!dataFileInfo.isFile() || !signFileInfo.isFile()) { if (!dataFileInfo.isFile() || !signFileInfo.isFile()) {
QMessageBox::critical( QMessageBox::critical(
this, _("Error"), this, _("Error"),
_("Please select the appropriate target file or signature file. " _("Please select the appropriate origin file or signature file. "
"Ensure that both are in this directory.")); "Ensure that both are in this directory."));
return; return;
} }
@ -433,8 +446,6 @@ void MainWindow::slotFileDecryptVerify() {
}); });
if (!if_error) { if (!if_error) {
infoBoard->associateFileTreeView(edit->curFilePage());
auto decrypt_res = DecryptResultAnalyse(error, std::move(d_result)); auto decrypt_res = DecryptResultAnalyse(error, std::move(d_result));
auto verify_res = VerifyResultAnalyse(error, std::move(v_result)); auto verify_res = VerifyResultAnalyse(error, std::move(v_result));
decrypt_res.analyse(); decrypt_res.analyse();

View File

@ -46,181 +46,166 @@ namespace GpgFrontend::UI {
* Encrypt Entry(Text & File) * Encrypt Entry(Text & File)
*/ */
void MainWindow::slotEncrypt() { void MainWindow::slotEncrypt() {
if (edit->tabCount() == 0) return; if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return;
if (edit->slotCurPageTextEdit() != nullptr) { auto key_ids = mKeyList->getChecked();
auto key_ids = mKeyList->getChecked();
if (key_ids->empty()) { if (key_ids->empty()) {
QMessageBox::critical(nullptr, _("No Key Selected"), QMessageBox::critical(nullptr, _("No Key Selected"), _("No Key Selected"));
_("No Key Selected")); return;
}
auto key_getter = GpgFrontend::GpgKeyGetter::GetInstance();
auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
for (const auto& key : *keys) {
if (!key.CanEncrActual()) {
QMessageBox::information(
nullptr, _("Invalid Operation"),
QString(
_("The selected key contains a key that does not actually have a "
"encrypt usage.")) +
"<br/><br/>" + _("For example the Following Key:") + " <br/>" +
QString::fromStdString(key.uids()->front().uid()));
return; return;
} }
}
auto key_getter = GpgFrontend::GpgKeyGetter::GetInstance(); auto tmp = std::make_unique<ByteArray>();
auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
for (const auto& key : *keys) { GpgEncrResult result = nullptr;
if (!key.CanEncrActual()) { GpgError error;
QMessageBox::information( bool if_error = false;
nullptr, _("Invalid Operation"), process_operation(this, _("Encrypting"), [&]() {
QString(_( try {
"The selected key contains a key that does not actually have a " auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString();
"encrypt usage.")) + error = GpgFrontend::BasicOperator::GetInstance().Encrypt(
"<br/><br/>" + _("For example the Following Key:") + " <br/>" + std::move(keys), buffer, tmp, result);
QString::fromStdString(key.uids()->front().uid())); } catch (const std::runtime_error& e) {
return; if_error = true;
}
} }
});
auto tmp = std::make_unique<ByteArray>(); if (!if_error) {
auto resultAnalyse = EncryptResultAnalyse(error, std::move(result));
resultAnalyse.analyse();
process_result_analyse(edit, infoBoard, resultAnalyse);
GpgEncrResult result = nullptr; if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
GpgError error; edit->slotFillTextEditWithText(QString::fromStdString(*tmp));
bool if_error = false;
process_operation(this, _("Encrypting"), [&]() {
try {
auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString();
error = GpgFrontend::BasicOperator::GetInstance().Encrypt(
std::move(keys), buffer, tmp, result);
} catch (const std::runtime_error& e) {
if_error = true;
}
});
if (!if_error) {
auto resultAnalyse = EncryptResultAnalyse(error, std::move(result));
resultAnalyse.analyse();
process_result_analyse(edit, infoBoard, resultAnalyse);
if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
edit->slotFillTextEditWithText(QString::fromStdString(*tmp));
#ifdef SMTP_SUPPORT #ifdef SMTP_SUPPORT
// set optional actions // set optional actions
if (resultAnalyse.getStatus() >= 0) { if (resultAnalyse.getStatus() >= 0) {
infoBoard->resetOptionActionsMenu(); infoBoard->resetOptionActionsMenu();
infoBoard->addOptionalAction("Send Mail", [this]() { infoBoard->addOptionalAction("Send Mail", [this]() {
if (settings.value("sendMail/enable", false).toBool()) if (settings.value("sendMail/enable", false).toBool())
new SendMailDialog(edit->curTextPage()->toPlainText(), this); new SendMailDialog(edit->curTextPage()->toPlainText(), this);
else { else {
QMessageBox::warning(nullptr, _("Function Disabled"), QMessageBox::warning(nullptr, _("Function Disabled"),
_("Please go to the settings interface to " _("Please go to the settings interface to "
"enable and configure this function.")); "enable and configure this function."));
} }
}); });
} }
#endif #endif
} else { } else {
QMessageBox::critical(this, _("Error"), QMessageBox::critical(this, _("Error"),
_("An error occurred during operation.")); _("An error occurred during operation."));
return; return;
}
} else if (edit->slotCurPageFileTreeView() != nullptr) {
this->slotFileEncrypt();
} }
} }
void MainWindow::slotSign() { void MainWindow::slotSign() {
if (edit->tabCount() == 0) return; if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return;
if (edit->slotCurPageTextEdit() != nullptr) { auto key_ids = mKeyList->getPrivateChecked();
auto key_ids = mKeyList->getPrivateChecked();
if (key_ids->empty()) { if (key_ids->empty()) {
QMessageBox::critical(this, _("No Key Selected"), _("No Key Selected")); QMessageBox::critical(this, _("No Key Selected"), _("No Key Selected"));
return; return;
} }
auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids); auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
for (const auto& key : *keys) { for (const auto& key : *keys) {
if (!key.CanSignActual()) { if (!key.CanSignActual()) {
QMessageBox::information( QMessageBox::information(
this, _("Invalid Operation"), this, _("Invalid Operation"),
QString(_( QString(
"The selected key contains a key that does not actually have a " _("The selected key contains a key that does not actually have a "
"signature usage.")) + "signature usage.")) +
"<br/><br/>" + _("For example the Following Key:") + "<br/>" + "<br/><br/>" + _("For example the Following Key:") + "<br/>" +
key.uids()->front().uid().c_str()); key.uids()->front().uid().c_str());
return;
}
}
auto tmp = std::make_unique<ByteArray>();
GpgSignResult result = nullptr;
gpgme_error_t error;
bool if_error = false;
process_operation(this, _("Signing"), [&]() {
try {
auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString();
error = GpgFrontend::BasicOperator::GetInstance().Sign(
std::move(keys), buffer, tmp, GPGME_SIG_MODE_CLEAR, result);
} catch (const std::runtime_error& e) {
if_error = true;
}
});
if (!if_error) {
auto resultAnalyse = SignResultAnalyse(error, std::move(result));
resultAnalyse.analyse();
process_result_analyse(edit, infoBoard, resultAnalyse);
if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
edit->slotFillTextEditWithText(QString::fromStdString(*tmp));
} else {
QMessageBox::critical(this, _("Error"),
_("An error occurred during operation."));
return; return;
} }
} else if (edit->slotCurPageFileTreeView() != nullptr) { }
this->slotFileSign();
auto tmp = std::make_unique<ByteArray>();
GpgSignResult result = nullptr;
gpgme_error_t error;
bool if_error = false;
process_operation(this, _("Signing"), [&]() {
try {
auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString();
error = GpgFrontend::BasicOperator::GetInstance().Sign(
std::move(keys), buffer, tmp, GPGME_SIG_MODE_CLEAR, result);
} catch (const std::runtime_error& e) {
if_error = true;
}
});
if (!if_error) {
auto resultAnalyse = SignResultAnalyse(error, std::move(result));
resultAnalyse.analyse();
process_result_analyse(edit, infoBoard, resultAnalyse);
if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
edit->slotFillTextEditWithText(QString::fromStdString(*tmp));
} else {
QMessageBox::critical(this, _("Error"),
_("An error occurred during operation."));
return;
} }
} }
void MainWindow::slotDecrypt() { void MainWindow::slotDecrypt() {
if (edit->tabCount() == 0) return; if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return;
if (edit->slotCurPageTextEdit() != nullptr) { auto decrypted = std::make_unique<ByteArray>();
auto decrypted = std::make_unique<ByteArray>(); QByteArray text = edit->curTextPage()->toPlainText().toUtf8();
QByteArray text = edit->curTextPage()->toPlainText().toUtf8();
if (text.trimmed().startsWith( if (text.trimmed().startsWith(GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) {
GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) { QMessageBox::critical(
QMessageBox::critical( this, _("Notice"),
this, _("Notice"), _("Short Crypto Text only supports Decrypt & Verify."));
_("Short Crypto Text only supports Decrypt & Verify.")); return;
return; }
GpgDecrResult result = nullptr;
gpgme_error_t error;
bool if_error = false;
process_operation(this, _("Decrypting"), [&]() {
try {
auto buffer = text.toStdString();
error = GpgFrontend::BasicOperator::GetInstance().Decrypt(
buffer, decrypted, result);
} catch (const std::runtime_error& e) {
if_error = true;
} }
});
GpgDecrResult result = nullptr; if (!if_error) {
gpgme_error_t error; auto resultAnalyse = DecryptResultAnalyse(error, std::move(result));
bool if_error = false; resultAnalyse.analyse();
process_operation(this, _("Decrypting"), [&]() { process_result_analyse(edit, infoBoard, resultAnalyse);
try {
auto buffer = text.toStdString();
error = GpgFrontend::BasicOperator::GetInstance().Decrypt(
buffer, decrypted, result);
} catch (const std::runtime_error& e) {
if_error = true;
}
});
if (!if_error) { if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
auto resultAnalyse = DecryptResultAnalyse(error, std::move(result)); edit->slotFillTextEditWithText(QString::fromStdString(*decrypted));
resultAnalyse.analyse(); } else {
process_result_analyse(edit, infoBoard, resultAnalyse); QMessageBox::critical(this, _("Error"),
_("An error occurred during operation."));
if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) return;
edit->slotFillTextEditWithText(QString::fromStdString(*decrypted));
} else {
QMessageBox::critical(this, _("Error"),
_("An error occurred during operation."));
return;
}
} else if (edit->slotCurPageFileTreeView() != nullptr) {
this->slotFileDecrypt();
} }
} }
@ -237,244 +222,222 @@ void MainWindow::slotFind() {
} }
void MainWindow::slotVerify() { void MainWindow::slotVerify() {
if (edit->tabCount() == 0) return; if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return;
if (edit->slotCurPageTextEdit() != nullptr) { auto text = edit->curTextPage()->toPlainText().toUtf8();
auto text = edit->curTextPage()->toPlainText().toUtf8(); // TODO(Saturneric) PreventNoDataErr
// TODO(Saturneric) PreventNoDataErr
auto sig_buffer = std::make_unique<ByteArray>(); auto sig_buffer = std::make_unique<ByteArray>();
sig_buffer.reset(); sig_buffer.reset();
GpgVerifyResult result = nullptr; GpgVerifyResult result = nullptr;
GpgError error; GpgError error;
bool if_error = false; bool if_error = false;
process_operation(this, _("Verifying"), [&]() { process_operation(this, _("Verifying"), [&]() {
try { try {
auto buffer = text.toStdString(); auto buffer = text.toStdString();
error = GpgFrontend::BasicOperator::GetInstance().Verify( error = GpgFrontend::BasicOperator::GetInstance().Verify(
buffer, sig_buffer, result); buffer, sig_buffer, result);
} catch (const std::runtime_error& e) { } catch (const std::runtime_error& e) {
if_error = true; if_error = true;
}
});
if (!if_error) {
auto resultAnalyse = VerifyResultAnalyse(error, std::move(result));
resultAnalyse.analyse();
process_result_analyse(edit, infoBoard, resultAnalyse);
// if (resultAnalyse->getStatus() >= 0) {
// infoBoard->resetOptionActionsMenu();
// infoBoard->addOptionalAction(
// "Show Verify Details", [this, error, result]() {
// VerifyDetailsDialog(this, mCtx, mKeyList, error, result);
// });
// }
} else {
QMessageBox::critical(this, _("Error"),
_("An error occurred during operation."));
return;
} }
} else if (edit->slotCurPageFileTreeView() != nullptr) { });
this->slotFileVerify();
if (!if_error) {
auto resultAnalyse = VerifyResultAnalyse(error, std::move(result));
resultAnalyse.analyse();
process_result_analyse(edit, infoBoard, resultAnalyse);
// if (resultAnalyse->getStatus() >= 0) {
// infoBoard->resetOptionActionsMenu();
// infoBoard->addOptionalAction(
// "Show Verify Details", [this, error, result]() {
// VerifyDetailsDialog(this, mCtx, mKeyList, error, result);
// });
// }
} }
} }
void MainWindow::slotEncryptSign() { void MainWindow::slotEncryptSign() {
if (edit->tabCount() == 0) return; if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return;
if (edit->slotCurPageTextEdit() != nullptr) { auto key_ids = mKeyList->getChecked();
auto key_ids = mKeyList->getChecked();
if (key_ids->empty()) { if (key_ids->empty()) {
QMessageBox::critical(nullptr, _("No Key Selected"), QMessageBox::critical(nullptr, _("No Key Selected"), _("No Key Selected"));
_("No Key Selected")); return;
}
auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
for (const auto& key : *keys) {
bool key_can_encrypt = key.CanEncrActual();
if (!key_can_encrypt) {
QMessageBox::critical(
nullptr, _("Invalid KeyPair"),
QString(_("The selected keypair cannot be used for encryption.")) +
"<br/><br/>" + _("For example the Following Key:") + " <br/>" +
QString::fromStdString(key.uids()->front().uid()));
return; return;
} }
}
auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids); auto signersPicker = new SignersPicker(this);
QEventLoop loop;
connect(signersPicker, SIGNAL(finished(int)), &loop, SLOT(quit()));
loop.exec();
for (const auto& key : *keys) { auto signer_key_ids = signersPicker->getCheckedSigners();
bool key_can_encrypt = key.CanEncrActual(); auto signer_keys = GpgKeyGetter::GetInstance().GetKeys(signer_key_ids);
if (!key_can_encrypt) { for (const auto& key : *keys) {
QMessageBox::critical( LOG(INFO) << "Keys " << key.email();
nullptr, _("Invalid KeyPair"), }
QString(_("The selected keypair cannot be used for encryption.")) +
"<br/><br/>" + _("For example the Following Key:") + " <br/>" + for (const auto& signer : *signer_keys) {
QString::fromStdString(key.uids()->front().uid())); LOG(INFO) << "Signers " << signer.email();
return; }
}
GpgEncrResult encr_result = nullptr;
GpgSignResult sign_result = nullptr;
GpgError error;
bool if_error = false;
auto tmp = std::make_unique<ByteArray>();
process_operation(this, _("Encrypting and Signing"), [&]() {
try {
auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString();
error = GpgFrontend::BasicOperator::GetInstance().EncryptSign(
std::move(keys), std::move(signer_keys), buffer, tmp, encr_result,
sign_result);
} catch (const std::runtime_error& e) {
if_error = true;
} }
});
auto signersPicker = new SignersPicker(this); if (!if_error) {
QEventLoop loop;
connect(signersPicker, SIGNAL(finished(int)), &loop, SLOT(quit()));
loop.exec();
auto signer_key_ids = signersPicker->getCheckedSigners();
auto signer_keys = GpgKeyGetter::GetInstance().GetKeys(signer_key_ids);
for (const auto& key : *keys) {
LOG(INFO) << "Keys " << key.email();
}
for (const auto& signer : *signer_keys) {
LOG(INFO) << "Signers " << signer.email();
}
GpgEncrResult encr_result = nullptr;
GpgSignResult sign_result = nullptr;
GpgError error;
bool if_error = false;
auto tmp = std::make_unique<ByteArray>();
process_operation(this, _("Encrypting and Signing"), [&]() {
try {
auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString();
error = GpgFrontend::BasicOperator::GetInstance().EncryptSign(
std::move(keys), std::move(signer_keys), buffer, tmp, encr_result,
sign_result);
} catch (const std::runtime_error& e) {
if_error = true;
}
});
if (!if_error) {
#ifdef ADVANCE_SUPPORT #ifdef ADVANCE_SUPPORT
if (settings.value("advanced/autoPubkeyExchange").toBool()) { if (settings.value("advanced/autoPubkeyExchange").toBool()) {
PubkeyUploader pubkeyUploader(mCtx, signerKeys); PubkeyUploader pubkeyUploader(mCtx, signerKeys);
pubkeyUploader.start(); pubkeyUploader.start();
if (!pubkeyUploader.result()) { if (!pubkeyUploader.result()) {
QMessageBox::warning( QMessageBox::warning(nullptr, _("Automatic Key Exchange Warning"),
nullptr, _("Automatic Key Exchange Warning"), _("Part of the automatic key exchange failed, "
_("Part of the automatic key exchange failed, " "which may be related to your key.") +
"which may be related to your key.") + _("If possible, try to use the RSA algorithm "
_("If possible, try to use the RSA algorithm " "compatible with the server for signing."));
"compatible with the server for signing."));
}
} }
}
#endif #endif
LOG(INFO) << "ResultAnalyse Started"; LOG(INFO) << "ResultAnalyse Started";
auto encrypt_res = EncryptResultAnalyse(error, std::move(encr_result)); auto encrypt_res = EncryptResultAnalyse(error, std::move(encr_result));
auto sign_res = SignResultAnalyse(error, std::move(sign_result)); auto sign_res = SignResultAnalyse(error, std::move(sign_result));
encrypt_res.analyse(); encrypt_res.analyse();
sign_res.analyse(); sign_res.analyse();
process_result_analyse(edit, infoBoard, encrypt_res, sign_res); process_result_analyse(edit, infoBoard, encrypt_res, sign_res);
if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
edit->slotFillTextEditWithText(QString::fromStdString(*tmp)); edit->slotFillTextEditWithText(QString::fromStdString(*tmp));
#ifdef SMTP_SUPPORT #ifdef SMTP_SUPPORT
infoBoard->resetOptionActionsMenu(); infoBoard->resetOptionActionsMenu();
infoBoard->addOptionalAction("Send Mail", [this]() { infoBoard->addOptionalAction("Send Mail", [this]() {
if (settings.value("sendMail/enable", false).toBool()) if (settings.value("sendMail/enable", false).toBool())
new SendMailDialog(edit->curTextPage()->toPlainText(), this); new SendMailDialog(edit->curTextPage()->toPlainText(), this);
else { else {
QMessageBox::warning(nullptr, _("Function Disabled"), QMessageBox::warning(nullptr, _("Function Disabled"),
_("Please go to the settings interface to " _("Please go to the settings interface to "
"enable and configure this function.")); "enable and configure this function."));
} }
}); });
#endif #endif
#ifdef ADVANCE_SUPPORT #ifdef ADVANCE_SUPPORT
infoBoard->addOptionalAction("Shorten Ciphertext", [this]() { infoBoard->addOptionalAction("Shorten Ciphertext", [this]() {
if (settings.value("general/serviceToken").toString().isEmpty()) if (settings.value("general/serviceToken").toString().isEmpty())
QMessageBox::warning(nullptr, _("Service Token Empty"), QMessageBox::warning(nullptr, _("Service Token Empty"),
_("Please go to the settings interface to set " _("Please go to the settings interface to set "
"Own Key and get Service Token.")); "Own Key and get Service Token."));
else { else {
shortenCryptText(); shortenCryptText();
} }
}); });
#endif #endif
} else { } else {
QMessageBox::critical(this, _("Error"), QMessageBox::critical(this, _("Error"),
_("An error occurred during operation.")); _("An error occurred during operation."));
return; return;
}
} else if (edit->slotCurPageFileTreeView() != nullptr) {
this->slotFileEncryptSign();
} }
} }
void MainWindow::slotDecryptVerify() { void MainWindow::slotDecryptVerify() {
if (edit->tabCount() == 0) return; if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return;
if (edit->slotCurPageTextEdit() != nullptr) { QString plainText = edit->curTextPage()->toPlainText();
QString plainText = edit->curTextPage()->toPlainText();
#ifdef ADVANCE_SUPPORT #ifdef ADVANCE_SUPPORT
if (plainText.trimmed().startsWith( if (plainText.trimmed().startsWith(
GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) { GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) {
auto cryptoText = getCryptText(plainText); auto cryptoText = getCryptText(plainText);
if (!cryptoText.isEmpty()) { if (!cryptoText.isEmpty()) {
plainText = cryptoText; plainText = cryptoText;
}
} }
}
#endif #endif
QByteArray text = plainText.toUtf8(); QByteArray text = plainText.toUtf8();
GpgDecrResult d_result = nullptr; GpgDecrResult d_result = nullptr;
GpgVerifyResult v_result = nullptr; GpgVerifyResult v_result = nullptr;
gpgme_error_t error; gpgme_error_t error;
bool if_error = false; bool if_error = false;
#ifdef ADVANCE_SUPPORT #ifdef ADVANCE_SUPPORT
// Automatically import public keys that are not stored locally // Automatically import public keys that are not stored locally
if (settings.value("advanced/autoPubkeyExchange").toBool()) { if (settings.value("advanced/autoPubkeyExchange").toBool()) {
gpgme_verify_result_t tmp_v_result = nullptr; gpgme_verify_result_t tmp_v_result = nullptr;
auto thread = QThread::create( auto thread =
[&]() { mCtx->verify(&text, nullptr, &tmp_v_result); }); QThread::create([&]() { mCtx->verify(&text, nullptr, &tmp_v_result); });
thread->start(); thread->start();
while (thread->isRunning()) QApplication::processEvents(); while (thread->isRunning()) QApplication::processEvents();
auto* checker = new UnknownSignersChecker(mCtx, tmp_v_result); auto* checker = new UnknownSignersChecker(mCtx, tmp_v_result);
checker->start(); checker->start();
checker->deleteLater(); checker->deleteLater();
} }
#endif #endif
auto decrypted = std::make_unique<ByteArray>(); auto decrypted = std::make_unique<ByteArray>();
process_operation(this, _("Decrypting and Verifying"), [&]() { process_operation(this, _("Decrypting and Verifying"), [&]() {
try { try {
auto buffer = text.toStdString(); auto buffer = text.toStdString();
error = BasicOperator::GetInstance().DecryptVerify(buffer, decrypted, error = BasicOperator::GetInstance().DecryptVerify(buffer, decrypted,
d_result, v_result); d_result, v_result);
} catch (const std::runtime_error& e) { } catch (const std::runtime_error& e) {
if_error = true; if_error = true;
}
});
if (!if_error) {
infoBoard->associateFileTreeView(edit->curFilePage());
auto decrypt_res = DecryptResultAnalyse(error, std::move(d_result));
auto verify_res = VerifyResultAnalyse(error, std::move(v_result));
decrypt_res.analyse();
verify_res.analyse();
process_result_analyse(edit, infoBoard, decrypt_res, verify_res);
edit->slotFillTextEditWithText(QString::fromStdString(*decrypted));
// if (verify_res.getStatus() >= 0) {
// infoBoard->resetOptionActionsMenu();
// infoBoard->addOptionalAction(
// "Show Verify Details", [this, error, v_result]() {
// VerifyDetailsDialog(this, mCtx, mKeyList, error,
// v_result);
// });
// }
} else {
QMessageBox::critical(this, _("Error"),
_("An error occurred during operation."));
return;
} }
});
} else if (edit->slotCurPageFileTreeView() != nullptr) { if (!if_error) {
this->slotFileDecryptVerify(); auto decrypt_res = DecryptResultAnalyse(error, std::move(d_result));
auto verify_res = VerifyResultAnalyse(error, std::move(v_result));
decrypt_res.analyse();
verify_res.analyse();
process_result_analyse(edit, infoBoard, decrypt_res, verify_res);
edit->slotFillTextEditWithText(QString::fromStdString(*decrypted));
// if (verify_res.getStatus() >= 0) {
// infoBoard->resetOptionActionsMenu();
// infoBoard->addOptionalAction(
// "Show Verify Details", [this, error, v_result]() {
// VerifyDetailsDialog(this, mCtx, mKeyList, error,
// v_result);
// });
// }
} else {
QMessageBox::critical(this, _("Error"),
_("An error occurred during operation."));
return;
} }
} }

View File

@ -45,7 +45,8 @@ void MainWindow::createActions() {
openAct->setToolTip(_("Open an existing file")); openAct->setToolTip(_("Open an existing file"));
connect(openAct, SIGNAL(triggered()), edit, SLOT(slotOpen())); connect(openAct, SIGNAL(triggered()), edit, SLOT(slotOpen()));
browserAct = new QAction(_("Browser"), this); browserAct = new QAction(_("File Browser"), this);
browserAct->setIcon(QIcon(":file-browser.png"));
browserAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B)); browserAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B));
browserAct->setToolTip(_("Open a file browser")); browserAct->setToolTip(_("Open a file browser"));
connect(browserAct, SIGNAL(triggered()), this, SLOT(slotOpenFileTab())); connect(browserAct, SIGNAL(triggered()), this, SLOT(slotOpenFileTab()));
@ -406,7 +407,7 @@ void MainWindow::createToolBars() {
fileToolBar->addAction(newTabAct); fileToolBar->addAction(newTabAct);
fileToolBar->addAction(openAct); fileToolBar->addAction(openAct);
fileToolBar->addAction(saveAct); fileToolBar->addAction(saveAct);
fileToolBar->hide(); fileToolBar->addAction(browserAct);
viewMenu->addAction(fileToolBar->toggleViewAction()); viewMenu->addAction(fileToolBar->toggleViewAction());
cryptToolBar = addToolBar(_("Crypt")); cryptToolBar = addToolBar(_("Crypt"));
@ -429,6 +430,7 @@ void MainWindow::createToolBars() {
editToolBar->addAction(copyAct); editToolBar->addAction(copyAct);
editToolBar->addAction(pasteAct); editToolBar->addAction(pasteAct);
editToolBar->addAction(selectAllAct); editToolBar->addAction(selectAllAct);
editToolBar->hide();
viewMenu->addAction(editToolBar->toggleViewAction()); viewMenu->addAction(editToolBar->toggleViewAction());
specialEditToolBar = addToolBar(_("Special Edit")); specialEditToolBar = addToolBar(_("Special Edit"));
@ -446,15 +448,6 @@ void MainWindow::createToolBars() {
importButton->setToolTip(_("Import key from...")); importButton->setToolTip(_("Import key from..."));
importButton->setText(_("Import key")); importButton->setText(_("Import key"));
keyToolBar->addWidget(importButton); keyToolBar->addWidget(importButton);
// Add dropdown menu for file encryption/decryption to crypttoolbar
fileEncButton = new QToolButton();
connect(fileEncButton, SIGNAL(clicked(bool)), this, SLOT(slotOpenFileTab()));
fileEncButton->setPopupMode(QToolButton::InstantPopup);
fileEncButton->setIcon(QIcon(":fileencryption.png"));
fileEncButton->setToolTip(_("Browser to view and operate file"));
fileEncButton->setText(_("Browser"));
fileToolBar->addWidget(fileEncButton);
} }
void MainWindow::createStatusBar() { void MainWindow::createStatusBar() {
@ -469,7 +462,6 @@ void MainWindow::createStatusBar() {
statusBarIcon->setPixmap(*pixmap); statusBarIcon->setPixmap(*pixmap);
statusBar()->insertPermanentWidget(0, statusBarIcon, 0); statusBar()->insertPermanentWidget(0, statusBarIcon, 0);
statusBarIcon->hide();
statusBar()->showMessage(_("Ready"), 2000); statusBar()->showMessage(_("Ready"), 2000);
statusBarBox->setLayout(statusBarBoxLayout); statusBarBox->setLayout(statusBarBoxLayout);
} }
@ -483,6 +475,33 @@ void MainWindow::createDockWindows() {
Qt::RightDockWidgetArea); Qt::RightDockWidgetArea);
keyListDock->setMinimumWidth(460); keyListDock->setMinimumWidth(460);
addDockWidget(Qt::RightDockWidgetArea, keyListDock); addDockWidget(Qt::RightDockWidgetArea, keyListDock);
mKeyList->addListGroupTab(
_("Default"), KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key) -> bool {
return !(key.revoked() || key.disabled() || key.expired());
});
mKeyList->addListGroupTab(
_("Only Public Key"), KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key) -> bool {
return !key.is_private_key() &&
!(key.revoked() || key.disabled() || key.expired());
});
mKeyList->addListGroupTab(
_("Has Private Key"), KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key) -> bool {
return key.is_private_key() &&
!(key.revoked() || key.disabled() || key.expired());
});
keyListDock->setWidget(mKeyList); keyListDock->setWidget(mKeyList);
viewMenu->addAction(keyListDock->toggleViewAction()); viewMenu->addAction(keyListDock->toggleViewAction());

View File

@ -26,13 +26,13 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include "MainWindow.h" #include "ui/MainWindow.h"
#include "ui/SignalStation.h"
namespace GpgFrontend::UI { namespace GpgFrontend::UI {
FilePage::FilePage(QWidget* parent) : QWidget(parent) { FilePage::FilePage(QWidget* parent) : QWidget(parent) {
firstParent = parent; firstParent = parent;
LOG(INFO) << "New File Page";
dirModel = new QFileSystemModel(); dirModel = new QFileSystemModel();
dirModel->setRootPath(QDir::currentPath()); dirModel->setRootPath(QDir::currentPath());
@ -86,8 +86,6 @@ FilePage::FilePage(QWidget* parent) : QWidget(parent) {
menuLayout->setStretchFactor(pathEdit, 10); menuLayout->setStretchFactor(pathEdit, 10);
menuLayout->addWidget(goPathButton); menuLayout->addWidget(goPathButton);
menuLayout->setStretchFactor(goPathButton, 1); menuLayout->setStretchFactor(goPathButton, 1);
// menuLayout->addWidget(refreshButton);
// menuLayout->setStretchFactor(refreshButton, 1);
auto* layout = new QVBoxLayout(); auto* layout = new QVBoxLayout();
layout->setContentsMargins(0, 0, 0, 0); layout->setContentsMargins(0, 0, 0, 0);
@ -99,20 +97,21 @@ FilePage::FilePage(QWidget* parent) : QWidget(parent) {
this->setLayout(layout); this->setLayout(layout);
connect(dirTreeView, SIGNAL(clicked(const QModelIndex&)), this, connect(dirTreeView, &QTreeView::clicked, this,
SLOT(fileTreeViewItemClicked(const QModelIndex&))); &FilePage::fileTreeViewItemClicked);
connect(dirTreeView, SIGNAL(doubleClicked(const QModelIndex&)), this, connect(dirTreeView, &QTreeView::doubleClicked, this,
SLOT(fileTreeViewItemDoubleClicked(const QModelIndex&))); &FilePage::fileTreeViewItemDoubleClicked);
connect(dirTreeView, SIGNAL(customContextMenuRequested(const QPoint&)), this, connect(dirTreeView, &QTreeView::customContextMenuRequested, this,
SLOT(onCustomContextMenu(const QPoint&))); &FilePage::onCustomContextMenu);
// refresh connect(this, &FilePage::signalRefreshInfoBoard, SignalStation::GetInstance(),
slotGoPath(); &SignalStation::signalRefreshInfoBoard);
} }
void FilePage::fileTreeViewItemClicked(const QModelIndex& index) { void FilePage::fileTreeViewItemClicked(const QModelIndex& index) {
selectedPath = boost::filesystem::path( selectedPath = boost::filesystem::path(
dirModel->fileInfo(index).absoluteFilePath().toStdString()); dirModel->fileInfo(index).absoluteFilePath().toStdString());
mPath = selectedPath;
LOG(INFO) << "selected path" << selectedPath; LOG(INFO) << "selected path" << selectedPath;
} }
@ -121,51 +120,42 @@ void FilePage::slotUpLevel() {
mPath = boost::filesystem::path( mPath = boost::filesystem::path(
dirModel->fileInfo(currentRoot).absoluteFilePath().toStdString()); dirModel->fileInfo(currentRoot).absoluteFilePath().toStdString());
LOG(INFO) << "get path" << mPath;
if (mPath.has_parent_path()) { if (mPath.has_parent_path()) {
mPath = mPath.parent_path(); mPath = mPath.parent_path();
auto fileInfo = QFileInfo(QString::fromStdString(mPath.string())); LOG(INFO) << "parent path" << mPath;
if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { pathEdit->setText(mPath.string().c_str());
pathEdit->setText(QString::fromStdString(mPath.string())); slotGoPath();
slotGoPath();
}
LOG(INFO) << "Current Root mPath" << mPath;
emit pathChanged(QString::fromStdString(mPath.string()));
} }
} }
void FilePage::fileTreeViewItemDoubleClicked(const QModelIndex& index) { void FilePage::fileTreeViewItemDoubleClicked(const QModelIndex& index) {
mPath = boost::filesystem::path( pathEdit->setText(dirModel->fileInfo(index).absoluteFilePath());
dirModel->fileInfo(index).absoluteFilePath().toStdString()); slotGoPath();
auto fileInfo = QFileInfo(QString::fromStdString(mPath.string()));
auto targetModelIndex =
dirTreeView->model()->index(index.row(), 0, index.parent());
if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) {
dirTreeView->setRootIndex(targetModelIndex);
pathEdit->setText(QString::fromStdString(mPath.string()));
}
for (int i = 1; i < dirModel->columnCount(); ++i)
dirTreeView->resizeColumnToContents(i);
LOG(INFO) << "Index mPath" << mPath;
emit pathChanged(QString::fromStdString(mPath.string()));
} }
QString FilePage::getSelected() const { return QString::fromStdString(selectedPath.string()); } QString FilePage::getSelected() const {
return QString::fromStdString(selectedPath.string());
}
void FilePage::slotGoPath() { void FilePage::slotGoPath() {
qDebug() << "getSelected" << pathEdit->text(); const auto path_edit = pathEdit->text().toStdString();
auto fileInfo = QFileInfo(pathEdit->text()); LOG(INFO) << "get path edit" << path_edit;
if (mPath.string() != path_edit) mPath = path_edit;
auto fileInfo = QFileInfo(mPath.string().c_str());
if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) {
mPath = boost::filesystem::path(fileInfo.filePath().toStdString()); mPath = boost::filesystem::path(fileInfo.filePath().toStdString());
LOG(INFO) << "Set Path" << mPath; LOG(INFO) << "set path" << mPath;
dirTreeView->setRootIndex(dirModel->index(fileInfo.filePath())); dirTreeView->setRootIndex(dirModel->index(fileInfo.filePath()));
for (int i = 1; i < dirModel->columnCount(); ++i) for (int i = 1; i < dirModel->columnCount(); ++i) {
dirTreeView->resizeColumnToContents(i); dirTreeView->resizeColumnToContents(i);
}
pathEdit->setText(mPath.generic_path().string().c_str());
} else { } else {
QMessageBox::critical(this, "Error", QMessageBox::critical(this, _("Error"),
"The path is unprivileged or unreachable."); _("The path is unprivileged or unreachable."));
} }
emit pathChanged(QString::fromStdString(mPath.string())); emit pathChanged(mPath.string().c_str());
} }
void FilePage::createPopupMenu() { void FilePage::createPopupMenu() {
@ -173,33 +163,45 @@ void FilePage::createPopupMenu() {
auto openItemAct = new QAction(_("Open"), this); auto openItemAct = new QAction(_("Open"), this);
connect(openItemAct, SIGNAL(triggered()), this, SLOT(slotOpenItem())); connect(openItemAct, SIGNAL(triggered()), this, SLOT(slotOpenItem()));
auto renameItemAct = new QAction(_("Rename"), this);
connect(renameItemAct, SIGNAL(triggered()), this, SLOT(slotRenameItem()));
auto deleteItemAct = new QAction(_("Delete"), this); auto deleteItemAct = new QAction(_("Delete"), this);
connect(deleteItemAct, SIGNAL(triggered()), this, SLOT(slotDeleteItem())); connect(deleteItemAct, SIGNAL(triggered()), this, SLOT(slotDeleteItem()));
encryptItemAct = new QAction(_("Encrypt and Sign"), this); encryptItemAct = new QAction(_("Encrypt Sign"), this);
connect(encryptItemAct, SIGNAL(triggered()), this, SLOT(slotEncryptItem())); connect(encryptItemAct, SIGNAL(triggered()), this, SLOT(slotEncryptItem()));
decryptItemAct = new QAction(_("Decrypt and Verify"), this); decryptItemAct =
new QAction(QString(_("Decrypt Verify")) + " " + _("(.gpg .asc)"), this);
connect(decryptItemAct, SIGNAL(triggered()), this, SLOT(slotDecryptItem())); connect(decryptItemAct, SIGNAL(triggered()), this, SLOT(slotDecryptItem()));
signItemAct = new QAction(_("Only Sign"), this); signItemAct = new QAction(_("Sign"), this);
connect(signItemAct, SIGNAL(triggered()), this, SLOT(slotSignItem())); connect(signItemAct, SIGNAL(triggered()), this, SLOT(slotSignItem()));
verifyItemAct = new QAction(_("Only Verify"), this); verifyItemAct =
new QAction(QString(_("Verify")) + " " + _("(.sig .gpg .asc)"), this);
connect(verifyItemAct, SIGNAL(triggered()), this, SLOT(slotVerifyItem())); connect(verifyItemAct, SIGNAL(triggered()), this, SLOT(slotVerifyItem()));
auto hashItemAct = new QAction(_("Calculate Hash"), this);
connect(hashItemAct, SIGNAL(triggered()), this, SLOT(slotCalculateHash()));
popUpMenu->addAction(openItemAct); popUpMenu->addAction(openItemAct);
popUpMenu->addAction(renameItemAct);
popUpMenu->addAction(deleteItemAct); popUpMenu->addAction(deleteItemAct);
popUpMenu->addSeparator(); popUpMenu->addSeparator();
popUpMenu->addAction(encryptItemAct); popUpMenu->addAction(encryptItemAct);
popUpMenu->addAction(decryptItemAct); popUpMenu->addAction(decryptItemAct);
popUpMenu->addAction(signItemAct); popUpMenu->addAction(signItemAct);
popUpMenu->addAction(verifyItemAct); popUpMenu->addAction(verifyItemAct);
popUpMenu->addSeparator();
popUpMenu->addAction(hashItemAct);
} }
void FilePage::onCustomContextMenu(const QPoint& point) { void FilePage::onCustomContextMenu(const QPoint& point) {
QModelIndex index = dirTreeView->indexAt(point); QModelIndex index = dirTreeView->indexAt(point);
selectedPath = boost::filesystem::path( selectedPath = boost::filesystem::path(
dirModel->fileInfo(index).absoluteFilePath().toStdString()); dirModel->fileInfo(index).absoluteFilePath().toStdString());
LOG(INFO) << "FilePage::onCustomContextMenu Right Click" << selectedPath; LOG(INFO) << "right click" << selectedPath;
if (index.isValid()) { if (index.isValid()) {
QFileInfo info(QString::fromStdString(selectedPath.string())); QFileInfo info(QString::fromStdString(selectedPath.string()));
encryptItemAct->setEnabled(
info.isFile() && (info.suffix() != "gpg" && info.suffix() != "sig"));
encryptItemAct->setEnabled( encryptItemAct->setEnabled(
info.isFile() && (info.suffix() != "gpg" && info.suffix() != "sig")); info.isFile() && (info.suffix() != "gpg" && info.suffix() != "sig"));
decryptItemAct->setEnabled(info.isFile() && info.suffix() == "gpg"); decryptItemAct->setEnabled(info.isFile() && info.suffix() == "gpg");
@ -215,21 +217,49 @@ void FilePage::onCustomContextMenu(const QPoint& point) {
void FilePage::slotOpenItem() { void FilePage::slotOpenItem() {
QFileInfo info(QString::fromStdString(selectedPath.string())); QFileInfo info(QString::fromStdString(selectedPath.string()));
if (info.isDir()) { if (info.isDir()) {
LOG(INFO) << "FilePage::slotOpenItem getSelected"
<< pathEdit->text().toStdString();
if (info.isReadable() && info.isExecutable()) { if (info.isReadable() && info.isExecutable()) {
LOG(INFO) << "FilePage::slotOpenItem Set Path" const auto file_path = info.filePath().toStdString();
<< info.filePath().toStdString(); LOG(INFO) << "set path" << file_path;
dirTreeView->setRootIndex(dirModel->index(info.filePath())); pathEdit->setText(info.filePath());
slotGoPath();
} else { } else {
QMessageBox::critical(this, "Error", QMessageBox::critical(this, _("Error"),
"The path is unprivileged or unreachable."); _("The directory is unprivileged or unreachable."));
} }
} else { } else {
auto mainWindow = qobject_cast<MainWindow*>(firstParent); if (info.isReadable()) {
LOG(INFO) << "FilePage::slotOpenItem Open Item" << selectedPath; auto mainWindow = qobject_cast<MainWindow*>(firstParent);
auto qt_path = QString::fromStdString(selectedPath.string()); LOG(INFO) << "open item" << selectedPath;
if (mainWindow != nullptr) mainWindow->slotOpenFile(qt_path); auto qt_path = QString::fromStdString(selectedPath.string());
if (mainWindow != nullptr) mainWindow->slotOpenFile(qt_path);
} else {
QMessageBox::critical(this, _("Error"),
_("The file is unprivileged or unreachable."));
}
}
}
void FilePage::slotRenameItem() {
auto new_name_path = selectedPath, old_name_path = selectedPath;
auto old_name = old_name_path.filename();
new_name_path = new_name_path.remove_filename();
bool ok;
auto text =
QInputDialog::getText(this, _("Rename"), _("New Filename"),
QLineEdit::Normal, old_name.string().c_str(), &ok);
if (ok && !text.isEmpty()) {
try {
new_name_path /= text.toStdString();
LOG(INFO) << "new name path" << new_name_path;
boost::filesystem::rename(old_name_path, new_name_path);
// refresh
this->slotGoPath();
} catch (...) {
LOG(ERROR) << "rename error" << new_name_path;
QMessageBox::critical(this, _("Error"),
_("Unable to rename the file or folder."));
}
} }
} }
@ -271,6 +301,52 @@ void FilePage::slotVerifyItem() {
if (mainWindow != nullptr) mainWindow->slotFileVerify(); if (mainWindow != nullptr) mainWindow->slotFileVerify();
} }
void FilePage::slotCalculateHash() {
// Returns empty QByteArray() on failure.
QFileInfo info(QString::fromStdString(selectedPath.string()));
if (info.isFile() && info.isReadable()) {
std::stringstream ss;
ss << "[#] " << _("File Hash") << std::endl;
ss << " " << _("filename") << _(": ")
<< selectedPath.filename().string().c_str() << std::endl;
QFile f(info.filePath());
f.open(QFile::ReadOnly);
auto buffer = f.readAll();
LOG(INFO) << "buffer size" << buffer.size();
f.close();
if (f.open(QFile::ReadOnly)) {
auto hash_md5 = QCryptographicHash(QCryptographicHash::Md5);
// md5
hash_md5.addData(buffer);
auto md5 = hash_md5.result().toHex().toStdString();
LOG(INFO) << "md5" << md5;
ss << " " << _("md5") << _(": ") << md5 << std::endl;
auto hash_sha1 = QCryptographicHash(QCryptographicHash::Sha1);
// sha1
hash_sha1.addData(buffer);
auto sha1 = hash_sha1.result().toHex().toStdString();
LOG(INFO) << "sha1" << sha1;
ss << " " << _("sha1") << _(": ") << sha1 << std::endl;
auto hash_sha256 = QCryptographicHash(QCryptographicHash::Sha256);
// sha1
hash_sha256.addData(buffer);
auto sha256 = hash_sha256.result().toHex().toStdString();
LOG(INFO) << "sha256" << sha256;
ss << " " << _("sha256") << _(": ") << sha256 << std::endl;
ss << std::endl;
emit signalRefreshInfoBoard(ss.str().c_str(),
InfoBoardStatus::INFO_ERROR_OK);
}
}
}
void FilePage::keyPressEvent(QKeyEvent* event) { void FilePage::keyPressEvent(QKeyEvent* event) {
qDebug() << "Key Press" << event->key(); qDebug() << "Key Press" << event->key();
if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {

View File

@ -28,6 +28,7 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include "ui/GpgFrontendUI.h" #include "ui/GpgFrontendUI.h"
#include "ui/widgets/InfoBoardWidget.h"
namespace GpgFrontend::UI { namespace GpgFrontend::UI {
@ -38,25 +39,30 @@ class FilePage : public QWidget {
[[nodiscard]] QString getSelected() const; [[nodiscard]] QString getSelected() const;
void createPopupMenu(); public slots:
void slotGoPath();
signals: signals:
void pathChanged(const QString& path); void pathChanged(const QString& path);
void signalRefreshInfoBoard(const QString& text,
InfoBoardStatus verify_label_status);
private slots: private slots:
void fileTreeViewItemClicked(const QModelIndex& index); void fileTreeViewItemClicked(const QModelIndex& index);
void fileTreeViewItemDoubleClicked(const QModelIndex& index); void fileTreeViewItemDoubleClicked(const QModelIndex& index);
void slotUpLevel(); void slotUpLevel();
void slotGoPath();
void slotOpenItem(); void slotOpenItem();
void slotRenameItem();
void slotDeleteItem(); void slotDeleteItem();
void slotEncryptItem(); void slotEncryptItem();
void slotDecryptItem(); void slotDecryptItem();
void slotSignItem(); void slotSignItem();
void slotVerifyItem(); void slotVerifyItem();
void slotCalculateHash();
void onCustomContextMenu(const QPoint& point); void onCustomContextMenu(const QPoint& point);
@ -64,6 +70,8 @@ class FilePage : public QWidget {
void keyPressEvent(QKeyEvent* event) override; void keyPressEvent(QKeyEvent* event) override;
private: private:
void createPopupMenu();
QFileSystemModel* dirModel; QFileSystemModel* dirModel;
QTreeView* dirTreeView; QTreeView* dirTreeView;
QLineEdit* pathEdit; QLineEdit* pathEdit;

View File

@ -24,6 +24,7 @@
#include "ui/widgets/InfoBoardWidget.h" #include "ui/widgets/InfoBoardWidget.h"
#include "ui/SignalStation.h"
#include "ui/settings/GlobalSettingStation.h" #include "ui/settings/GlobalSettingStation.h"
namespace GpgFrontend::UI { namespace GpgFrontend::UI {
@ -81,6 +82,9 @@ InfoBoardWidget::InfoBoardWidget(QWidget* parent, KeyList* keyList)
notificationWidgetLayout->addStretch(0); notificationWidgetLayout->addStretch(0);
this->setLayout(notificationWidgetLayout); this->setLayout(notificationWidgetLayout);
connect(SignalStation::GetInstance(), &SignalStation::signalRefreshInfoBoard,
this, &InfoBoardWidget::slotRefresh);
// set default size // set default size
infoBoard->resize(480, 120); infoBoard->resize(480, 120);
resize(480, 120); resize(480, 120);
@ -145,15 +149,6 @@ void InfoBoardWidget::associateTextEdit(QTextEdit* edit) {
connect(edit, SIGNAL(textChanged()), this, SLOT(slotReset())); connect(edit, SIGNAL(textChanged()), this, SLOT(slotReset()));
} }
void InfoBoardWidget::associateFileTreeView(FilePage* treeView) {
// if (mFileTreeView != nullptr)
// disconnect(mFileTreeView, &FilePage::pathChanged, this,
// &InfoBoardWidget::slotReset);
// this->mFileTreeView = treeView;
// connect(treeView, &FilePage::pathChanged, this,
// &InfoBoardWidget::slotReset);
}
void InfoBoardWidget::associateTabWidget(QTabWidget* tab) { void InfoBoardWidget::associateTabWidget(QTabWidget* tab) {
if (mTextPage != nullptr) if (mTextPage != nullptr)
disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset())); disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset()));
@ -167,7 +162,6 @@ void InfoBoardWidget::associateTabWidget(QTabWidget* tab) {
} }
mTextPage = nullptr; mTextPage = nullptr;
mFileTreeView = nullptr;
mTabWidget = tab; mTabWidget = tab;
connect(tab, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset())); connect(tab, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset()));
connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(slotReset())); connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(slotReset()));

View File

@ -26,11 +26,11 @@
#define __VERIFYNOTIFICATION_H__ #define __VERIFYNOTIFICATION_H__
#include "EditorPage.h" #include "EditorPage.h"
#include "FilePage.h"
#include "gpg/result_analyse/VerifyResultAnalyse.h" #include "gpg/result_analyse/VerifyResultAnalyse.h"
#include "ui/VerifyDetailsDialog.h" #include "ui/VerifyDetailsDialog.h"
namespace GpgFrontend::UI { namespace GpgFrontend::UI {
/** /**
* @details Enumeration for the status of Verifylabel * @details Enumeration for the status of Verifylabel
*/ */
@ -57,8 +57,6 @@ class InfoBoardWidget : public QWidget {
void associateTextEdit(QTextEdit* edit); void associateTextEdit(QTextEdit* edit);
void associateFileTreeView(FilePage* treeView);
void associateTabWidget(QTabWidget* tab); void associateTabWidget(QTabWidget* tab);
void addOptionalAction(const QString& name, void addOptionalAction(const QString& name,
@ -100,8 +98,6 @@ class InfoBoardWidget : public QWidget {
KeyList* mKeyList; /** Table holding the keys */ KeyList* mKeyList; /** Table holding the keys */
QTextEdit* mTextPage{nullptr}; /** TextEdit associated to the notification */ QTextEdit* mTextPage{nullptr}; /** TextEdit associated to the notification */
FilePage* mFileTreeView{
nullptr}; /** TreeView associated to the notification */
QTabWidget* mTabWidget{ QTabWidget* mTabWidget{
nullptr}; /** TreeView associated to the notification */ nullptr}; /** TreeView associated to the notification */

View File

@ -31,61 +31,24 @@
namespace GpgFrontend::UI { namespace GpgFrontend::UI {
KeyList::KeyList(QWidget* parent) : QWidget(parent) { init(); }
KeyList::KeyList(KeyListRow::KeyType selectType, KeyList::KeyList(KeyListRow::KeyType selectType,
KeyListColumn::InfoType infoType, QWidget* parent) KeyListColumn::InfoType infoType,
: QWidget(parent), const std::function<bool(const GpgKey&)>& filter,
appPath(qApp->applicationDirPath()), QWidget* parent)
settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", : QWidget(parent) {
QSettings::IniFormat), init();
mSelectType(selectType), addListGroupTab("Default", selectType, infoType, filter);
mInfoType(infoType) { }
mKeyList = new QTableWidget(this);
mKeyList->setColumnCount(7);
mKeyList->horizontalHeader()->setSectionResizeMode(
QHeaderView::ResizeToContents);
mKeyList->verticalHeader()->hide();
mKeyList->setShowGrid(false);
mKeyList->sortByColumn(2, Qt::AscendingOrder);
mKeyList->setSelectionBehavior(QAbstractItemView::SelectRows);
mKeyList->setSelectionMode(QAbstractItemView::SingleSelection);
// table items not editable void KeyList::init() {
mKeyList->setEditTriggers(QAbstractItemView::NoEditTriggers); mGroupTab = new QTabWidget();
// no focus (rectangle around table items) mGroupTab->setMovable(true);
// maybe it should focus on whole row mGroupTab->setTabsClosable(false);
mKeyList->setFocusPolicy(Qt::NoFocus);
mKeyList->setAlternatingRowColors(true);
// Hidden Column For Purpose
if (!(mInfoType & KeyListColumn::TYPE)) {
mKeyList->setColumnHidden(1, true);
}
if (!(mInfoType & KeyListColumn::NAME)) {
mKeyList->setColumnHidden(2, true);
}
if (!(mInfoType & KeyListColumn::EmailAddress)) {
mKeyList->setColumnHidden(3, true);
}
if (!(mInfoType & KeyListColumn::Usage)) {
mKeyList->setColumnHidden(4, true);
}
if (!(mInfoType & KeyListColumn::Validity)) {
mKeyList->setColumnHidden(5, true);
}
if (!(mInfoType & KeyListColumn::FingerPrint)) {
mKeyList->setColumnHidden(6, true);
}
QStringList labels;
labels << _("Select") << _("Type") << _("Name") << _("Email Address")
<< _("Usage") << _("Validity") << _("Finger Print");
mKeyList->setHorizontalHeaderLabels(labels);
mKeyList->horizontalHeader()->setStretchLastSection(false);
auto* layout = new QVBoxLayout; auto* layout = new QVBoxLayout;
layout->addWidget(mKeyList); layout->addWidget(mGroupTab);
layout->setContentsMargins(0, 0, 0, 0); layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(3); layout->setSpacing(3);
setLayout(layout); setLayout(layout);
@ -95,136 +58,97 @@ KeyList::KeyList(KeyListRow::KeyType selectType,
// register key database refresh signal // register key database refresh signal
connect(SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()), this, connect(SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()), this,
SLOT(slotRefresh())); SLOT(slotRefresh()));
connect(mKeyList, SIGNAL(doubleClicked(const QModelIndex&)), this,
SLOT(slotDoubleClicked(const QModelIndex&)));
setAcceptDrops(true); setAcceptDrops(true);
slotRefresh(); }
void KeyList::addListGroupTab(
const QString& name, KeyListRow::KeyType selectType,
KeyListColumn::InfoType infoType,
const std::function<bool(const GpgKey&)>& filter) {
auto key_list = new QTableWidget(this);
if (mKeyList == nullptr) {
mKeyList = key_list;
}
mGroupTab->addTab(key_list, name);
mKeyTables.emplace_back(key_list, selectType, infoType, filter);
key_list->setColumnCount(7);
key_list->horizontalHeader()->setSectionResizeMode(
QHeaderView::ResizeToContents);
key_list->verticalHeader()->hide();
key_list->setShowGrid(false);
key_list->sortByColumn(2, Qt::AscendingOrder);
key_list->setSelectionBehavior(QAbstractItemView::SelectRows);
key_list->setSelectionMode(QAbstractItemView::SingleSelection);
// table items not editable
key_list->setEditTriggers(QAbstractItemView::NoEditTriggers);
// no focus (rectangle around table items)
// maybe it should focus on whole row
key_list->setFocusPolicy(Qt::NoFocus);
key_list->setAlternatingRowColors(true);
// Hidden Column For Purpose
if (!(infoType & KeyListColumn::TYPE)) {
key_list->setColumnHidden(1, true);
}
if (!(infoType & KeyListColumn::NAME)) {
key_list->setColumnHidden(2, true);
}
if (!(infoType & KeyListColumn::EmailAddress)) {
key_list->setColumnHidden(3, true);
}
if (!(infoType & KeyListColumn::Usage)) {
key_list->setColumnHidden(4, true);
}
if (!(infoType & KeyListColumn::Validity)) {
key_list->setColumnHidden(5, true);
}
if (!(infoType & KeyListColumn::FingerPrint)) {
key_list->setColumnHidden(6, true);
}
QStringList labels;
labels << _("Select") << _("Type") << _("Name") << _("Email Address")
<< _("Usage") << _("Validity") << _("Finger Print");
key_list->setHorizontalHeaderLabels(labels);
key_list->horizontalHeader()->setStretchLastSection(false);
connect(key_list, &QTableWidget::doubleClicked, this,
&KeyList::slotDoubleClicked);
// refresh
mKeyTables.back().Refresh();
} }
void KeyList::slotRefresh() { void KeyList::slotRefresh() {
LOG(INFO) << "KeyList::slotRefresh Called"; LOG(INFO) << _("called");
auto keyList = getChecked(); for (auto& key_table : mKeyTables) {
// while filling the table, sort enabled causes errors key_table.Refresh();
mKeyList->setSortingEnabled(false);
mKeyList->clearContents();
auto keys = GpgKeyGetter::GetInstance().FetchKey();
auto it = keys->begin();
int row_count = 0;
while (it != keys->end()) {
if (mFilter != nullptr) {
if (!mFilter(*it)) {
it = keys->erase(it);
continue;
}
}
if (!excluded_key_ids.empty()) {
auto iterator =
std::find_if(excluded_key_ids.begin(), excluded_key_ids.end(),
[it](const auto& key_id) -> bool {
if (it->id() == key_id)
return true;
else
return false;
});
if (iterator != excluded_key_ids.end()) {
it = keys->erase(it);
continue;
}
}
if (mSelectType == KeyListRow::ONLY_SECRET_KEY && !it->is_private_key()) {
it = keys->erase(it);
continue;
}
row_count++;
it++;
} }
}
mKeyList->setRowCount(row_count); KeyIdArgsListPtr KeyList::getChecked(const KeyTable& key_table) {
auto ret = std::make_unique<KeyIdArgsList>();
int row_index = 0; for (int i = 0; i < key_table.key_list->rowCount(); i++) {
it = keys->begin(); if (key_table.key_list->item(i, 0)->checkState() == Qt::Checked) {
buffered_keys.clear(); ret->push_back(key_table.buffered_keys[i].id());
while (it != keys->end()) {
buffered_keys.push_back(GpgKeyGetter::GetInstance().GetKey(it->id()));
auto* tmp0 = new QTableWidgetItem(QString::number(row_index));
tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled |
Qt::ItemIsSelectable);
tmp0->setTextAlignment(Qt::AlignCenter);
tmp0->setCheckState(Qt::Unchecked);
mKeyList->setItem(row_index, 0, tmp0);
QString type_str;
QTextStream type_steam(&type_str);
if (it->is_private_key()) {
type_steam << "pub/sec";
} else {
type_steam << "pub";
} }
if (it->is_private_key() && !it->has_master_key()) {
type_steam << "#";
}
auto* tmp1 = new QTableWidgetItem(type_str);
mKeyList->setItem(row_index, 1, tmp1);
auto* tmp2 = new QTableWidgetItem(QString::fromStdString(it->name()));
mKeyList->setItem(row_index, 2, tmp2);
auto* tmp3 = new QTableWidgetItem(QString::fromStdString(it->email()));
mKeyList->setItem(row_index, 3, tmp3);
QString usage;
QTextStream usage_steam(&usage);
if (it->CanCertActual()) usage_steam << "C";
if (it->CanEncrActual()) usage_steam << "E";
if (it->CanSignActual()) usage_steam << "S";
if (it->CanAuthActual()) usage_steam << "A";
auto* temp_usage = new QTableWidgetItem(usage);
temp_usage->setTextAlignment(Qt::AlignCenter);
mKeyList->setItem(row_index, 4, temp_usage);
auto* temp_validity =
new QTableWidgetItem(QString::fromStdString(it->owner_trust()));
temp_validity->setTextAlignment(Qt::AlignCenter);
mKeyList->setItem(row_index, 5, temp_validity);
auto* temp_fpr = new QTableWidgetItem(QString::fromStdString(it->fpr()));
temp_fpr->setTextAlignment(Qt::AlignCenter);
mKeyList->setItem(row_index, 6, temp_fpr);
// strike out expired keys
if (it->expired() || it->revoked()) {
QFont strike = tmp2->font();
strike.setStrikeOut(true);
tmp0->setFont(strike);
temp_usage->setFont(strike);
temp_fpr->setFont(strike);
temp_validity->setFont(strike);
tmp1->setFont(strike);
tmp2->setFont(strike);
tmp3->setFont(strike);
}
it++;
++row_index;
} }
return ret;
setChecked(keyList);
} }
KeyIdArgsListPtr KeyList::getChecked() { KeyIdArgsListPtr KeyList::getChecked() {
auto key_list = qobject_cast<QTableWidget*>(mGroupTab->currentWidget());
const auto& buffered_keys =
mKeyTables[mGroupTab->currentIndex()].buffered_keys;
auto ret = std::make_unique<KeyIdArgsList>(); auto ret = std::make_unique<KeyIdArgsList>();
for (int i = 0; i < mKeyList->rowCount(); i++) { for (int i = 0; i < key_list->rowCount(); i++) {
if (mKeyList->item(i, 0)->checkState() == Qt::Checked) { if (key_list->item(i, 0)->checkState() == Qt::Checked) {
ret->push_back(buffered_keys[i].id()); ret->push_back(buffered_keys[i].id());
} }
} }
@ -232,9 +156,12 @@ KeyIdArgsListPtr KeyList::getChecked() {
} }
KeyIdArgsListPtr KeyList::getAllPrivateKeys() { KeyIdArgsListPtr KeyList::getAllPrivateKeys() {
auto key_list = qobject_cast<QTableWidget*>(mGroupTab->currentWidget());
const auto& buffered_keys =
mKeyTables[mGroupTab->currentIndex()].buffered_keys;
auto ret = std::make_unique<KeyIdArgsList>(); auto ret = std::make_unique<KeyIdArgsList>();
for (int i = 0; i < mKeyList->rowCount(); i++) { for (int i = 0; i < key_list->rowCount(); i++) {
if (mKeyList->item(i, 1) && buffered_keys[i].is_private_key()) { if (key_list->item(i, 1) && buffered_keys[i].is_private_key()) {
ret->push_back(buffered_keys[i].id()); ret->push_back(buffered_keys[i].id());
} }
} }
@ -243,21 +170,44 @@ KeyIdArgsListPtr KeyList::getAllPrivateKeys() {
KeyIdArgsListPtr KeyList::getPrivateChecked() { KeyIdArgsListPtr KeyList::getPrivateChecked() {
auto ret = std::make_unique<KeyIdArgsList>(); auto ret = std::make_unique<KeyIdArgsList>();
for (int i = 0; i < mKeyList->rowCount(); i++) { if (mGroupTab->size().isEmpty()) return ret;
if ((mKeyList->item(i, 0)->checkState() == Qt::Checked) &&
(mKeyList->item(i, 1))) { auto key_list = qobject_cast<QTableWidget*>(mGroupTab->currentWidget());
const auto& buffered_keys =
mKeyTables[mGroupTab->currentIndex()].buffered_keys;
for (int i = 0; i < key_list->rowCount(); i++) {
if ((key_list->item(i, 0)->checkState() == Qt::Checked) &&
(key_list->item(i, 1))) {
ret->push_back(buffered_keys[i].id()); ret->push_back(buffered_keys[i].id());
} }
} }
return ret; return ret;
} }
void KeyList::setChecked(const KeyIdArgsListPtr& keyIds) { void KeyList::setChecked(const KeyIdArgsListPtr& keyIds,
const KeyTable& key_table) {
if (!keyIds->empty()) { if (!keyIds->empty()) {
for (int i = 0; i < mKeyList->rowCount(); i++) { for (int i = 0; i < key_table.key_list->rowCount(); i++) {
if (std::find(keyIds->begin(), keyIds->end(),
key_table.buffered_keys[i].id()) != keyIds->end()) {
key_table.key_list->item(i, 0)->setCheckState(Qt::Checked);
}
}
}
}
void KeyList::setChecked(const KeyIdArgsListPtr& keyIds) {
if (mGroupTab->size().isEmpty()) return;
auto key_list = qobject_cast<QTableWidget*>(mGroupTab->currentWidget());
const auto& buffered_keys =
mKeyTables[mGroupTab->currentIndex()].buffered_keys;
if (!keyIds->empty()) {
for (int i = 0; i < key_list->rowCount(); i++) {
if (std::find(keyIds->begin(), keyIds->end(), buffered_keys[i].id()) != if (std::find(keyIds->begin(), keyIds->end(), buffered_keys[i].id()) !=
keyIds->end()) { keyIds->end()) {
mKeyList->item(i, 0)->setCheckState(Qt::Checked); key_list->item(i, 0)->setCheckState(Qt::Checked);
} }
} }
} }
@ -265,9 +215,14 @@ void KeyList::setChecked(const KeyIdArgsListPtr& keyIds) {
KeyIdArgsListPtr KeyList::getSelected() { KeyIdArgsListPtr KeyList::getSelected() {
auto ret = std::make_unique<KeyIdArgsList>(); auto ret = std::make_unique<KeyIdArgsList>();
if (mGroupTab->size().isEmpty()) return ret;
for (int i = 0; i < mKeyList->rowCount(); i++) { auto key_list = qobject_cast<QTableWidget*>(mGroupTab->currentWidget());
if (mKeyList->item(i, 0)->isSelected() == 1) { const auto& buffered_keys =
mKeyTables[mGroupTab->currentIndex()].buffered_keys;
for (int i = 0; i < key_list->rowCount(); i++) {
if (key_list->item(i, 0)->isSelected() == 1) {
ret->push_back(buffered_keys[i].id()); ret->push_back(buffered_keys[i].id());
} }
} }
@ -275,6 +230,9 @@ KeyIdArgsListPtr KeyList::getSelected() {
} }
[[maybe_unused]] bool KeyList::containsPrivateKeys() { [[maybe_unused]] bool KeyList::containsPrivateKeys() {
if (mGroupTab->size().isEmpty()) return false;
mKeyList = qobject_cast<QTableWidget*>(mGroupTab->currentWidget());
for (int i = 0; i < mKeyList->rowCount(); i++) { for (int i = 0; i < mKeyList->rowCount(); i++) {
if (mKeyList->item(i, 1)) { if (mKeyList->item(i, 1)) {
return true; return true;
@ -284,10 +242,16 @@ KeyIdArgsListPtr KeyList::getSelected() {
} }
void KeyList::setColumnWidth(int row, int size) { void KeyList::setColumnWidth(int row, int size) {
if (mGroupTab->size().isEmpty()) return;
mKeyList = qobject_cast<QTableWidget*>(mGroupTab->currentWidget());
mKeyList->setColumnWidth(row, size); mKeyList->setColumnWidth(row, size);
} }
void KeyList::contextMenuEvent(QContextMenuEvent* event) { void KeyList::contextMenuEvent(QContextMenuEvent* event) {
if (mGroupTab->size().isEmpty()) return;
mKeyList = qobject_cast<QTableWidget*>(mGroupTab->currentWidget());
if (mKeyList->selectedItems().length() > 0) { if (mKeyList->selectedItems().length() > 0) {
popupMenu->exec(event->globalPos()); popupMenu->exec(event->globalPos());
} }
@ -374,18 +338,10 @@ void KeyList::importKeys(const QByteArray& inBuffer) {
new KeyImportDetailDialog(result, false, this); new KeyImportDetailDialog(result, false, this);
} }
void KeyList::setExcludeKeys(std::initializer_list<std::string> key_ids) {
excluded_key_ids.clear();
for (auto& key_id : key_ids) {
excluded_key_ids.push_back(key_id);
}
}
void KeyList::setFilter(std::function<bool(const GpgKey&)> filter) {
this->mFilter = std::move(filter);
}
void KeyList::slotDoubleClicked(const QModelIndex& index) { void KeyList::slotDoubleClicked(const QModelIndex& index) {
if (mGroupTab->size().isEmpty()) return;
const auto& buffered_keys =
mKeyTables[mGroupTab->currentIndex()].buffered_keys;
if (mAction != nullptr) { if (mAction != nullptr) {
const auto key = const auto key =
GpgKeyGetter::GetInstance().GetKey(buffered_keys[index.row()].id()); GpgKeyGetter::GetInstance().GetKey(buffered_keys[index.row()].id());
@ -399,6 +355,10 @@ void KeyList::setDoubleClickedAction(
} }
std::string KeyList::getSelectedKey() { std::string KeyList::getSelectedKey() {
if (mGroupTab->size().isEmpty()) return {};
const auto& buffered_keys =
mKeyTables[mGroupTab->currentIndex()].buffered_keys;
for (int i = 0; i < mKeyList->rowCount(); i++) { for (int i = 0; i < mKeyList->rowCount(); i++) {
if (mKeyList->item(i, 0)->isSelected() == 1) { if (mKeyList->item(i, 0)->isSelected() == 1) {
return buffered_keys[i].id(); return buffered_keys[i].id();
@ -407,4 +367,128 @@ std::string KeyList::getSelectedKey() {
return {}; return {};
} }
KeyIdArgsListPtr KeyTable::GetChecked() {
auto ret = std::make_unique<KeyIdArgsList>();
for (int i = 0; i < key_list->rowCount(); i++) {
if (key_list->item(i, 0)->checkState() == Qt::Checked) {
ret->push_back(buffered_keys[i].id());
}
}
return ret;
}
void KeyTable::SetChecked(const KeyIdArgsListPtr& key_ids) {
if (!key_ids->empty()) {
for (int i = 0; i < key_list->rowCount(); i++) {
if (std::find(key_ids->begin(), key_ids->end(), buffered_keys[i].id()) !=
key_ids->end()) {
key_list->item(i, 0)->setCheckState(Qt::Checked);
}
}
}
}
void KeyTable::Refresh() {
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();
auto it = keys->begin();
int row_count = 0;
while (it != keys->end()) {
if (filter != nullptr) {
if (!filter(*it)) {
it = keys->erase(it);
continue;
}
}
if (select_type == KeyListRow::ONLY_SECRET_KEY && !it->is_private_key()) {
it = keys->erase(it);
continue;
}
row_count++;
it++;
}
key_list->setRowCount(row_count);
int row_index = 0;
it = keys->begin();
auto& table_buffered_keys = buffered_keys;
table_buffered_keys.clear();
while (it != keys->end()) {
table_buffered_keys.push_back(GpgKeyGetter::GetInstance().GetKey(it->id()));
auto* tmp0 = new QTableWidgetItem(QString::number(row_index));
tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled |
Qt::ItemIsSelectable);
tmp0->setTextAlignment(Qt::AlignCenter);
tmp0->setCheckState(Qt::Unchecked);
key_list->setItem(row_index, 0, tmp0);
QString type_str;
QTextStream type_steam(&type_str);
if (it->is_private_key()) {
type_steam << "pub/sec";
} else {
type_steam << "pub";
}
if (it->is_private_key() && !it->has_master_key()) {
type_steam << "#";
}
auto* tmp1 = new QTableWidgetItem(type_str);
key_list->setItem(row_index, 1, tmp1);
auto* tmp2 = new QTableWidgetItem(QString::fromStdString(it->name()));
key_list->setItem(row_index, 2, tmp2);
auto* tmp3 = new QTableWidgetItem(QString::fromStdString(it->email()));
key_list->setItem(row_index, 3, tmp3);
QString usage;
QTextStream usage_steam(&usage);
if (it->CanCertActual()) usage_steam << "C";
if (it->CanEncrActual()) usage_steam << "E";
if (it->CanSignActual()) usage_steam << "S";
if (it->CanAuthActual()) usage_steam << "A";
auto* temp_usage = new QTableWidgetItem(usage);
temp_usage->setTextAlignment(Qt::AlignCenter);
key_list->setItem(row_index, 4, temp_usage);
auto* temp_validity =
new QTableWidgetItem(QString::fromStdString(it->owner_trust()));
temp_validity->setTextAlignment(Qt::AlignCenter);
key_list->setItem(row_index, 5, temp_validity);
auto* temp_fpr = new QTableWidgetItem(QString::fromStdString(it->fpr()));
temp_fpr->setTextAlignment(Qt::AlignCenter);
key_list->setItem(row_index, 6, temp_fpr);
// strike out expired keys
if (it->expired() || it->revoked()) {
QFont strike = tmp2->font();
strike.setStrikeOut(true);
tmp0->setFont(strike);
temp_usage->setFont(strike);
temp_fpr->setFont(strike);
temp_validity->setFont(strike);
tmp1->setFont(strike);
tmp2->setFont(strike);
tmp3->setFont(strike);
}
it++;
++row_index;
}
SetChecked(checked_key_list);
}
} // namespace GpgFrontend::UI } // namespace GpgFrontend::UI

View File

@ -25,6 +25,8 @@
#ifndef __KEYLIST_H__ #ifndef __KEYLIST_H__
#define __KEYLIST_H__ #define __KEYLIST_H__
#include <utility>
#include "gpg/GpgContext.h" #include "gpg/GpgContext.h"
#include "ui/KeyImportDetailDialog.h" #include "ui/KeyImportDetailDialog.h"
namespace GpgFrontend::UI { namespace GpgFrontend::UI {
@ -48,6 +50,31 @@ struct KeyListColumn {
static constexpr InfoType FingerPrint = 1 << 5; static constexpr InfoType FingerPrint = 1 << 5;
}; };
struct KeyTable {
QTableWidget* key_list;
KeyListRow::KeyType select_type;
KeyListColumn::InfoType info_type;
std::vector<GpgKey> buffered_keys;
std::function<bool(const GpgKey&)> filter;
KeyTable(
QTableWidget* _key_list, KeyListRow::KeyType _select_type,
KeyListColumn::InfoType _info_type,
std::function<bool(const GpgKey&)> _filter = [](const GpgKey&) -> bool {
return true;
})
: key_list(_key_list),
select_type(_select_type),
info_type(_info_type),
filter(std::move(_filter)) {}
void Refresh();
KeyIdArgsListPtr GetChecked();
void SetChecked(const KeyIdArgsListPtr& key_ids);
};
class KeyList : public QWidget { class KeyList : public QWidget {
Q_OBJECT Q_OBJECT
@ -55,31 +82,34 @@ class KeyList : public QWidget {
explicit KeyList( explicit KeyList(
KeyListRow::KeyType selectType = KeyListRow::SECRET_OR_PUBLIC_KEY, KeyListRow::KeyType selectType = KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::InfoType infoType = KeyListColumn::ALL, KeyListColumn::InfoType infoType = KeyListColumn::ALL,
const std::function<bool(const GpgKey&)>& filter =
[](const GpgKey&) -> bool { return true; },
QWidget* parent = nullptr); QWidget* parent = nullptr);
void setExcludeKeys(std::initializer_list<std::string> key_ids); explicit KeyList(QWidget* parent);
void setFilter(std::function<bool(const GpgKey&)> filter); void addListGroupTab(
const QString& name,
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; });
void setDoubleClickedAction( void setDoubleClickedAction(
std::function<void(const GpgKey&, QWidget*)> action); std::function<void(const GpgKey&, QWidget*)> action);
void setColumnWidth(int row, int size); void setColumnWidth(int row, int size);
void addMenuAction(QAction* act); void addMenuAction(QAction* act);
void addSeparator(); void addSeparator();
KeyIdArgsListPtr getChecked(); KeyIdArgsListPtr getChecked();
static KeyIdArgsListPtr getChecked(const KeyTable& key_table);
KeyIdArgsListPtr getPrivateChecked(); KeyIdArgsListPtr getPrivateChecked();
KeyIdArgsListPtr getAllPrivateKeys(); KeyIdArgsListPtr getAllPrivateKeys();
void setChecked(const KeyIdArgsListPtr& keyIds); void setChecked(const KeyIdArgsListPtr& keyIds);
static void setChecked(const KeyIdArgsListPtr& keyIds,
const KeyTable& key_table);
KeyIdArgsListPtr getSelected(); KeyIdArgsListPtr getSelected();
std::string getSelectedKey(); std::string getSelectedKey();
[[maybe_unused]] static void markKeys(QStringList* keyIds); [[maybe_unused]] static void markKeys(QStringList* keyIds);
@ -91,20 +121,19 @@ class KeyList : public QWidget {
void slotRefresh(); void slotRefresh();
private: private:
void init();
void importKeys(const QByteArray& inBuffer); void importKeys(const QByteArray& inBuffer);
QString appPath; QString appPath;
QSettings settings; QSettings settings;
QTableWidget* mKeyList; QTabWidget* mGroupTab{};
QMenu* popupMenu; QTableWidget* mKeyList{};
QNetworkAccessManager* qnam{};
std::vector<GpgKey> buffered_keys; std::vector<KeyTable> mKeyTables;
KeyListRow::KeyType mSelectType;
KeyListColumn::InfoType mInfoType; QMenu* popupMenu{};
std::vector<std::string> excluded_key_ids;
std::function<bool(const GpgKey&)> mFilter = nullptr;
std::function<void(const GpgKey&, QWidget*)> mAction = nullptr; std::function<void(const GpgKey&, QWidget*)> mAction = nullptr;
private slots: private slots:

View File

@ -33,14 +33,13 @@ SignersPicker::SignersPicker(QWidget* parent) : QDialog(parent) {
/*Setup KeyList*/ /*Setup KeyList*/
mKeyList = new KeyList( mKeyList = new KeyList(
KeyListRow::ONLY_SECRET_KEY, KeyListRow::ONLY_SECRET_KEY,
KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage); KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage,
[](const GpgKey& key) -> bool {
mKeyList->setFilter([](const GpgKey& key) -> bool { if (!key.CanSignActual())
if (!key.CanSignActual()) return false;
return false; else
else return true;
return true; });
});
mKeyList->slotRefresh(); mKeyList->slotRefresh();

View File

@ -51,7 +51,8 @@ void TextEdit::slotNewTab() {
QString header = _("untitled") + QString::number(++countPage) + ".txt"; QString header = _("untitled") + QString::number(++countPage) + ".txt";
auto* page = new EditorPage(); auto* page = new EditorPage();
tabWidget->addTab(page, header); auto index = tabWidget->addTab(page, header);
tabWidget->setTabIcon(index, QIcon(":file.png"));
tabWidget->setCurrentIndex(tabWidget->count() - 1); tabWidget->setCurrentIndex(tabWidget->count() - 1);
page->getTextPage()->setFocus(); page->getTextPage()->setFocus();
connect(page->getTextPage()->document(), SIGNAL(modificationChanged(bool)), connect(page->getTextPage()->document(), SIGNAL(modificationChanged(bool)),
@ -66,10 +67,12 @@ void TextEdit::slotNewHelpTab(const QString& title, const QString& path) const {
void TextEdit::slotNewFileTab() const { void TextEdit::slotNewFileTab() const {
auto* page = new FilePage(qobject_cast<QWidget*>(parent())); auto* page = new FilePage(qobject_cast<QWidget*>(parent()));
tabWidget->addTab(page, "[Browser]"); auto index = tabWidget->addTab(page, QString());
tabWidget->setTabIcon(index, QIcon(":file-browser.png"));
tabWidget->setCurrentIndex(tabWidget->count() - 1); tabWidget->setCurrentIndex(tabWidget->count() - 1);
connect(page, SIGNAL(pathChanged(const QString&)), this, connect(page, &FilePage::pathChanged, this,
SLOT(slotFilePagePathChanged(const QString&))); &TextEdit::slotFilePagePathChanged);
page->slotGoPath();
} }
void TextEdit::slotOpenFile(QString& path) { void TextEdit::slotOpenFile(QString& path) {
@ -580,7 +583,6 @@ void TextEdit::slotFilePagePathChanged(const QString& path) const {
} else { } else {
mPath = tPath; mPath = tPath;
} }
mPath.prepend("[Browser] ");
tabWidget->setTabText(index, mPath); tabWidget->setTabText(index, mPath);
} }