diff options
author | saturneric <[email protected]> | 2025-01-26 18:17:20 +0000 |
---|---|---|
committer | saturneric <[email protected]> | 2025-01-26 18:18:10 +0000 |
commit | 92e1ed7b3fd5360278d41db087518b6c5af80b3e (patch) | |
tree | 577edfa58889d97a0b3ec1f2c045b9d6fe9cff70 /src/ui/main_window/MainWindowFileSlotFunction.cpp | |
parent | fix: 'std::future' is defined in header '<future>' (diff) | |
download | GpgFrontend-92e1ed7b3fd5360278d41db087518b6c5af80b3e.tar.gz GpgFrontend-92e1ed7b3fd5360278d41db087518b6c5af80b3e.zip |
feat: allow file batch operations
Diffstat (limited to 'src/ui/main_window/MainWindowFileSlotFunction.cpp')
-rw-r--r-- | src/ui/main_window/MainWindowFileSlotFunction.cpp | 1590 |
1 files changed, 794 insertions, 796 deletions
diff --git a/src/ui/main_window/MainWindowFileSlotFunction.cpp b/src/ui/main_window/MainWindowFileSlotFunction.cpp index e2fe86bd..bfda5a8b 100644 --- a/src/ui/main_window/MainWindowFileSlotFunction.cpp +++ b/src/ui/main_window/MainWindowFileSlotFunction.cpp @@ -39,589 +39,747 @@ #include "core/utils/IOUtils.h" #include "ui/UserInterfaceUtils.h" #include "ui/dialog/SignersPicker.h" +#include "ui/struct/GpgOperaResult.h" +#include "ui/struct/GpgOperaResultContext.h" #include "ui/widgets/KeyList.h" namespace GpgFrontend::UI { -void MainWindow::SlotFileEncrypt(const QString& path) { - auto check_result = TargetFilePreCheck(path, true); - if (!std::get<0>(check_result)) { - QMessageBox::critical( - this, tr("Error"), - tr("Cannot read from file: %1").arg(QFileInfo(path).fileName())); - return; +auto MainWindow::check_read_file_paths_helper(const QContainer<QString>& paths) + -> bool { + QStringList invalid_files; + for (const auto& path : paths) { + auto result = TargetFilePreCheck(path, true); + if (!std::get<0>(result)) { + invalid_files.append(path); + } } - bool const non_ascii_at_file_operation = - GlobalSettingStation::GetInstance() - .GetSettings() - .value("gnupg/non_ascii_at_file_operation", true) - .toBool(); - auto out_path = - SetExtensionOfOutputFile(path, kENCRYPT, !non_ascii_at_file_operation); + if (!invalid_files.empty()) { + QString error_file_names; + for (const auto& file_path : invalid_files) { + error_file_names += QFileInfo(file_path).fileName() + "\n"; + } + + QMessageBox::critical(this, tr("Error"), + tr("Cannot read from the following files:\n\n%1") + .arg(error_file_names.trimmed())); + return false; + } - if (QFile::exists(out_path)) { - auto out_file_name = tr("The target file %1 already exists, " - "do you need to overwrite it?") - .arg(out_path); - auto ret = QMessageBox::warning(this, tr("Warning"), out_file_name, - QMessageBox::Ok | QMessageBox::Cancel); + return true; +} - if (ret == QMessageBox::Cancel) return; +auto MainWindow::check_write_file_paths_helper( + const QContainer<QString>& o_paths) -> bool { + for (const auto& o_path : o_paths) { + if (QFile::exists(o_path)) { + auto out_file_name = tr("The target file %1 already exists, " + "do you need to overwrite it?") + .arg(QFileInfo(o_path).fileName()); + auto ret = QMessageBox::warning(this, tr("Warning"), out_file_name, + QMessageBox::Ok | QMessageBox::Cancel); + + if (ret == QMessageBox::Cancel) return false; + } } - check_result = TargetFilePreCheck(out_path, false); - if (!std::get<0>(check_result)) { - QMessageBox::critical(this, tr("Error"), - tr("Cannot write to file: %1").arg(out_path)); - return; + QStringList invalid_output_files; + for (const auto& path : o_paths) { + auto result = TargetFilePreCheck(path, false); + if (!std::get<0>(result)) { + invalid_output_files.append(path); + } } - // check selected keys - auto key_ids = m_key_list_->GetChecked(); - if (key_ids.empty()) { - // Symmetric Encrypt - auto ret = QMessageBox::information( - this, tr("Symmetric Encryption"), - tr("No Key Selected. Do you want to encrypt with a " - "symmetric cipher using a passphrase?"), - QMessageBox::Ok | QMessageBox::Cancel); - if (ret == QMessageBox::Cancel) return; + if (!invalid_output_files.empty()) { + QString error_file_names; + for (const auto& file_path : invalid_output_files) { + error_file_names += QFileInfo(file_path).fileName() + "\n"; + } - CommonUtils::WaitForOpera( - this, tr("Symmetrically Encrypting"), [=](const OperaWaitingHd& op_hd) { - GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .EncryptFileSymmetric( - path, !non_ascii_at_file_operation, out_path, - [=](GpgError err, const DataObjectPtr& data_obj) { - // stop waiting - op_hd(); - - if (CheckGpgError(err) == GPG_ERR_USER_1 || - data_obj == nullptr || - !data_obj->Check<GpgEncryptResult>()) { - QMessageBox::critical(this, tr("Error"), - tr("Unknown error occurred")); - return; - } - - auto result = ExtractParams<GpgEncryptResult>(data_obj, 0); - auto result_analyse = GpgEncryptResultAnalyse( - m_key_list_->GetCurrentGpgContextChannel(), err, - result); - result_analyse.Analyse(); - - slot_result_analyse_show_helper(result_analyse); - this->slot_refresh_current_file_view(); - }); - }); + QMessageBox::critical(this, tr("Error"), + tr("Cannot write to the following files:\n\n%1") + .arg(error_file_names.trimmed())); + return false; + } - return; + return true; +} + +auto MainWindow::check_keys_helper( + const KeyIdArgsList& key_ids, + const std::function<bool(const GpgKey&)>& capability_check, + const QString& capability_err_string) -> GpgKeyList { + if (key_ids.empty()) { + QMessageBox::critical( + this, tr("No Key Checked"), + tr("Please check the key in the key toolbox on the right.")); + return {}; } - auto p_keys = + auto keys = GpgKeyGetter::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) .GetKeys(key_ids); - assert(std::all_of(p_keys.begin(), p_keys.end(), + assert(std::all_of(keys.begin(), keys.end(), [](const auto& key) { return key.IsGood(); })); // check key abilities - for (const auto& key : p_keys) { - bool const key_can_encrypt = key.IsHasActualEncryptionCapability(); - - if (!key_can_encrypt) { - QMessageBox::critical( - nullptr, tr("Invalid KeyPair"), - tr("The selected keypair cannot be used for encryption.") + - "<br/><br/>" + tr("For example the Following Key:") + " <br/>" + - key.GetUIDs()->front().GetUID()); - return; + for (const auto& key : keys) { + if (!capability_check(key)) { + QMessageBox::critical(nullptr, tr("Invalid KeyPair"), + capability_err_string + "<br/><br/>" + + tr("For example the Following Key:") + + " <br/>" + key.GetUIDs()->front().GetUID()); + return {}; } } - CommonUtils::WaitForOpera( - this, tr("Encrypting"), [=](const OperaWaitingHd& op_hd) { - GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .EncryptFile( - {p_keys.begin(), p_keys.end()}, path, - !non_ascii_at_file_operation, out_path, - [=](GpgError err, const DataObjectPtr& data_obj) { - // stop waiting - op_hd(); - - if (CheckGpgError(err) == GPG_ERR_USER_1 || - data_obj == nullptr || - !data_obj->Check<GpgEncryptResult>()) { - QMessageBox::critical(this, tr("Error"), - tr("Unknown error occurred")); - return; - } - - auto result = ExtractParams<GpgEncryptResult>(data_obj, 0); - auto result_analyse = GpgEncryptResultAnalyse( - m_key_list_->GetCurrentGpgContextChannel(), err, result); - result_analyse.Analyse(); - - slot_result_analyse_show_helper(result_analyse); - this->slot_refresh_current_file_view(); - }); - }); + return keys; } -void MainWindow::SlotDirectoryEncrypt(const QString& path) { - auto check_result = TargetFilePreCheck(path, true); - if (!std::get<0>(check_result)) { - QMessageBox::critical( - this, tr("Error"), - tr("Cannot read from file: %1").arg(QFileInfo(path).fileName())); - return; +auto MainWindow::execute_operas_helper( + const QString& task, const QSharedPointer<GpgOperaContexts>& contexts) { + CommonUtils::WaitForMultipleOperas(this, task, contexts->operas); + slot_result_analyse_show_helper(contexts->opera_results); +} + +void MainWindow::build_operas_file_symmetric_encrypt( + QSharedPointer<GpgOperaContext>& context) { + assert(context->paths.size() == context->o_paths.size()); + + for (int i = 0; i < context->paths.size(); i++) { + const auto& path = context->paths[i]; + const auto& o_path = context->o_paths[i]; + + auto opera = [=, &opera_results = + context->opera_results](const OperaWaitingHd& op_hd) { + GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) + .EncryptFileSymmetric( + path, context->ascii, o_path, + [=, &opera_results](GpgError err, const DataObjectPtr& data_obj) { + // stop waiting + op_hd(); + + if (CheckGpgError(err) == GPG_ERR_USER_1 || + data_obj == nullptr || + !data_obj->Check<GpgEncryptResult>()) { + QMessageBox::critical(this, tr("Error"), + tr("Unknown error occurred")); + return; + } + + auto result = ExtractParams<GpgEncryptResult>(data_obj, 0); + auto result_analyse = GpgEncryptResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, result); + result_analyse.Analyse(); + + opera_results.append({result_analyse.GetStatus(), + result_analyse.GetResultReport(), + QFileInfo(path).fileName()}); + }); + }; + + context->operas.push_back(opera); } +} + +void MainWindow::build_operas_file_encrypt( + QSharedPointer<GpgOperaContext>& context) { + assert(context->paths.size() == context->o_paths.size()); + + for (int i = 0; i < context->paths.size(); i++) { + const auto& path = context->paths[i]; + const auto& o_path = context->o_paths[i]; + + auto opera = [=, &opera_results = + context->opera_results](const OperaWaitingHd& op_hd) { + GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) + .EncryptFile( + context->keys, path, context->ascii, o_path, + [=, &opera_results](GpgError err, const DataObjectPtr& data_obj) { + // stop waiting + op_hd(); + + if (CheckGpgError(err) == GPG_ERR_USER_1 || + data_obj == nullptr || + !data_obj->Check<GpgEncryptResult>()) { + QMessageBox::critical(this, tr("Error"), + tr("Unknown error occurred")); + return; + } + + auto result = ExtractParams<GpgEncryptResult>(data_obj, 0); + auto result_analyse = GpgEncryptResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, result); + result_analyse.Analyse(); + + opera_results.append({result_analyse.GetStatus(), + result_analyse.GetResultReport(), + QFileInfo(path).fileName()}); + }); + }; + + context->operas.push_back(opera); + } +} + +void MainWindow::build_operas_directory_symmetric_encrypt( + QSharedPointer<GpgOperaContext>& context) { + assert(context->paths.size() == context->o_paths.size()); + + for (int i = 0; i < context->paths.size(); i++) { + const auto& path = context->paths[i]; + const auto& o_path = context->o_paths[i]; + + auto opera = [=, &opera_results = + context->opera_results](const OperaWaitingHd& op_hd) { + GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) + .EncryptDirectorySymmetric( + path, context->ascii, o_path, + [=, &opera_results](GpgError err, const DataObjectPtr& data_obj) { + // stop waiting + op_hd(); + + if (data_obj == nullptr || + !data_obj->Check<GpgEncryptResult>()) { + QMessageBox::critical(this, tr("Error"), + tr("Unknown error occurred")); + return; + } + + auto result = ExtractParams<GpgEncryptResult>(data_obj, 0); + auto result_analyse = GpgEncryptResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, result); + result_analyse.Analyse(); + + opera_results.append({result_analyse.GetStatus(), + result_analyse.GetResultReport(), + QFileInfo(path).fileName()}); + }); + }; + + context->operas.push_back(opera); + } +} + +void MainWindow::build_operas_directory_encrypt( + QSharedPointer<GpgOperaContext>& context) { + assert(context->paths.size() == context->o_paths.size()); + + for (int i = 0; i < context->paths.size(); i++) { + const auto& path = context->paths[i]; + const auto& o_path = context->o_paths[i]; + + auto opera = [=, &opera_results = + context->opera_results](const OperaWaitingHd& op_hd) { + GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) + .EncryptDirectory( + context->keys, path, context->ascii, o_path, + [=, &opera_results](GpgError err, const DataObjectPtr& data_obj) { + // stop waiting + op_hd(); + + if (CheckGpgError(err) == GPG_ERR_USER_1 || + data_obj == nullptr || + !data_obj->Check<GpgEncryptResult>()) { + QMessageBox::critical(this, tr("Error"), + tr("Unknown error occurred")); + return; + } + + auto result = ExtractParams<GpgEncryptResult>(data_obj, 0); + auto result_analyse = GpgEncryptResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, result); + result_analyse.Analyse(); + + opera_results.append({result_analyse.GetStatus(), + result_analyse.GetResultReport(), + QFileInfo(path).fileName()}); + }); + }; + + context->operas.push_back(opera); + } +} + +void MainWindow::SlotFileEncrypt(const QContainer<QString>& paths) { + auto contexts = QSharedPointer<GpgOperaContexts>::create(); bool const non_ascii_at_file_operation = GlobalSettingStation::GetInstance() .GetSettings() .value("gnupg/non_ascii_at_file_operation", true) .toBool(); - auto out_path = SetExtensionOfOutputFileForArchive( - path, kENCRYPT, !non_ascii_at_file_operation); - if (QFile::exists(out_path)) { - auto out_file_name = tr("The target file %1 already exists, " - "do you need to overwrite it?") - .arg(out_path); - auto ret = QMessageBox::warning(this, tr("Warning"), out_file_name, - QMessageBox::Ok | QMessageBox::Cancel); + contexts->ascii = !non_ascii_at_file_operation; - if (ret == QMessageBox::Cancel) return; - } - - check_result = TargetFilePreCheck(out_path, false); - if (!std::get<0>(check_result)) { - QMessageBox::critical(this, tr("Error"), - tr("Cannot write to file: %1").arg(out_path)); - return; - } - - // check selected keys + bool is_symmetric = false; auto key_ids = m_key_list_->GetChecked(); - // symmetric encrypt - if (key_ids.empty()) { + + // Symmetric Encrypt + if (key_ids.isEmpty()) { auto ret = QMessageBox::information( this, tr("Symmetric Encryption"), tr("No Key Selected. Do you want to encrypt with a " "symmetric cipher using a passphrase?"), QMessageBox::Ok | QMessageBox::Cancel); if (ret == QMessageBox::Cancel) return; - - CommonUtils::WaitForOpera( - this, tr("Archiving & Symmetrically Encrypting"), - [=](const OperaWaitingHd& op_hd) { - GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .EncryptDerectorySymmetric( - path, !non_ascii_at_file_operation, out_path, - [=](GpgError err, const DataObjectPtr& data_obj) { - // stop waiting - op_hd(); - - if (data_obj == nullptr || - !data_obj->Check<GpgEncryptResult>()) { - QMessageBox::critical(this, tr("Error"), - tr("Unknown error occurred")); - return; - } - - auto result = ExtractParams<GpgEncryptResult>(data_obj, 0); - auto result_analyse = GpgEncryptResultAnalyse( - m_key_list_->GetCurrentGpgContextChannel(), err, - result); - result_analyse.Analyse(); - - slot_result_analyse_show_helper(result_analyse); - this->slot_refresh_current_file_view(); - }); - }); - - return; + is_symmetric = true; + } else { + contexts->keys = check_keys_helper( + key_ids, + [](const GpgKey& key) { return key.IsHasActualEncryptionCapability(); }, + tr("The selected keypair cannot be used for encryption.")); + if (contexts->keys.empty()) return; + } + + if (!check_read_file_paths_helper(paths)) return; + + for (const auto& path : paths) { + QFileInfo info(path); + if (info.isDir()) { + contexts->GetContextPath(1).append(path); + contexts->GetContextOutPath(1).append( + SetExtensionOfOutputFileForArchive(path, kENCRYPT, contexts->ascii)); + } else { + contexts->GetContextPath(0).append(path); + contexts->GetContextOutPath(0).append( + SetExtensionOfOutputFile(path, kENCRYPT, contexts->ascii)); + } } - auto p_keys = - GpgKeyGetter::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .GetKeys(key_ids); - assert(std::all_of(p_keys.begin(), p_keys.end(), - [](const auto& key) { return key.IsGood(); })); + if (!check_write_file_paths_helper(contexts->GetAllOutPath())) return; - // check key abilities - for (const auto& key : p_keys) { - bool const key_can_encrypt = key.IsHasActualEncryptionCapability(); - - if (!key_can_encrypt) { - QMessageBox::critical( - nullptr, tr("Invalid KeyPair"), - tr("The selected keypair cannot be used for encryption.") + - "<br/><br/>" + tr("For example the Following Key:") + " <br/>" + - key.GetUIDs()->front().GetUID()); - return; + // Symmetric Encrypt + if (is_symmetric) { + auto f_context = contexts->GetContext(0); + if (f_context != nullptr) build_operas_file_symmetric_encrypt(f_context); + + auto d_context = contexts->GetContext(1); + if (d_context != nullptr) { + build_operas_directory_symmetric_encrypt(d_context); } + } else { + auto f_context = contexts->GetContext(0); + if (f_context != nullptr) build_operas_file_encrypt(f_context); + + auto d_context = contexts->GetContext(1); + if (d_context != nullptr) build_operas_directory_encrypt(d_context); } - CommonUtils::WaitForOpera( - this, tr("Archiving & Encrypting"), [=](const OperaWaitingHd& op_hd) { - GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .EncryptDirectory( - {p_keys.begin(), p_keys.end()}, path, - !non_ascii_at_file_operation, out_path, - [=](GpgError err, const DataObjectPtr& data_obj) { - // stop waiting - op_hd(); - - if (CheckGpgError(err) == GPG_ERR_USER_1 || - data_obj == nullptr || - !data_obj->Check<GpgEncryptResult>()) { - QMessageBox::critical(this, tr("Error"), - tr("Unknown error occurred")); - return; - } - - auto result = ExtractParams<GpgEncryptResult>(data_obj, 0); - auto result_analyse = GpgEncryptResultAnalyse( - m_key_list_->GetCurrentGpgContextChannel(), err, result); - result_analyse.Analyse(); - - slot_result_analyse_show_helper(result_analyse); - this->slot_refresh_current_file_view(); - }); - }); + execute_operas_helper(tr("Encrypting"), contexts); } -void MainWindow::SlotFileDecrypt(const QString& path) { - auto check_result = TargetFilePreCheck(path, true); - if (!std::get<0>(check_result)) { - QMessageBox::critical( - this, tr("Error"), - tr("Cannot read from file: %1").arg(QFileInfo(path).fileName())); - return; +/** + * @brief + * + * @param context + */ +void MainWindow::build_operas_file_decrypt( + QSharedPointer<GpgOperaContext>& context) { + assert(context->paths.size() == context->o_paths.size()); + + for (int i = 0; i < context->paths.size(); i++) { + const auto& path = context->paths[i]; + const auto& o_path = context->o_paths[i]; + + auto opera = [=, &opera_results = + context->opera_results](const OperaWaitingHd& op_hd) { + GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) + .DecryptFile( + path, o_path, + [=, &opera_results](GpgError err, const DataObjectPtr& data_obj) { + // stop waiting + op_hd(); + + if (CheckGpgError(err) == GPG_ERR_USER_1 || + data_obj == nullptr || + !data_obj->Check<GpgDecryptResult>()) { + QMessageBox::critical(this, tr("Error"), + tr("Unknown error occurred")); + return; + } + + auto result = ExtractParams<GpgDecryptResult>(data_obj, 0); + auto result_analyse = GpgDecryptResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, result); + result_analyse.Analyse(); + + opera_results.append({result_analyse.GetStatus(), + result_analyse.GetResultReport(), + QFileInfo(path).fileName()}); + }); + }; + + context->operas.push_back(opera); } +} - auto out_path = SetExtensionOfOutputFile(path, kDECRYPT, true); - if (QFileInfo(out_path).exists()) { - auto ret = QMessageBox::warning( - this, tr("Warning"), - tr("The target file already exists, do you need to overwrite it?"), - QMessageBox::Ok | QMessageBox::Cancel); - - if (ret == QMessageBox::Cancel) return; +void MainWindow::build_operas_archive_decrypt( + QSharedPointer<GpgOperaContext>& context) { + assert(context->paths.size() == context->o_paths.size()); + + for (int i = 0; i < context->paths.size(); i++) { + const auto& path = context->paths[i]; + const auto& o_path = context->o_paths[i]; + + auto opera = [=, &opera_results = + context->opera_results](const OperaWaitingHd& op_hd) { + GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) + .DecryptArchive( + path, o_path, + [=, &opera_results](GpgError err, const DataObjectPtr& data_obj) { + // stop waiting + op_hd(); + + if (CheckGpgError(err) == GPG_ERR_USER_1 || + data_obj == nullptr || + !data_obj->Check<GpgDecryptResult>()) { + QMessageBox::critical(this, tr("Error"), + tr("Unknown error occurred")); + return; + } + + auto result = ExtractParams<GpgDecryptResult>(data_obj, 0); + auto result_analyse = GpgDecryptResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, result); + result_analyse.Analyse(); + + opera_results.append({result_analyse.GetStatus(), + result_analyse.GetResultReport(), + QFileInfo(path).fileName()}); + }); + }; + + context->operas.push_back(opera); } +} - check_result = TargetFilePreCheck(out_path, false); - if (!std::get<0>(check_result)) { - QMessageBox::critical(this, tr("Error"), - tr("Cannot write to file: %1").arg(out_path)); - return; - } +void MainWindow::SlotFileDecrypt(const QContainer<QString>& paths) { + auto contexts = QSharedPointer<GpgOperaContexts>::create(); - CommonUtils::WaitForOpera( - this, tr("Decrypting"), [=](const OperaWaitingHd& op_hd) { - GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .DecryptFile( - path, out_path, - [=](GpgError err, const DataObjectPtr& data_obj) { - // stop waiting - op_hd(); - - if (CheckGpgError(err) == GPG_ERR_USER_1 || - data_obj == nullptr || - !data_obj->Check<GpgDecryptResult>()) { - QMessageBox::critical(this, tr("Error"), - tr("Unknown error occurred")); - return; - } - - auto result = ExtractParams<GpgDecryptResult>(data_obj, 0); - auto result_analyse = GpgDecryptResultAnalyse( - m_key_list_->GetCurrentGpgContextChannel(), err, result); - result_analyse.Analyse(); - - slot_result_analyse_show_helper(result_analyse); - this->slot_refresh_current_file_view(); - }); - }); -} + contexts->ascii = true; -void MainWindow::SlotArchiveDecrypt(const QString& path) { - auto check_result = TargetFilePreCheck(path, true); - if (!std::get<0>(check_result)) { - QMessageBox::critical(this, tr("Error"), - tr("Cannot read from file: %1").arg(path)); - return; - } + if (!check_read_file_paths_helper(paths)) return; - auto out_path = SetExtensionOfOutputFileForArchive(path, kDECRYPT, true); - if (QFileInfo(out_path).exists()) { - auto ret = QMessageBox::warning( - this, tr("Warning"), - tr("The target file already exists, do you need to overwrite it?"), - QMessageBox::Ok | QMessageBox::Cancel); + for (const auto& path : paths) { + QFileInfo info(path); + const auto extension = info.completeSuffix(); - if (ret == QMessageBox::Cancel) return; + if (extension == "tar.gpg" || extension == "tar.asc") { + contexts->GetContextPath(1).append(path); + contexts->GetContextOutPath(1).append( + SetExtensionOfOutputFileForArchive(path, kDECRYPT, contexts->ascii)); + } else { + contexts->GetContextPath(0).append(path); + contexts->GetContextOutPath(0).append( + SetExtensionOfOutputFile(path, kDECRYPT, contexts->ascii)); + } } - check_result = TargetFilePreCheck(out_path, false); - if (!std::get<0>(check_result)) { - QMessageBox::critical(this, tr("Error"), - tr("Cannot write to file: %1").arg(out_path)); - return; - } + if (!check_write_file_paths_helper(contexts->GetAllOutPath())) return; - CommonUtils::WaitForOpera( - this, tr("Decrypting & Extrating"), [=](const OperaWaitingHd& op_hd) { - GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .DecryptArchive( - path, out_path, - [=](GpgError err, const DataObjectPtr& data_obj) { - // stop waiting - op_hd(); - - if (CheckGpgError(err) == GPG_ERR_USER_1 || - data_obj == nullptr || - !data_obj->Check<GpgDecryptResult>()) { - QMessageBox::critical(this, tr("Error"), - tr("Unknown error occurred")); - return; - } - - auto result = ExtractParams<GpgDecryptResult>(data_obj, 0); - auto result_analyse = GpgDecryptResultAnalyse( - m_key_list_->GetCurrentGpgContextChannel(), err, result); - result_analyse.Analyse(); - - slot_result_analyse_show_helper(result_analyse); - this->slot_refresh_current_file_view(); - }); - }); -} + auto f_context = contexts->GetContext(0); + if (f_context != nullptr) build_operas_file_decrypt(f_context); -void MainWindow::SlotFileSign(const QString& path) { - auto check_result = TargetFilePreCheck(path, true); - if (!std::get<0>(check_result)) { - QMessageBox::critical( - this, tr("Error"), - tr("Cannot read from file: %1").arg(QFileInfo(path).fileName())); - return; + auto d_context = contexts->GetContext(1); + if (d_context != nullptr) { + build_operas_archive_decrypt(d_context); } - auto key_ids = m_key_list_->GetChecked(); - auto keys = - GpgKeyGetter::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .GetKeys(key_ids); - assert(std::all_of(keys.begin(), keys.end(), - [](const auto& key) { return key.IsGood(); })); + execute_operas_helper(tr("Decrypting"), contexts); +} - if (keys.empty()) { - QMessageBox::critical( - this, tr("No Key Checked"), - tr("Please check the key in the key toolbox on the right.")); - return; +void MainWindow::build_operas_file_sign( + QSharedPointer<GpgOperaContext>& context) { + assert(context->paths.size() == context->o_paths.size()); + + for (int i = 0; i < context->paths.size(); i++) { + const auto& path = context->paths[i]; + const auto& o_path = context->o_paths[i]; + + auto opera = [=, &opera_results = + context->opera_results](const OperaWaitingHd& op_hd) { + GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) + .SignFile( + context->keys, path, context->ascii, o_path, + [=, &opera_results](GpgError err, const DataObjectPtr& data_obj) { + // stop waiting + op_hd(); + + if (CheckGpgError(err) == GPG_ERR_USER_1 || + data_obj == nullptr || !data_obj->Check<GpgSignResult>()) { + QMessageBox::critical(this, tr("Error"), + tr("Unknown error occurred")); + return; + } + + auto result = ExtractParams<GpgSignResult>(data_obj, 0); + auto result_analyse = GpgSignResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, result); + result_analyse.Analyse(); + + opera_results.append({result_analyse.GetStatus(), + result_analyse.GetResultReport(), + QFileInfo(path).fileName()}); + }); + }; + + context->operas.push_back(opera); } +} - for (const auto& key : keys) { - if (!key.IsHasActualSigningCapability()) { - QMessageBox::information( - this, tr("Invalid Operation"), - tr("The selected key contains a key that does not actually " - "have a sign usage.") + - "<br/><br/>" + tr("for example the Following Key:") + " <br/>" + - key.GetUIDs()->front().GetUID()); - return; - } - } +void MainWindow::SlotFileSign(const QContainer<QString>& paths) { + auto contexts = QSharedPointer<GpgOperaContexts>::create(); bool const non_ascii_at_file_operation = GlobalSettingStation::GetInstance() .GetSettings() .value("gnupg/non_ascii_at_file_operation", true) .toBool(); - auto sig_file_path = - SetExtensionOfOutputFile(path, kSIGN, !non_ascii_at_file_operation); - if (QFileInfo(sig_file_path).exists()) { - auto ret = QMessageBox::warning(this, tr("Warning"), - tr("The signature file \"%1\" exists, " - "do you need to overwrite it?") - .arg(sig_file_path), - QMessageBox::Ok | QMessageBox::Cancel); + contexts->ascii = !non_ascii_at_file_operation; - if (ret == QMessageBox::Cancel) return; + auto key_ids = m_key_list_->GetChecked(); + + contexts->keys = check_keys_helper( + key_ids, + [](const GpgKey& key) { return key.IsHasActualSigningCapability(); }, + tr("The selected key contains a key that does not actually have a sign " + "usage.")); + if (contexts->keys.empty()) return; + + if (!check_read_file_paths_helper(paths)) return; + + for (const auto& path : paths) { + QFileInfo info(path); + contexts->GetContextPath(0).append(path); + contexts->GetContextOutPath(0).append( + SetExtensionOfOutputFile(path, kSIGN, contexts->ascii)); } - CommonUtils::WaitForOpera( - this, tr("Signing"), [=](const OperaWaitingHd& op_hd) { - GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .SignFile({keys.begin(), keys.end()}, path, - !non_ascii_at_file_operation, sig_file_path, - [=](GpgError err, const DataObjectPtr& data_obj) { - // stop waiting - op_hd(); - - if (CheckGpgError(err) == GPG_ERR_USER_1 || - data_obj == nullptr || - !data_obj->Check<GpgSignResult>()) { - QMessageBox::critical(this, tr("Error"), - tr("Unknown error occurred")); - return; - } - - auto result = ExtractParams<GpgSignResult>(data_obj, 0); - auto result_analyse = GpgSignResultAnalyse( - m_key_list_->GetCurrentGpgContextChannel(), err, - result); - result_analyse.Analyse(); - - slot_result_analyse_show_helper(result_analyse); - this->slot_refresh_current_file_view(); - }); - }); + if (!check_write_file_paths_helper(contexts->GetAllOutPath())) return; + + auto f_context = contexts->GetContext(0); + if (f_context != nullptr) build_operas_file_sign(f_context); + + execute_operas_helper(tr("Signing"), contexts); } -void MainWindow::SlotFileVerify(const QString& path) { - auto check_result = TargetFilePreCheck(path, true); - if (!std::get<0>(check_result)) { - QMessageBox::critical( - this, tr("Error"), - tr("Cannot read from file: %1").arg(QFileInfo(path).fileName())); - return; +void MainWindow::build_operas_file_verify( + QSharedPointer<GpgOperaContext>& context) { + assert(context->paths.size() == context->o_paths.size()); + + for (int i = 0; i < context->paths.size(); i++) { + const auto& path = context->paths[i]; + const auto& o_path = context->o_paths[i]; + + auto opera = [=, &opera_results = + context->opera_results](const OperaWaitingHd& op_hd) { + GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) + .VerifyFile( + o_path, path, + [=, &opera_results](GpgError err, const DataObjectPtr& data_obj) { + // stop waiting + op_hd(); + + if (CheckGpgError(err) == GPG_ERR_USER_1 || + data_obj == nullptr || + !data_obj->Check<GpgVerifyResult>()) { + QMessageBox::critical(this, tr("Error"), + tr("Unknown error occurred")); + return; + } + + auto result = ExtractParams<GpgVerifyResult>(data_obj, 0); + auto result_analyse = GpgVerifyResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, result); + result_analyse.Analyse(); + + slot_result_analyse_show_helper(result_analyse); + + if (!result_analyse.GetUnknownSignatures().isEmpty() && + Module::IsModuleActivate(kKeyServerSyncModuleID)) { + slot_verifying_unknown_signature_helper(result_analyse); + } + + opera_results.append( + {result_analyse.GetStatus(), + result_analyse.GetResultReport(), + QFileInfo(path.isEmpty() ? o_path : path).fileName()}); + }); + }; + + context->operas.push_back(opera); } +} - auto file_info = QFileInfo(path); - QString sign_file_path = path; - QString data_file_path; +void MainWindow::SlotFileVerify(const QContainer<QString>& paths) { + auto contexts = QSharedPointer<GpgOperaContexts>::create(); - bool const prossible_singleton_target = - file_info.suffix() == "gpg" || file_info.suffix() == "pgp"; - if (prossible_singleton_target) { - swap(data_file_path, sign_file_path); - } else { - data_file_path = file_info.path() + "/" + file_info.completeBaseName(); - } + if (!check_read_file_paths_helper(paths)) return; - auto data_file_info = QFileInfo(data_file_path); - if (!prossible_singleton_target && !data_file_info.exists()) { - bool ok; - QString const text = QInputDialog::getText( - this, tr("File to be Verified"), - tr("Please provide An ABSOLUTE Path \n" - "If Data And Signature is COMBINED within a single file, " - "KEEP THIS EMPTY: "), - QLineEdit::Normal, data_file_path, &ok); + for (const auto& path : paths) { + QFileInfo info(path); - if (!ok) return; + QString sign_file_path = path; + QString data_file_path; - data_file_path = text.isEmpty() ? data_file_path : text; - data_file_info = QFileInfo(data_file_path); - } + bool const possible_singleton_target = + info.suffix() == "gpg" || info.suffix() == "pgp"; + if (possible_singleton_target) { + swap(data_file_path, sign_file_path); + } else { + data_file_path = info.path() + "/" + info.completeBaseName(); + } - if (!data_file_info.isFile() || - (!sign_file_path.isEmpty() && !QFileInfo(sign_file_path).isFile())) { - QMessageBox::critical( - this, tr("Error"), - tr("Please select the appropriate origin file or signature file. " - "Ensure that both are in this directory.")); - return; - } + auto data_file_info = QFileInfo(data_file_path); + if (!possible_singleton_target && !data_file_info.exists()) { + bool ok; + QString const text = QInputDialog::getText( + this, tr("File to be Verified"), + tr("Please provide An ABSOLUTE Path \n" + "If Data And Signature is COMBINED within a single file, " + "KEEP THIS EMPTY: "), + QLineEdit::Normal, data_file_path, &ok); - CommonUtils::WaitForOpera( - this, tr("Verifying"), [=](const OperaWaitingHd& op_hd) { - GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .VerifyFile( - data_file_path, sign_file_path, - [=](GpgError err, const DataObjectPtr& data_obj) { - // stop waiting - op_hd(); - - if (CheckGpgError(err) == GPG_ERR_USER_1 || - data_obj == nullptr || - !data_obj->Check<GpgVerifyResult>()) { - QMessageBox::critical(this, tr("Error"), - tr("Unknown error occurred")); - return; - } - - auto result = ExtractParams<GpgVerifyResult>(data_obj, 0); - auto result_analyse = GpgVerifyResultAnalyse( - m_key_list_->GetCurrentGpgContextChannel(), err, result); - result_analyse.Analyse(); - - slot_result_analyse_show_helper(result_analyse); - - if (!result_analyse.GetUnknownSignatures().isEmpty() && - Module::IsModuleActivate(kKeyServerSyncModuleID)) { - slot_verifying_unknown_signature_helper(result_analyse); - } - - this->slot_refresh_current_file_view(); - }); - }); -} + if (!ok) return; -void MainWindow::SlotFileEncryptSign(const QString& path) { - auto check_result = TargetFilePreCheck(path, true); - if (!std::get<0>(check_result)) { - QMessageBox::critical(this, tr("Error"), - tr("Cannot read from file: %1").arg(path)); - return; + data_file_path = text.isEmpty() ? data_file_path : text; + data_file_info = QFileInfo(data_file_path); + } + + contexts->GetContextPath(0).append(sign_file_path); + contexts->GetContextOutPath(0).append(data_file_path); } - // check selected keys - auto key_ids = m_key_list_->GetChecked(); - auto p_keys = - GpgKeyGetter::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .GetKeys(key_ids); - assert(std::all_of(p_keys.begin(), p_keys.end(), - [](const auto& key) { return key.IsGood(); })); + auto f_context = contexts->GetContext(0); + if (f_context != nullptr) build_operas_file_verify(f_context); - if (p_keys.empty()) { - QMessageBox::critical( - this, tr("No Key Checked"), - tr("Please check the key in the key toolbox on the right.")); - return; + execute_operas_helper(tr("Verifying"), contexts); +} + +void MainWindow::build_operas_file_encrypt_sign( + QSharedPointer<GpgOperaContext>& context) { + assert(context->paths.size() == context->o_paths.size()); + + for (int i = 0; i < context->paths.size(); i++) { + const auto& path = context->paths[i]; + const auto& o_path = context->o_paths[i]; + + auto opera = [=, &opera_results = + context->opera_results](const OperaWaitingHd& op_hd) { + GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) + .EncryptSignFile( + context->keys, context->singer_keys, path, context->ascii, o_path, + [=, &opera_results](GpgError err, const DataObjectPtr& data_obj) { + // stop waiting + op_hd(); + + if (CheckGpgError(err) == GPG_ERR_USER_1 || + data_obj == nullptr || + !data_obj->Check<GpgEncryptResult, GpgSignResult>()) { + QMessageBox::critical(this, tr("Error"), + tr("Unknown error occurred")); + return; + } + auto encrypt_result = + ExtractParams<GpgEncryptResult>(data_obj, 0); + auto sign_result = ExtractParams<GpgSignResult>(data_obj, 1); + + auto encrypt_result_analyse = GpgEncryptResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, + encrypt_result); + encrypt_result_analyse.Analyse(); + + auto sign_result_analyse = GpgSignResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, + sign_result); + sign_result_analyse.Analyse(); + + opera_results.append( + {std::min(encrypt_result_analyse.GetStatus(), + sign_result_analyse.GetStatus()), + encrypt_result_analyse.GetResultReport() + + sign_result_analyse.GetResultReport(), + QFileInfo(path).fileName()}); + }); + }; + + context->operas.push_back(opera); } +} - // check key abilities - for (const auto& key : p_keys) { - bool const key_can_encrypt = key.IsHasActualEncryptionCapability(); - - if (!key_can_encrypt) { - QMessageBox::critical( - nullptr, tr("Invalid KeyPair"), - tr("The selected keypair cannot be used for encryption.") + - "<br/><br/>" + tr("For example the Following Key:") + " <br/>" + - key.GetUIDs()->front().GetUID()); - return; - } +void MainWindow::build_operas_directory_encrypt_sign( + QSharedPointer<GpgOperaContext>& context) { + assert(context->paths.size() == context->o_paths.size()); + + for (int i = 0; i < context->paths.size(); i++) { + const auto& path = context->paths[i]; + const auto& o_path = context->o_paths[i]; + + auto opera = [=, &opera_results = + context->opera_results](const OperaWaitingHd& op_hd) { + GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) + .EncryptSignDirectory( + context->keys, context->singer_keys, path, context->ascii, o_path, + [=, &opera_results](GpgError err, const DataObjectPtr& data_obj) { + // stop waiting + op_hd(); + + if (CheckGpgError(err) == GPG_ERR_USER_1 || + data_obj == nullptr || + !data_obj->Check<GpgEncryptResult, GpgSignResult>()) { + QMessageBox::critical(this, tr("Error"), + tr("Unknown error occurred")); + return; + } + auto encrypt_result = + ExtractParams<GpgEncryptResult>(data_obj, 0); + auto sign_result = ExtractParams<GpgSignResult>(data_obj, 1); + + auto encrypt_result_analyse = GpgEncryptResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, + encrypt_result); + encrypt_result_analyse.Analyse(); + + auto sign_result_analyse = GpgSignResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, + sign_result); + sign_result_analyse.Analyse(); + + opera_results.append( + {std::min(encrypt_result_analyse.GetStatus(), + sign_result_analyse.GetStatus()), + encrypt_result_analyse.GetResultReport() + + sign_result_analyse.GetResultReport(), + QFileInfo(path).fileName()}); + }); + }; + + context->operas.push_back(opera); } +} + +void MainWindow::SlotFileEncryptSign(const QContainer<QString>& paths) { + auto contexts = QSharedPointer<GpgOperaContexts>::create(); bool const non_ascii_at_file_operation = GlobalSettingStation::GetInstance() .GetSettings() .value("gnupg/non_ascii_at_file_operation", true) .toBool(); - auto out_path = SetExtensionOfOutputFile(path, kENCRYPT_SIGN, - !non_ascii_at_file_operation); - check_result = TargetFilePreCheck(out_path, false); - if (!std::get<0>(check_result)) { - QMessageBox::critical(this, tr("Error"), - tr("Cannot write to file: %1").arg(out_path)); - return; - } + contexts->ascii = !non_ascii_at_file_operation; - if (QFile::exists(out_path)) { - auto ret = QMessageBox::warning( - this, tr("Warning"), - tr("The target file already exists, do you need to overwrite it?"), - QMessageBox::Ok | QMessageBox::Cancel); + auto key_ids = m_key_list_->GetChecked(); - if (ret == QMessageBox::Cancel) return; - } + contexts->keys = check_keys_helper( + key_ids, + [](const GpgKey& key) { return key.IsHasActualEncryptionCapability(); }, + tr("The selected keypair cannot be used for encryption.")); + if (contexts->keys.empty()) return; auto* signers_picker = new SignersPicker(m_key_list_->GetCurrentGpgContextChannel(), this); @@ -633,350 +791,190 @@ void MainWindow::SlotFileEncryptSign(const QString& path) { if (!signers_picker->GetStatus()) return; auto signer_key_ids = signers_picker->GetCheckedSigners(); - auto p_signer_keys = + auto signer_keys = GpgKeyGetter::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) .GetKeys(signer_key_ids); - assert(std::all_of(p_signer_keys.begin(), p_signer_keys.end(), + assert(std::all_of(signer_keys.begin(), signer_keys.end(), [](const auto& key) { return key.IsGood(); })); - CommonUtils::WaitForOpera( - this, tr("Encrypting and Signing"), [=](const OperaWaitingHd& op_hd) { - GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .EncryptSignFile( - {p_keys.begin(), p_keys.end()}, - {p_signer_keys.begin(), p_signer_keys.end()}, path, - !non_ascii_at_file_operation, out_path, - [=](GpgError err, const DataObjectPtr& data_obj) { - // stop waiting - op_hd(); - - if (CheckGpgError(err) == GPG_ERR_USER_1 || - data_obj == nullptr || - !data_obj->Check<GpgEncryptResult, GpgSignResult>()) { - QMessageBox::critical(this, tr("Error"), - tr("Unknown error occurred")); - return; - } - auto encrypt_result = - ExtractParams<GpgEncryptResult>(data_obj, 0); - auto sign_result = ExtractParams<GpgSignResult>(data_obj, 1); - - auto encrypt_result_analyse = GpgEncryptResultAnalyse( - m_key_list_->GetCurrentGpgContextChannel(), err, - encrypt_result); - encrypt_result_analyse.Analyse(); - - auto sign_result_analyse = GpgSignResultAnalyse( - m_key_list_->GetCurrentGpgContextChannel(), err, - sign_result); - sign_result_analyse.Analyse(); - - slot_result_analyse_show_helper(encrypt_result_analyse, - sign_result_analyse); - - this->slot_refresh_current_file_view(); - }); - }); -} + contexts->singer_keys = signer_keys; -void MainWindow::SlotDirectoryEncryptSign(const QString& path) { - auto check_result = TargetFilePreCheck(path, true); - if (!std::get<0>(check_result)) { - QMessageBox::critical(this, tr("Error"), - tr("Cannot read from file: %1").arg(path)); - return; - } + if (!check_read_file_paths_helper(paths)) return; - // check selected keys - auto key_ids = m_key_list_->GetChecked(); - auto p_keys = - GpgKeyGetter::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .GetKeys(key_ids); - assert(std::all_of(p_keys.begin(), p_keys.end(), - [](const auto& key) { return key.IsGood(); })); - - if (p_keys.empty()) { - QMessageBox::critical( - this, tr("No Key Checked"), - tr("Please check the key in the key toolbox on the right.")); - return; - } - - // check key abilities - for (const auto& key : p_keys) { - bool const key_can_encrypt = key.IsHasActualEncryptionCapability(); - - if (!key_can_encrypt) { - QMessageBox::critical( - nullptr, tr("Invalid KeyPair"), - tr("The selected keypair cannot be used for encryption.") + - "<br/><br/>" + tr("For example the Following Key:") + " <br/>" + - key.GetUIDs()->front().GetUID()); - return; + for (const auto& path : paths) { + QFileInfo info(path); + if (info.isDir()) { + contexts->GetContextPath(1).append(path); + contexts->GetContextOutPath(1).append( + SetExtensionOfOutputFileForArchive(path, kENCRYPT, contexts->ascii)); + } else { + contexts->GetContextPath(0).append(path); + contexts->GetContextOutPath(0).append( + SetExtensionOfOutputFile(path, kENCRYPT, contexts->ascii)); } } - bool const non_ascii_at_file_operation = - GlobalSettingStation::GetInstance() - .GetSettings() - .value("gnupg/non_ascii_at_file_operation", true) - .toBool(); - auto out_path = SetExtensionOfOutputFileForArchive( - path, kENCRYPT_SIGN, !non_ascii_at_file_operation); - - check_result = TargetFilePreCheck(out_path, false); - if (!std::get<0>(check_result)) { - QMessageBox::critical(this, tr("Error"), - tr("Cannot write to file: %1").arg(out_path)); - return; - } + if (!check_write_file_paths_helper(contexts->GetAllOutPath())) return; - if (QFile::exists(out_path)) { - auto ret = QMessageBox::warning( - this, tr("Warning"), - tr("The target file already exists, do you need to overwrite it?"), - QMessageBox::Ok | QMessageBox::Cancel); + auto f_context = contexts->GetContext(0); + if (f_context != nullptr) build_operas_file_encrypt_sign(f_context); - if (ret == QMessageBox::Cancel) return; - } - - auto* signers_picker = - new SignersPicker(m_key_list_->GetCurrentGpgContextChannel(), this); - QEventLoop loop; - connect(signers_picker, &SignersPicker::finished, &loop, &QEventLoop::quit); - loop.exec(); + auto d_context = contexts->GetContext(1); + if (d_context != nullptr) build_operas_directory_encrypt_sign(d_context); - // return when canceled - if (!signers_picker->GetStatus()) return; + execute_operas_helper(tr("Encrypting and Signing"), contexts); +} - auto signer_key_ids = signers_picker->GetCheckedSigners(); - auto p_signer_keys = - GpgKeyGetter::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .GetKeys(signer_key_ids); -#ifndef NDEBUG - for (const auto& key : p_signer_keys) { - assert(key.IsGood()); +void MainWindow::build_operas_file_decrypt_verify( + QSharedPointer<GpgOperaContext>& context) { + assert(context->paths.size() == context->o_paths.size()); + + for (int i = 0; i < context->paths.size(); i++) { + const auto& path = context->paths[i]; + const auto& o_path = context->o_paths[i]; + + auto opera = [=, &opera_results = + context->opera_results](const OperaWaitingHd& op_hd) { + GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) + .DecryptVerifyFile( + path, o_path, + [=, &opera_results](GpgError err, const DataObjectPtr& data_obj) { + // stop waiting + op_hd(); + + if (CheckGpgError(err) == GPG_ERR_USER_1 || + data_obj == nullptr || + !data_obj->Check<GpgDecryptResult, GpgVerifyResult>()) { + QMessageBox::critical(this, tr("Error"), + tr("Unknown error occurred")); + return; + } + auto decrypt_result = + ExtractParams<GpgDecryptResult>(data_obj, 0); + auto verify_result = + ExtractParams<GpgVerifyResult>(data_obj, 1); + + auto decrypt_result_analyse = GpgDecryptResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, + decrypt_result); + decrypt_result_analyse.Analyse(); + + auto verify_result_analyse = GpgVerifyResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, + verify_result); + verify_result_analyse.Analyse(); + + opera_results.append( + {std::min(decrypt_result_analyse.GetStatus(), + verify_result_analyse.GetStatus()), + decrypt_result_analyse.GetResultReport() + + verify_result_analyse.GetResultReport(), + QFileInfo(path).fileName()}); + + if (!verify_result_analyse.GetUnknownSignatures().isEmpty() && + Module::IsModuleActivate(kKeyServerSyncModuleID)) { + slot_verifying_unknown_signature_helper( + verify_result_analyse); + } + }); + }; + + context->operas.push_back(opera); } -#endif - - CommonUtils::WaitForOpera( - this, tr("Archiving & Encrypting & Signing"), - [=](const OperaWaitingHd& op_hd) { - GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .EncryptSignDirectory( - {p_keys.begin(), p_keys.end()}, - {p_signer_keys.begin(), p_signer_keys.end()}, path, - !non_ascii_at_file_operation, out_path, - [=](GpgError err, const DataObjectPtr& data_obj) { - // stop waiting - op_hd(); - - if (CheckGpgError(err) == GPG_ERR_USER_1 || - data_obj == nullptr || - !data_obj->Check<GpgEncryptResult, GpgSignResult>()) { - QMessageBox::critical(this, tr("Error"), - tr("Unknown error occurred")); - return; - } - auto encrypt_result = - ExtractParams<GpgEncryptResult>(data_obj, 0); - auto sign_result = ExtractParams<GpgSignResult>(data_obj, 1); - - auto encrypt_result_analyse = GpgEncryptResultAnalyse( - m_key_list_->GetCurrentGpgContextChannel(), err, - encrypt_result); - encrypt_result_analyse.Analyse(); - - auto sign_result_analyse = GpgSignResultAnalyse( - m_key_list_->GetCurrentGpgContextChannel(), err, - sign_result); - sign_result_analyse.Analyse(); - - slot_result_analyse_show_helper(encrypt_result_analyse, - sign_result_analyse); - - this->slot_refresh_current_file_view(); - }); - }); } -void MainWindow::SlotFileDecryptVerify(const QString& path) { - auto check_result = TargetFilePreCheck(path, true); - if (!std::get<0>(check_result)) { - QMessageBox::critical(this, tr("Error"), - tr("Cannot read from file: %1").arg(path)); - return; +void MainWindow::build_operas_archive_decrypt_verify( + QSharedPointer<GpgOperaContext>& context) { + assert(context->paths.size() == context->o_paths.size()); + + for (int i = 0; i < context->paths.size(); i++) { + const auto& path = context->paths[i]; + const auto& o_path = context->o_paths[i]; + + auto opera = [=, &opera_results = + context->opera_results](const OperaWaitingHd& op_hd) { + GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) + .DecryptVerifyArchive( + path, o_path, + [=, &opera_results](GpgError err, const DataObjectPtr& data_obj) { + // stop waiting + op_hd(); + + if (CheckGpgError(err) == GPG_ERR_USER_1 || + data_obj == nullptr || + !data_obj->Check<GpgDecryptResult, GpgVerifyResult>()) { + QMessageBox::critical(this, tr("Error"), + tr("Unknown error occurred")); + return; + } + auto decrypt_result = + ExtractParams<GpgDecryptResult>(data_obj, 0); + auto verify_result = + ExtractParams<GpgVerifyResult>(data_obj, 1); + + auto decrypt_result_analyse = GpgDecryptResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, + decrypt_result); + decrypt_result_analyse.Analyse(); + + auto verify_result_analyse = GpgVerifyResultAnalyse( + m_key_list_->GetCurrentGpgContextChannel(), err, + verify_result); + verify_result_analyse.Analyse(); + + opera_results.append( + {std::min(decrypt_result_analyse.GetStatus(), + verify_result_analyse.GetStatus()), + decrypt_result_analyse.GetResultReport() + + verify_result_analyse.GetResultReport(), + QFileInfo(path).fileName()}); + + if (!verify_result_analyse.GetUnknownSignatures().isEmpty() && + Module::IsModuleActivate(kKeyServerSyncModuleID)) { + slot_verifying_unknown_signature_helper( + verify_result_analyse); + } + }); + }; + + context->operas.push_back(opera); } +} - auto out_path = SetExtensionOfOutputFile(path, kDECRYPT_VERIFY, true); - check_result = TargetFilePreCheck(out_path, false); - if (!std::get<0>(check_result)) { - QMessageBox::critical(this, tr("Error"), - tr("Cannot write to file: %1").arg(out_path)); - return; - } +void MainWindow::SlotFileDecryptVerify(const QContainer<QString>& paths) { + auto contexts = QSharedPointer<GpgOperaContexts>::create(); - if (QFile::exists(out_path)) { - auto ret = QMessageBox::warning(this, tr("Warning"), - tr("The output file %1 already exists, do " - "you need to overwrite it?") - .arg(out_path), - QMessageBox::Ok | QMessageBox::Cancel); + contexts->ascii = true; - if (ret == QMessageBox::Cancel) return; - } + if (!check_read_file_paths_helper(paths)) return; - CommonUtils::WaitForOpera( - this, tr("Decrypting and Verifying"), [=](const OperaWaitingHd& op_hd) { - GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .DecryptVerifyFile( - path, out_path, - [=](GpgError err, const DataObjectPtr& data_obj) { - // stop waiting - op_hd(); - - if (CheckGpgError(err) == GPG_ERR_USER_1 || - data_obj == nullptr || - !data_obj->Check<GpgDecryptResult, GpgVerifyResult>()) { - QMessageBox::critical(this, tr("Error"), - tr("Unknown error occurred")); - return; - } - auto decrypt_result = - ExtractParams<GpgDecryptResult>(data_obj, 0); - auto verify_result = - ExtractParams<GpgVerifyResult>(data_obj, 1); - - auto decrypt_result_analyse = GpgDecryptResultAnalyse( - m_key_list_->GetCurrentGpgContextChannel(), err, - decrypt_result); - decrypt_result_analyse.Analyse(); - - auto verify_result_analyse = GpgVerifyResultAnalyse( - m_key_list_->GetCurrentGpgContextChannel(), err, - verify_result); - verify_result_analyse.Analyse(); - - slot_result_analyse_show_helper(decrypt_result_analyse, - verify_result_analyse); - - this->slot_refresh_current_file_view(); - - if (!verify_result_analyse.GetUnknownSignatures().isEmpty() && - Module::IsModuleActivate(kKeyServerSyncModuleID)) { - LOG_D() << "try to sync missing key info from server" - << verify_result_analyse.GetUnknownSignatures(); - - QString fingerprint_list; - for (const auto& fingerprint : - verify_result_analyse.GetUnknownSignatures()) { - fingerprint_list += fingerprint + "\n"; - } - - // Interaction with user - auto user_response = QMessageBox::question( - this, tr("Missing Keys"), - tr("Some signatures cannot be verified because the " - "corresponding keys are missing.\n\n" - "The following fingerprints are missing:\n%1\n\n" - "Would you like to fetch these keys from the key " - "server?") - .arg(fingerprint_list), - QMessageBox::Yes | QMessageBox::No); - - if (user_response == QMessageBox::Yes) { - CommonUtils::GetInstance() - ->ImportKeyByKeyServerSyncModule( - this, m_key_list_->GetCurrentGpgContextChannel(), - verify_result_analyse.GetUnknownSignatures()); - } else { - QMessageBox::information( - this, tr("Verification Incomplete"), - tr("Verification was incomplete due to missing " - "keys. You can manually import the keys later.")); - } - } - }); - }); -} + for (const auto& path : paths) { + QFileInfo info(path); + const auto extension = info.completeSuffix(); -void MainWindow::SlotArchiveDecryptVerify(const QString& path) { - auto check_result = TargetFilePreCheck(path, true); - if (!std::get<0>(check_result)) { - QMessageBox::critical(this, tr("Error"), - tr("Cannot read from file: %1").arg(path)); - return; + if (extension == "tar.gpg" || extension == "tar.asc") { + contexts->GetContextPath(1).append(path); + contexts->GetContextOutPath(1).append( + SetExtensionOfOutputFileForArchive(path, kDECRYPT, contexts->ascii)); + } else { + contexts->GetContextPath(0).append(path); + contexts->GetContextOutPath(0).append( + SetExtensionOfOutputFile(path, kDECRYPT, contexts->ascii)); + } } - auto out_path = - SetExtensionOfOutputFileForArchive(path, kDECRYPT_VERIFY, true); - check_result = TargetFilePreCheck(out_path, false); - if (!std::get<0>(check_result)) { - QMessageBox::critical(this, tr("Error"), - tr("Cannot write to file: %1").arg(out_path)); - return; - } + if (!check_write_file_paths_helper(contexts->GetAllOutPath())) return; - if (QFile::exists(out_path)) { - auto ret = QMessageBox::warning(this, tr("Warning"), - tr("The output file %1 already exists, do " - "you need to overwrite it?") - .arg(out_path), - QMessageBox::Ok | QMessageBox::Cancel); + auto f_context = contexts->GetContext(0); + if (f_context != nullptr) build_operas_file_decrypt_verify(f_context); - if (ret == QMessageBox::Cancel) return; + auto d_context = contexts->GetContext(1); + if (d_context != nullptr) { + build_operas_archive_decrypt_verify(d_context); } - CommonUtils::WaitForOpera( - this, tr("Decrypting & Verifying & Extracting"), - [=](const OperaWaitingHd& op_hd) { - GpgFileOpera::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .DecryptVerifyArchive( - path, out_path, - [=](GpgError err, const DataObjectPtr& data_obj) { - // stop waiting - op_hd(); - - if (CheckGpgError(err) == GPG_ERR_USER_1 || - data_obj == nullptr || - !data_obj->Check<GpgDecryptResult, GpgVerifyResult>()) { - QMessageBox::critical(this, tr("Error"), - tr("Unknown error occurred")); - return; - } - auto decrypt_result = - ExtractParams<GpgDecryptResult>(data_obj, 0); - auto verify_result = - ExtractParams<GpgVerifyResult>(data_obj, 1); - - auto decrypt_result_analyse = GpgDecryptResultAnalyse( - m_key_list_->GetCurrentGpgContextChannel(), err, - decrypt_result); - decrypt_result_analyse.Analyse(); - - auto verify_result_analyse = GpgVerifyResultAnalyse( - m_key_list_->GetCurrentGpgContextChannel(), err, - verify_result); - verify_result_analyse.Analyse(); - - slot_result_analyse_show_helper(decrypt_result_analyse, - verify_result_analyse); - - // pause this feature - // if (verify_result_analyse.GetStatus() == -2) { - // import_unknown_key_from_keyserver(this, - // verify_result_analyse); - // } - // pause this feature - // if (verify_result_analyse.GetStatus() >= 0) { - // show_verify_details(this, info_board_, err, - // verify_result); - // } - - this->slot_refresh_current_file_view(); - }); - }); -} + execute_operas_helper(tr("Decrypting and Verifying"), contexts); +}; void MainWindow::SlotFileVerifyEML(const QString& path) { auto check_result = TargetFilePreCheck(path, true); |