diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/MainWindow.cpp | 4 | ||||
-rw-r--r-- | src/gpg/GpgFileOpera.cpp | 237 | ||||
-rw-r--r-- | src/gpg/result_analyse/VerifyResultAnalyse.cpp | 2 | ||||
-rw-r--r-- | src/ui/main_window/MainWindowSlotFunction.cpp | 796 | ||||
-rw-r--r-- | src/ui/main_window/MainWindowSlotUI.cpp | 10 | ||||
-rw-r--r-- | src/ui/main_window/MainWindowUI.cpp | 12 | ||||
-rw-r--r-- | src/ui/widgets/EditorPage.cpp | 12 | ||||
-rw-r--r-- | src/ui/widgets/FilePage.cpp | 150 | ||||
-rw-r--r-- | src/ui/widgets/InfoBoardWidget.cpp | 35 | ||||
-rw-r--r-- | src/ui/widgets/TextEdit.cpp | 170 |
10 files changed, 1154 insertions, 274 deletions
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 67274a65..0d8521e7 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -34,7 +34,9 @@ MainWindow::MainWindow() setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); - edit = new TextEdit(); + qDebug() << "Main Window" << this; + + edit = new TextEdit(this); setCentralWidget(edit); /* the list of Keys available*/ diff --git a/src/gpg/GpgFileOpera.cpp b/src/gpg/GpgFileOpera.cpp new file mode 100644 index 00000000..f7db9d44 --- /dev/null +++ b/src/gpg/GpgFileOpera.cpp @@ -0,0 +1,237 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ +#include "gpg/GpgFileOpera.h" + +gpgme_error_t GpgFileOpera::encryptFile(GpgME::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath, + gpgme_encrypt_result_t *result) { + + QFileInfo fileInfo(mPath); + + if (!fileInfo.isFile() || !fileInfo.isReadable()) + throw std::runtime_error("no permission"); + + QFile infile; + infile.setFileName(mPath); + if (!infile.open(QIODevice::ReadOnly)) + throw std::runtime_error("cannot open file"); + + QByteArray inBuffer = infile.readAll(); + auto outBuffer = QByteArray(); + infile.close(); + + auto error = ctx->encrypt(keys, inBuffer, &outBuffer, result); + + if (gpg_err_code(error) != GPG_ERR_NO_ERROR) return error; + + QFile outfile(mPath + ".asc"); + + if (!outfile.open(QFile::WriteOnly)) + throw std::runtime_error("cannot open file"); + + QDataStream out(&outfile); + out.writeRawData(outBuffer.data(), outBuffer.length()); + outfile.close(); + return error; +} + +gpgme_error_t GpgFileOpera::decryptFile(GpgME::GpgContext *ctx, const QString &mPath, gpgme_decrypt_result_t *result) { + + QFileInfo fileInfo(mPath); + + if (!fileInfo.isFile() || !fileInfo.isReadable()) + throw std::runtime_error("no permission"); + + QFile infile; + infile.setFileName(mPath); + if (!infile.open(QIODevice::ReadOnly)) + throw std::runtime_error("cannot open file"); + + QByteArray inBuffer = infile.readAll(); + auto outBuffer = QByteArray(); + infile.close(); + + auto error = ctx->decrypt(inBuffer, &outBuffer, result); + + if (gpgme_err_code(error) != GPG_ERR_NO_ERROR) return error; + + QString outFileName, fileExtension = fileInfo.suffix(); + + if (fileExtension == "asc" || fileExtension == "gpg") { + int pos = mPath.lastIndexOf(QChar('.')); + outFileName = mPath.left(pos); + } else { + outFileName = mPath + ".out"; + } + + QFile outfile(outFileName); + + if (!outfile.open(QFile::WriteOnly)) + throw std::runtime_error("cannot open file"); + + QDataStream out(&outfile); + out.writeRawData(outBuffer.data(), outBuffer.length()); + outfile.close(); + + return error; +} + +gpgme_error_t GpgFileOpera::signFile(GpgME::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath, + gpgme_sign_result_t *result) { + + QFileInfo fileInfo(mPath); + + if (!fileInfo.isFile() || !fileInfo.isReadable()) + throw std::runtime_error("no permission"); + + QFile infile; + infile.setFileName(mPath); + if (!infile.open(QIODevice::ReadOnly)) + throw std::runtime_error("cannot open file"); + + + QByteArray inBuffer = infile.readAll(); + auto outBuffer = QByteArray(); + infile.close(); + + auto error = ctx->sign(keys, inBuffer, &outBuffer, true, result); + + if (gpg_err_code(error) != GPG_ERR_NO_ERROR) return error; + + QFile outfile(mPath + ".sig"); + + if (!outfile.open(QFile::WriteOnly)) + throw std::runtime_error("cannot open file"); + + QDataStream out(&outfile); + out.writeRawData(outBuffer.data(), outBuffer.length()); + outfile.close(); + + return error; +} + +gpgme_error_t GpgFileOpera::verifyFile(GpgME::GpgContext *ctx, const QString &mPath, gpgme_verify_result_t *result) { + + QFileInfo fileInfo(mPath); + + if (!fileInfo.isFile() || !fileInfo.isReadable()) + throw std::runtime_error("no permission"); + + QFile infile; + infile.setFileName(mPath); + if (!infile.open(QIODevice::ReadOnly)) + throw std::runtime_error("cannot open file"); + + + QByteArray inBuffer = infile.readAll(); + + QFile signFile; + signFile.setFileName(mPath + ".sig"); + if (!signFile.open(QIODevice::ReadOnly)) { + throw std::runtime_error("cannot open file"); + } + + + + auto signBuffer = signFile.readAll(); + infile.close(); + + + auto error = ctx->verify(&inBuffer, &signBuffer, result); + + return error; +} + +gpg_error_t GpgFileOpera::encryptSignFile(GpgME::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath, + gpgme_encrypt_result_t *encr_res, + gpgme_sign_result_t *sign_res) { + QFileInfo fileInfo(mPath); + + if (!fileInfo.isFile() || !fileInfo.isReadable()) + throw std::runtime_error("no permission"); + + QFile infile; + infile.setFileName(mPath); + if (!infile.open(QIODevice::ReadOnly)) + throw std::runtime_error("cannot open file"); + + QByteArray inBuffer = infile.readAll(); + auto outBuffer = QByteArray(); + infile.close(); + + auto error = ctx->encryptSign(keys, inBuffer, &outBuffer, encr_res, sign_res); + + if (gpg_err_code(error) != GPG_ERR_NO_ERROR) + return error; + + QFile outfile(mPath + ".gpg"); + + if (!outfile.open(QFile::WriteOnly)) + throw std::runtime_error("cannot open file"); + + QDataStream out(&outfile); + out.writeRawData(outBuffer.data(), outBuffer.length()); + outfile.close(); + + return error; +} + +gpg_error_t GpgFileOpera::decryptVerifyFile(GpgME::GpgContext *ctx, const QString &mPath, gpgme_decrypt_result_t *decr_res, + gpgme_verify_result_t *verify_res) { + QFileInfo fileInfo(mPath); + + if (!fileInfo.isFile() || !fileInfo.isReadable()) + throw std::runtime_error("no permission"); + + QFile infile; + infile.setFileName(mPath); + if (!infile.open(QIODevice::ReadOnly)) + throw std::runtime_error("cannot open file"); + + QByteArray inBuffer = infile.readAll(); + auto outBuffer = QByteArray(); + infile.close(); + + auto error = ctx->decryptVerify(inBuffer, &outBuffer, decr_res, verify_res); + if (gpg_err_code(error) != GPG_ERR_NO_ERROR) return error; + + QString outFileName, fileExtension = fileInfo.suffix(); + + if (fileExtension == "asc" || fileExtension == "gpg") { + int pos = mPath.lastIndexOf(QChar('.')); + outFileName = mPath.left(pos); + } else { + outFileName = mPath + ".out"; + } + + QFile outfile(outFileName); + + if (!outfile.open(QFile::WriteOnly)) + throw std::runtime_error("cannot open file"); + + QDataStream out(&outfile); + out.writeRawData(outBuffer.data(), outBuffer.length()); + outfile.close(); + + return error; +} diff --git a/src/gpg/result_analyse/VerifyResultAnalyse.cpp b/src/gpg/result_analyse/VerifyResultAnalyse.cpp index 79442c9a..59c7e3ef 100644 --- a/src/gpg/result_analyse/VerifyResultAnalyse.cpp +++ b/src/gpg/result_analyse/VerifyResultAnalyse.cpp @@ -17,7 +17,7 @@ VerifyResultAnalyse::VerifyResultAnalyse(GpgME::GpgContext *ctx, gpgme_error_t e if (sign == nullptr) { stream << "> Not Signature Found" << Qt::endl; - setStatus(-1); + setStatus(0); return; } diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp index 60c33d83..106c3cd1 100644 --- a/src/ui/main_window/MainWindowSlotFunction.cpp +++ b/src/ui/main_window/MainWindowSlotFunction.cpp @@ -25,124 +25,135 @@ #include "MainWindow.h" void MainWindow::slotEncrypt() { - if (edit->tabCount() == 0 || edit->slotCurPage() == nullptr) { - return; - } - QVector<GpgKey> keys; - mKeyList->getCheckedKeys(keys); + if (edit->tabCount() == 0) return; - if (keys.count() == 0) { - QMessageBox::critical(nullptr, tr("No Key Selected"), tr("No Key Selected")); - return; - } + if (edit->slotCurPageTextEdit() != nullptr) { - for (const auto &key : keys) { - if (!GpgME::GpgContext::checkIfKeyCanEncr(key)) { - QMessageBox::information(nullptr, - tr("Invalid Operation"), - tr("The selected key contains a key that does not actually have a encrypt function.<br/>") - + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid); + QVector<GpgKey> keys; + mKeyList->getCheckedKeys(keys); + + if (keys.count() == 0) { + QMessageBox::critical(nullptr, tr("No Key Selected"), tr("No Key Selected")); return; + } + + for (const auto &key : keys) { + if (!GpgME::GpgContext::checkIfKeyCanEncr(key)) { + QMessageBox::information(nullptr, + tr("Invalid Operation"), + tr("The selected key contains a key that does not actually have a encrypt usage.<br/>") + + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid); + return; + } } - } - auto *tmp = new QByteArray(); + auto *tmp = new QByteArray(); - gpgme_encrypt_result_t result = nullptr; - auto error = mCtx->encrypt(keys, edit->curTextPage()->toPlainText().toUtf8(), tmp, &result); + gpgme_encrypt_result_t result = nullptr; + auto error = mCtx->encrypt(keys, edit->curTextPage()->toPlainText().toUtf8(), tmp, &result); - auto resultAnalyse = new EncryptResultAnalyse(error, result); - auto &reportText = resultAnalyse->getResultReport(); + auto resultAnalyse = new EncryptResultAnalyse(error, result); + auto &reportText = resultAnalyse->getResultReport(); - auto *tmp2 = new QString(*tmp); - edit->slotFillTextEditWithText(*tmp2); - infoBoard->associateTextEdit(edit->curTextPage()); + auto *tmp2 = new QString(*tmp); + edit->slotFillTextEditWithText(*tmp2); + infoBoard->associateTextEdit(edit->curTextPage()); - if (resultAnalyse->getStatus() < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (resultAnalyse->getStatus() > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + if (resultAnalyse->getStatus() < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (resultAnalyse->getStatus() > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); - delete resultAnalyse; + delete resultAnalyse; + } else if (edit->slotCurPageFileTreeView() != nullptr) { + this->slotFileEncrypt(); + } } void MainWindow::slotSign() { - if (edit->tabCount() == 0 || edit->slotCurPage() == nullptr) { - return; - } - QVector<GpgKey> keys; + if (edit->tabCount() == 0) return; - mKeyList->getPrivateCheckedKeys(keys); + if (edit->slotCurPageTextEdit() != nullptr) { - if (keys.isEmpty()) { - QMessageBox::critical(nullptr, tr("No Key Selected"), tr("No Key Selected")); - return; - } + QVector<GpgKey> keys; - for (const auto &key : keys) { - if (!GpgME::GpgContext::checkIfKeyCanSign(key)) { - QMessageBox::information(nullptr, - tr("Invalid Operation"), - tr("The selected key contains a key that does not actually have a signature function.<br/>") - + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid); + mKeyList->getPrivateCheckedKeys(keys); + + if (keys.isEmpty()) { + QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected")); return; } - } - auto *tmp = new QByteArray(); + for (const auto &key : keys) { + if (!GpgME::GpgContext::checkIfKeyCanSign(key)) { + QMessageBox::information(this, + tr("Invalid Operation"), + tr("The selected key contains a key that does not actually have a signature usage.<br/>") + + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid); + return; + } + } - gpgme_sign_result_t result = nullptr; + auto *tmp = new QByteArray(); - auto error = mCtx->sign(keys, edit->curTextPage()->toPlainText().toUtf8(), tmp, false, &result); - infoBoard->associateTextEdit(edit->curTextPage()); - edit->slotFillTextEditWithText(QString::fromUtf8(*tmp)); + gpgme_sign_result_t result = nullptr; - auto resultAnalyse = new SignResultAnalyse(error, result); + auto error = mCtx->sign(keys, edit->curTextPage()->toPlainText().toUtf8(), tmp, false, &result); + infoBoard->associateTextEdit(edit->curTextPage()); + edit->slotFillTextEditWithText(QString::fromUtf8(*tmp)); - auto &reportText = resultAnalyse->getResultReport(); - if (resultAnalyse->getStatus() < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (resultAnalyse->getStatus() > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + auto resultAnalyse = new SignResultAnalyse(error, result); + + auto &reportText = resultAnalyse->getResultReport(); + if (resultAnalyse->getStatus() < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (resultAnalyse->getStatus() > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); - delete resultAnalyse; + delete resultAnalyse; + } else if (edit->slotCurPageFileTreeView() != nullptr) { + this->slotFileSign(); + } } void MainWindow::slotDecrypt() { - if (edit->tabCount() == 0 || edit->slotCurPage() == nullptr) { - return; - } + if (edit->tabCount() == 0) return; - auto *decrypted = new QByteArray(); - QByteArray text = edit->curTextPage()->toPlainText().toUtf8(); - GpgME::GpgContext::preventNoDataErr(&text); + if (edit->slotCurPageTextEdit() != nullptr) { - gpgme_decrypt_result_t result = nullptr; - // try decrypt, if fail do nothing, especially don't replace text - auto error = mCtx->decrypt(text, decrypted, &result); - infoBoard->associateTextEdit(edit->curTextPage()); + auto *decrypted = new QByteArray(); + QByteArray text = edit->curTextPage()->toPlainText().toUtf8(); + GpgME::GpgContext::preventNoDataErr(&text); - if(gpgme_err_code(error) == GPG_ERR_NO_ERROR) - edit->slotFillTextEditWithText(QString::fromUtf8(*decrypted)); + gpgme_decrypt_result_t result = nullptr; + // try decrypt, if fail do nothing, especially don't replace text + auto error = mCtx->decrypt(text, decrypted, &result); + infoBoard->associateTextEdit(edit->curTextPage()); - auto resultAnalyse = new DecryptResultAnalyse(mCtx, error, result); + if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) + edit->slotFillTextEditWithText(QString::fromUtf8(*decrypted)); - auto &reportText = resultAnalyse->getResultReport(); - if (resultAnalyse->getStatus() < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (resultAnalyse->getStatus() > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + auto resultAnalyse = new DecryptResultAnalyse(mCtx, error, result); - delete resultAnalyse; + auto &reportText = resultAnalyse->getResultReport(); + if (resultAnalyse->getStatus() < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (resultAnalyse->getStatus() > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + + delete resultAnalyse; + } else if (edit->slotCurPageFileTreeView() != nullptr) { + this->slotFileDecrypt(); + } } void MainWindow::slotFind() { @@ -151,54 +162,151 @@ void MainWindow::slotFind() { } // At first close verifynotification, if existing - edit->slotCurPage()->closeNoteByClass("findwidget"); + edit->slotCurPageTextEdit()->closeNoteByClass("findwidget"); auto *fw = new FindWidget(this, edit->curTextPage()); - edit->slotCurPage()->showNotificationWidget(fw, "findWidget"); + edit->slotCurPageTextEdit()->showNotificationWidget(fw, "findWidget"); } void MainWindow::slotVerify() { - if (edit->tabCount() == 0 || edit->slotCurPage() == nullptr) { - return; + + if (edit->tabCount() == 0) return; + + if (edit->slotCurPageTextEdit() != nullptr) { + + QByteArray text = edit->curTextPage()->toPlainText().toUtf8(); + GpgME::GpgContext::preventNoDataErr(&text); + + + gpgme_verify_result_t result; + + auto error = mCtx->verify(&text, nullptr, &result); + + auto resultAnalyse = new VerifyResultAnalyse(mCtx, error, result); + infoBoard->associateTextEdit(edit->curTextPage()); + + auto &reportText = resultAnalyse->getResultReport(); + if (resultAnalyse->getStatus() < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (resultAnalyse->getStatus() > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + + if (resultAnalyse->getStatus() >= 0) { + infoBoard->resetOptionActionsMenu(); + infoBoard->addOptionalAction("Show Verify Details", [this, error, result]() { + VerifyDetailsDialog(this, mCtx, mKeyList, error, result); + }); + } + delete resultAnalyse; + } else if (edit->slotCurPageFileTreeView() != nullptr) { + this->slotFileVerify(); } +} + +void MainWindow::slotEncryptSign() { - // If an unknown key is found, enable the importfromkeyserveraction - QByteArray text = edit->curTextPage()->toPlainText().toUtf8(); - GpgME::GpgContext::preventNoDataErr(&text); + if (edit->tabCount() == 0) return; + + if (edit->slotCurPageTextEdit() != nullptr) { + + QVector<GpgKey> keys; + mKeyList->getCheckedKeys(keys); + if (keys.empty()) { + QMessageBox::critical(nullptr, tr("No Key Selected"), tr("No Key Selected")); + return; + } + + for (const auto &key : keys) { + if (!GpgME::GpgContext::checkIfKeyCanSign(key) || !GpgME::GpgContext::checkIfKeyCanEncr(key)) { + QMessageBox::information(nullptr, + tr("Invalid Operation"), + tr("The selected key cannot be used for signing and encryption at the same time.<br/>") + + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid); + return; + } + } + + auto *tmp = new QByteArray(); + gpgme_encrypt_result_t encr_result = nullptr; + gpgme_sign_result_t sign_result = nullptr; + + auto error = mCtx->encryptSign(keys, edit->curTextPage()->toPlainText().toUtf8(), tmp, &encr_result, + &sign_result); + auto *tmp2 = new QString(*tmp); + edit->slotFillTextEditWithText(*tmp2); + + auto resultAnalyseEncr = new EncryptResultAnalyse(error, encr_result); + auto resultAnalyseSign = new SignResultAnalyse(error, sign_result); + int status = std::min(resultAnalyseEncr->getStatus(), resultAnalyseSign->getStatus()); + auto reportText = resultAnalyseEncr->getResultReport() + resultAnalyseSign->getResultReport(); + + infoBoard->associateTextEdit(edit->curTextPage()); + + if (status < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (status > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + + delete resultAnalyseEncr; + delete resultAnalyseSign; + } else if (edit->slotCurPageFileTreeView() != nullptr) { + this->slotFileVerify(); + } +} + +void MainWindow::slotDecryptVerify() { - gpgme_verify_result_t result; + if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { + return; + } - auto error = mCtx->verify(&text, nullptr, &result); + auto *decrypted = new QByteArray(); + QByteArray text = edit->curTextPage()->toPlainText().toUtf8(); + GpgME::GpgContext::preventNoDataErr(&text); - auto resultAnalyse = new VerifyResultAnalyse(mCtx, error, result); + gpgme_decrypt_result_t d_result = nullptr; + gpgme_verify_result_t v_result = nullptr; + // try decrypt, if fail do nothing, especially don't replace text + auto error = mCtx->decryptVerify(text, decrypted, &d_result, &v_result); infoBoard->associateTextEdit(edit->curTextPage()); - auto &reportText = resultAnalyse->getResultReport(); - if (resultAnalyse->getStatus() < 0) + if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) + edit->slotFillTextEditWithText(QString::fromUtf8(*decrypted)); + + auto resultAnalyseDecrypt = new DecryptResultAnalyse(mCtx, error, d_result); + auto resultAnalyseVerify = new VerifyResultAnalyse(mCtx, error, v_result); + + int status = std::min(resultAnalyseDecrypt->getStatus(), resultAnalyseVerify->getStatus()); + auto &reportText = resultAnalyseDecrypt->getResultReport() + resultAnalyseVerify->getResultReport(); + if (status < 0) infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (resultAnalyse->getStatus() > 0) + else if (status > 0) infoBoard->slotRefresh(reportText, INFO_ERROR_OK); else infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); - if (resultAnalyse->getStatus() >= 0) { + if (resultAnalyseVerify->getStatus() >= 0) { infoBoard->resetOptionActionsMenu(); - infoBoard->addOptionalAction("Show Verify Details", [this, error, result]() { - VerifyDetailsDialog(this, mCtx, mKeyList, error, result); + infoBoard->addOptionalAction("Show Verify Details", [this, error, v_result]() { + VerifyDetailsDialog(this, mCtx, mKeyList, error, v_result); }); } - - delete resultAnalyse; + delete resultAnalyseDecrypt; + delete resultAnalyseVerify; } /* * Append the selected (not checked!) Key(s) To Textedit */ void MainWindow::slotAppendSelectedKeys() { - if (edit->tabCount() == 0 || edit->slotCurPage() == nullptr) { + if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { return; } @@ -245,116 +353,470 @@ void MainWindow::uploadKeyToServer() { } void MainWindow::slotFileEncrypt() { - QStringList *keyList; - keyList = mKeyList->getChecked(); - new FileEncryptionDialog(mCtx, *keyList, FileEncryptionDialog::Encrypt, this); + + auto fileTreeView = edit->slotCurPageFileTreeView(); + auto path = fileTreeView->getSelected(); + + QFileInfo fileInfo(path); + QFileInfo pathInfo(fileInfo.absolutePath()); + + if (!fileInfo.isFile()) { + QMessageBox::critical(this, tr("Error"), tr("Select a file before doing it.")); + return; + } + if (!fileInfo.isReadable()) { + QMessageBox::critical(this, tr("Error"), tr("No permission to read this file.")); + return; + } + if (!pathInfo.isWritable()) { + QMessageBox::critical(this, tr("Error"), tr("No permission to create file.")); + return; + } + if (QFile::exists(path + ".asc")) { + 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; + } + + QVector<GpgKey> keys; + + mKeyList->getCheckedKeys(keys); + + if (keys.empty()) { + QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected")); + return; + } + + for (const auto &key : keys) { + if (!GpgME::GpgContext::checkIfKeyCanEncr(key)) { + QMessageBox::information(this, + tr("Invalid Operation"), + tr("The selected key contains a key that does not actually have a encrypt usage.<br/>") + + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid); + return; + + } + } + + try { + gpgme_encrypt_result_t result; + auto error = GpgFileOpera::encryptFile(mCtx, keys, path, &result); + + auto resultAnalyse = new EncryptResultAnalyse(error, result); + auto &reportText = resultAnalyse->getResultReport(); + infoBoard->associateTabWidget(edit->tabWidget); + infoBoard->associateFileTreeView(edit->curFilePage()); + + if (resultAnalyse->getStatus() < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (resultAnalyse->getStatus() > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + + delete resultAnalyse; + + fileTreeView->update(); + + } catch (std::runtime_error &e) { + QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation.")); + } + } void MainWindow::slotFileDecrypt() { - QStringList *keyList; - keyList = mKeyList->getChecked(); - new FileEncryptionDialog(mCtx, *keyList, FileEncryptionDialog::Decrypt, this); + + auto fileTreeView = edit->slotCurPageFileTreeView(); + auto path = fileTreeView->getSelected(); + + QFileInfo fileInfo(path); + QFileInfo pathInfo(fileInfo.absolutePath()); + if (!fileInfo.isFile()) { + QMessageBox::critical(this, tr("Error"), tr("Select a file before doing it.")); + return; + } + if (!fileInfo.isReadable()) { + QMessageBox::critical(this, tr("Error"), tr("No permission to read this file.")); + return; + } + if (!pathInfo.isWritable()) { + QMessageBox::critical(this, tr("Error"), tr("No permission to create file.")); + return; + } + + QString outFileName, fileExtension = fileInfo.suffix(); + + if (fileExtension == "asc" || fileExtension == "gpg") { + int pos = path.lastIndexOf(QChar('.')); + outFileName = path.left(pos); + } else { + outFileName = path + ".out"; + } + + if (QFile::exists(outFileName)) { + 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; + } + + try { + gpgme_decrypt_result_t result; + auto error = GpgFileOpera::decryptFile(mCtx, path, &result); + + auto resultAnalyse = new DecryptResultAnalyse(mCtx, error, result); + auto &reportText = resultAnalyse->getResultReport(); + infoBoard->associateTabWidget(edit->tabWidget); + infoBoard->associateFileTreeView(edit->curFilePage()); + + if (resultAnalyse->getStatus() < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (resultAnalyse->getStatus() > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + + delete resultAnalyse; + + fileTreeView->update(); + } catch (std::runtime_error &e) { + QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation.")); + return; + } + + } void MainWindow::slotFileSign() { - QStringList *keyList; - keyList = mKeyList->getChecked(); - new FileEncryptionDialog(mCtx, *keyList, FileEncryptionDialog::Sign, this); + + auto fileTreeView = edit->slotCurPageFileTreeView(); + auto path = fileTreeView->getSelected(); + + QFileInfo fileInfo(path); + QFileInfo pathInfo(fileInfo.absolutePath()); + + if (!fileInfo.isFile()) { + QMessageBox::critical(this, tr("Error"), tr("Select a file before doing it.")); + return; + } + if (!fileInfo.isReadable()) { + QMessageBox::critical(this, tr("Error"), tr("No permission to read this file.")); + return; + } + if (!pathInfo.isWritable()) { + QMessageBox::critical(this, tr("Error"), tr("No permission to create file.")); + return; + } + + if (QFile::exists(path + ".sig")) { + 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; + } + + QVector<GpgKey> keys; + + mKeyList->getCheckedKeys(keys); + + if (keys.empty()) { + QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected")); + return; + } + + for (const auto &key : keys) { + if (!GpgME::GpgContext::checkIfKeyCanEncr(key)) { + QMessageBox::information(this, + tr("Invalid Operation"), + tr("The selected key contains a key that does not actually have a encrypt usage.<br/>") + + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid); + return; + + } + } + + try { + gpgme_sign_result_t result; + auto error = GpgFileOpera::signFile(mCtx, keys, path, &result); + + auto resultAnalyse = new SignResultAnalyse(error, result); + auto &reportText = resultAnalyse->getResultReport(); + infoBoard->associateTabWidget(edit->tabWidget); + infoBoard->associateFileTreeView(edit->curFilePage()); + + if (resultAnalyse->getStatus() < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (resultAnalyse->getStatus() > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + + delete resultAnalyse; + + fileTreeView->update(); + + } catch (std::runtime_error &e) { + QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation.")); + } + + fileTreeView->update(); + } void MainWindow::slotFileVerify() { - QStringList *keyList; - keyList = mKeyList->getChecked(); - new FileEncryptionDialog(mCtx, *keyList, FileEncryptionDialog::Verify, this); + + auto fileTreeView = edit->slotCurPageFileTreeView(); + auto path = fileTreeView->getSelected(); + + QFileInfo fileInfo(path); + + QString signFilePath, dataFilePath; + + if (fileInfo.suffix() == "sig" || fileInfo.suffix() == "gpg") { + int pos = path.lastIndexOf(QChar('.')); + dataFilePath = path.left(pos); + signFilePath = path; + } else { + dataFilePath = path; + signFilePath = path + ".sig"; + } + + QFileInfo dataFileInfo(dataFilePath), signFileInfo(signFilePath); + + if (!dataFileInfo.isFile() || !signFileInfo.isFile()) { + QMessageBox::critical(this, tr("Error"), + tr("Please select the appropriate target file or signature file. Ensure that both are in this directory.")); + return; + } + if (!dataFileInfo.isReadable()) { + QMessageBox::critical(this, tr("Error"), tr("No permission to read target file.")); + return; + } + if (!fileInfo.isReadable()) { + QMessageBox::critical(this, tr("Error"), tr("No permission to read signature file.")); + return; + } + + try { + gpgme_verify_result_t result; + auto error = GpgFileOpera::verifyFile(mCtx, dataFilePath, &result); + + auto resultAnalyse = new VerifyResultAnalyse(mCtx, error, result); + auto &reportText = resultAnalyse->getResultReport(); + infoBoard->associateTabWidget(edit->tabWidget); + infoBoard->associateFileTreeView(edit->curFilePage()); + + if (resultAnalyse->getStatus() < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (resultAnalyse->getStatus() > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + + if (resultAnalyse->getStatus() >= 0) { + infoBoard->resetOptionActionsMenu(); + infoBoard->addOptionalAction("Show Verify Details", [this, error, result]() { + VerifyDetailsDialog(this, mCtx, mKeyList, error, result); + }); + } + + delete resultAnalyse; + + fileTreeView->update(); + } catch (std::runtime_error &e) { + QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation.")); + return; + } } -void MainWindow::slotEncryptSign() { +void MainWindow::slotFileEncryptSign() { + auto fileTreeView = edit->slotCurPageFileTreeView(); + auto path = fileTreeView->getSelected(); - if (edit->tabCount() == 0 || edit->slotCurPage() == nullptr) { + QFileInfo fileInfo(path); + QFileInfo pathInfo(fileInfo.absolutePath()); + + if (!fileInfo.isFile()) { + QMessageBox::critical(this, tr("Error"), tr("Select a file before doing it.")); return; } + if (!fileInfo.isReadable()) { + QMessageBox::critical(this, tr("Error"), tr("No permission to read this file.")); + return; + } + if (!pathInfo.isWritable()) { + QMessageBox::critical(this, tr("Error"), tr("No permission to create file.")); + return; + } + if (QFile::exists(path + ".asc")) { + 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; + } QVector<GpgKey> keys; + mKeyList->getCheckedKeys(keys); if (keys.empty()) { - QMessageBox::critical(nullptr, tr("No Key Selected"), tr("No Key Selected")); + QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected")); return; } for (const auto &key : keys) { - if (!GpgME::GpgContext::checkIfKeyCanSign(key) || !GpgME::GpgContext::checkIfKeyCanEncr(key)) { - QMessageBox::information(nullptr, + if (!GpgME::GpgContext::checkIfKeyCanEncr(key)) { + QMessageBox::information(this, tr("Invalid Operation"), - tr("The selected key cannot be used for signing and encryption at the same time.<br/>") + tr("The selected key contains a key that does not actually have a encrypt usage.<br/>") + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid); return; + } } - auto *tmp = new QByteArray(); - gpgme_encrypt_result_t encr_result = nullptr; - gpgme_sign_result_t sign_result = nullptr; + try { - auto error = mCtx->encryptSign(keys, edit->curTextPage()->toPlainText().toUtf8(), tmp, &encr_result, &sign_result); - auto *tmp2 = new QString(*tmp); - edit->slotFillTextEditWithText(*tmp2); + gpgme_encrypt_result_t encr_result = nullptr; + gpgme_sign_result_t sign_result = nullptr; - auto resultAnalyseEncr = new EncryptResultAnalyse(error, encr_result); - auto resultAnalyseSign = new SignResultAnalyse(error, sign_result); - int status = std::min(resultAnalyseEncr->getStatus(), resultAnalyseSign->getStatus()); - auto reportText = resultAnalyseEncr->getResultReport() + resultAnalyseSign->getResultReport(); + auto error = GpgFileOpera::encryptSignFile(mCtx, keys, path, &encr_result, &sign_result); - infoBoard->associateTextEdit(edit->curTextPage()); + auto resultAnalyseEncr = new EncryptResultAnalyse(error, encr_result); + auto resultAnalyseSign = new SignResultAnalyse(error, sign_result); + int status = std::min(resultAnalyseEncr->getStatus(), resultAnalyseSign->getStatus()); + auto reportText = resultAnalyseEncr->getResultReport() + resultAnalyseSign->getResultReport(); - if (status < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (status > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + infoBoard->associateFileTreeView(edit->curFilePage()); + + if (status < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (status > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + + delete resultAnalyseEncr; + delete resultAnalyseSign; - delete resultAnalyseEncr; - delete resultAnalyseSign; + fileTreeView->update(); + + } catch (std::runtime_error &e) { + QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation.")); + } } -void MainWindow::slotDecryptVerify() { +void MainWindow::slotFileDecryptVerify() { + auto fileTreeView = edit->slotCurPageFileTreeView(); + auto path = fileTreeView->getSelected(); - if (edit->tabCount() == 0 || edit->slotCurPage() == nullptr) { + QFileInfo fileInfo(path); + QFileInfo pathInfo(fileInfo.absolutePath()); + if (!fileInfo.isFile()) { + QMessageBox::critical(this, tr("Error"), tr("Select a file(.gpg/.asc) before doing it.")); + return; + } + if (!fileInfo.isReadable()) { + QMessageBox::critical(this, tr("Error"), tr("No permission to read this file.")); + return; + } + if (!pathInfo.isWritable()) { + QMessageBox::critical(this, tr("Error"), tr("No permission to create file.")); return; } - auto *decrypted = new QByteArray(); - QByteArray text = edit->curTextPage()->toPlainText().toUtf8(); - GpgME::GpgContext::preventNoDataErr(&text); + QString outFileName, fileExtension = fileInfo.suffix(); - gpgme_decrypt_result_t d_result = nullptr; - gpgme_verify_result_t v_result = nullptr; - // try decrypt, if fail do nothing, especially don't replace text - auto error = mCtx->decryptVerify(text, decrypted, &d_result, &v_result); - infoBoard->associateTextEdit(edit->curTextPage()); + if (fileExtension == "asc" || fileExtension == "gpg") { + int pos = path.lastIndexOf(QChar('.')); + outFileName = path.left(pos); + } else { + outFileName = path + ".out"; + } - if(gpgme_err_code(error) == GPG_ERR_NO_ERROR) - edit->slotFillTextEditWithText(QString::fromUtf8(*decrypted)); + if (QFile::exists(outFileName)) { + auto ret = QMessageBox::warning(this, + tr("Warning"), + tr("The target file already exists, do you need to overwrite it?"), + QMessageBox::Ok | QMessageBox::Cancel); - auto resultAnalyseDecrypt = new DecryptResultAnalyse(mCtx, error, d_result); - auto resultAnalyseVerify = new VerifyResultAnalyse(mCtx, error, v_result); + if (ret == QMessageBox::Cancel) + return; + } - int status = std::min(resultAnalyseDecrypt->getStatus(), resultAnalyseVerify->getStatus()); - auto &reportText = resultAnalyseDecrypt->getResultReport() + resultAnalyseVerify->getResultReport(); - if (status < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (status > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + try { + + gpgme_decrypt_result_t d_result = nullptr; + gpgme_verify_result_t v_result = nullptr; + // try decrypt, if fail do nothing, especially don't replace text + auto error = GpgFileOpera::decryptVerifyFile(mCtx, path, &d_result, &v_result); + infoBoard->associateFileTreeView(edit->curFilePage()); + + auto resultAnalyseDecrypt = new DecryptResultAnalyse(mCtx, error, d_result); + auto resultAnalyseVerify = new VerifyResultAnalyse(mCtx, error, v_result); + + int status = std::min(resultAnalyseDecrypt->getStatus(), resultAnalyseVerify->getStatus()); + auto &reportText = resultAnalyseDecrypt->getResultReport() + resultAnalyseVerify->getResultReport(); + if (status < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (status > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + + if (resultAnalyseVerify->getStatus() >= 0) { + infoBoard->resetOptionActionsMenu(); + infoBoard->addOptionalAction("Show Verify Details", [this, error, v_result]() { + VerifyDetailsDialog(this, mCtx, mKeyList, error, v_result); + }); + } + delete resultAnalyseDecrypt; + delete resultAnalyseVerify; - if (resultAnalyseVerify->getStatus() >= 0) { - infoBoard->resetOptionActionsMenu(); - infoBoard->addOptionalAction("Show Verify Details", [this, error, v_result]() { - VerifyDetailsDialog(this, mCtx, mKeyList, error, v_result); - }); + fileTreeView->update(); + } catch (std::runtime_error &e) { + QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation.")); + return; } - delete resultAnalyseDecrypt; - delete resultAnalyseVerify; +} + +void MainWindow::slotFileEncryptCustom() { + QStringList *keyList; + keyList = mKeyList->getChecked(); + new FileEncryptionDialog(mCtx, *keyList, FileEncryptionDialog::Encrypt, this); +} + +void MainWindow::slotFileDecryptCustom() { + QStringList *keyList; + keyList = mKeyList->getChecked(); + new FileEncryptionDialog(mCtx, *keyList, FileEncryptionDialog::Decrypt, this); +} + +void MainWindow::slotFileSignCustom() { + QStringList *keyList; + keyList = mKeyList->getChecked(); + new FileEncryptionDialog(mCtx, *keyList, FileEncryptionDialog::Sign, this); +} + +void MainWindow::slotFileVerifyCustom() { + QStringList *keyList; + keyList = mKeyList->getChecked(); + new FileEncryptionDialog(mCtx, *keyList, FileEncryptionDialog::Verify, this); +} + +void MainWindow::slotOpenFile(QString &path) { + edit->slotOpenFile(path); } diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp index 8ee09f64..219d09b6 100644 --- a/src/ui/main_window/MainWindowSlotUI.cpp +++ b/src/ui/main_window/MainWindowSlotUI.cpp @@ -63,10 +63,8 @@ void MainWindow::slotCheckAttachmentFolder() { } void MainWindow::slotImportKeyFromEdit() { - if (edit->tabCount() == 0 || edit->slotCurPage() == 0) { + if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return; - } - keyMgmt->slotImportKeys(edit->curTextPage()->toPlainText().toUtf8()); } @@ -163,7 +161,7 @@ void MainWindow::slotOpenSettingsDialog() { } void MainWindow::slotCleanDoubleLinebreaks() { - if (edit->tabCount() == 0 || edit->slotCurPage() == nullptr) { + if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { return; } @@ -173,7 +171,7 @@ void MainWindow::slotCleanDoubleLinebreaks() { } void MainWindow::slotAddPgpHeader() { - if (edit->tabCount() == 0 || edit->slotCurPage() == nullptr) { + if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { return; } @@ -187,7 +185,7 @@ void MainWindow::slotAddPgpHeader() { void MainWindow::slotCutPgpHeader() { - if (edit->tabCount() == 0 || edit->slotCurPage() == nullptr) { + if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { return; } diff --git a/src/ui/main_window/MainWindowUI.cpp b/src/ui/main_window/MainWindowUI.cpp index 5afdc263..1c7029b9 100644 --- a/src/ui/main_window/MainWindowUI.cpp +++ b/src/ui/main_window/MainWindowUI.cpp @@ -169,19 +169,19 @@ void MainWindow::createActions() { */ fileEncryptAct = new QAction(tr("&Encrypt File"), this); fileEncryptAct->setToolTip(tr("Encrypt File")); - connect(fileEncryptAct, SIGNAL(triggered()), this, SLOT(slotFileEncrypt())); + connect(fileEncryptAct, SIGNAL(triggered()), this, SLOT(slotFileEncryptCustom())); fileDecryptAct = new QAction(tr("&Decrypt File"), this); fileDecryptAct->setToolTip(tr("Decrypt File")); - connect(fileDecryptAct, SIGNAL(triggered()), this, SLOT(slotFileDecrypt())); + connect(fileDecryptAct, SIGNAL(triggered()), this, SLOT(slotFileDecryptCustom())); fileSignAct = new QAction(tr("&Sign File"), this); fileSignAct->setToolTip(tr("Sign File")); - connect(fileSignAct, SIGNAL(triggered()), this, SLOT(slotFileSign())); + connect(fileSignAct, SIGNAL(triggered()), this, SLOT(slotFileSignCustom())); fileVerifyAct = new QAction(tr("&Verify File"), this); fileVerifyAct->setToolTip(tr("Verify File")); - connect(fileVerifyAct, SIGNAL(triggered()), this, SLOT(slotFileVerify())); + connect(fileVerifyAct, SIGNAL(triggered()), this, SLOT(slotFileVerifyCustom())); signAct = new QAction(tr("&Sign"), this); @@ -386,8 +386,8 @@ void MainWindow::createToolBars() { // Add dropdown menu for file encryption/decryption to crypttoolbar fileEncButton = new QToolButton(); - fileEncButton->setMenu(fileEncMenu); - // connect(fileEncButton, SIGNAL(clicked(bool)), this, SLOT(slotOpenFileTab())); + // fileEncButton->setMenu(fileEncMenu); + connect(fileEncButton, SIGNAL(clicked(bool)), this, SLOT(slotOpenFileTab())); fileEncButton->setPopupMode(QToolButton::InstantPopup); fileEncButton->setIcon(QIcon(":fileencryption.png")); fileEncButton->setToolTip(tr("Opera File")); diff --git a/src/ui/widgets/EditorPage.cpp b/src/ui/widgets/EditorPage.cpp index cb4ca5ef..8a51b721 100644 --- a/src/ui/widgets/EditorPage.cpp +++ b/src/ui/widgets/EditorPage.cpp @@ -27,7 +27,7 @@ #include <utility> EditorPage::EditorPage(QString filePath, QWidget *parent) : QWidget(parent), - fullFilePath(std::move(filePath)) { + fullFilePath(std::move(filePath)) { // Set the Textedit properties textPage = new QTextEdit(); textPage->setAcceptRichText(false); @@ -42,7 +42,7 @@ EditorPage::EditorPage(QString filePath, QWidget *parent) : QWidget(parent), setAttribute(Qt::WA_DeleteOnClose); textPage->setFocus(); - //connect(textPage, SIGNAL(textChanged()), this, SLOT(formatGpgHeader())); + connect(textPage, SIGNAL(textChanged()), this, SLOT(formatGpgHeader())); } const QString &EditorPage::getFilePath() const { @@ -64,11 +64,11 @@ void EditorPage::showNotificationWidget(QWidget *widget, const char *className) void EditorPage::closeNoteByClass(const char *className) { QList<QWidget *> widgets = findChildren<QWidget *>(); - foreach(QWidget *widget, widgets) { - if (widget->property(className) == true) { - widget->close(); - } + for (QWidget *widget: widgets) { + if (widget->property(className) == true) { + widget->close(); } + } } void EditorPage::slotFormatGpgHeader() { diff --git a/src/ui/widgets/FilePage.cpp b/src/ui/widgets/FilePage.cpp index e3d73670..16724f40 100644 --- a/src/ui/widgets/FilePage.cpp +++ b/src/ui/widgets/FilePage.cpp @@ -24,25 +24,42 @@ #include "ui/widgets/FilePage.h" +#include "MainWindow.h" + FilePage::FilePage(QWidget *parent) : QWidget(parent) { + + qDebug() << "First Parent" << parent; + firstParent = parent; + qDebug() << "New File Page"; dirModel = new QFileSystemModel(); - dirModel->setRootPath(QDir::currentPath()); dirTreeView = new QTreeView(); dirTreeView->setModel(dirModel); dirTreeView->setAnimated(true); dirTreeView->setIndentation(20); - dirTreeView->setSortingEnabled(true); dirTreeView->setRootIndex(dirModel->index(QDir::currentPath())); + dirTreeView->setContextMenuPolicy(Qt::CustomContextMenu); + mPath = dirModel->rootPath(); + + createPopupMenu(); upLevelButton = new QPushButton("UP Level"); connect(upLevelButton, SIGNAL(clicked(bool)), this, SLOT(slotUpLevel())); + goPathButton = new QPushButton("Go Path"); + connect(goPathButton, SIGNAL(clicked(bool)), this, SLOT(slotGoPath())); + + pathEdit = new QLineEdit(); + pathEdit->setFixedWidth(500); + pathEdit->setText(dirModel->rootPath()); + auto *menuLayout = new QHBoxLayout(); menuLayout->addWidget(upLevelButton); + menuLayout->addWidget(pathEdit); + menuLayout->addWidget(goPathButton); menuLayout->addStretch(0); auto *layout = new QVBoxLayout(); @@ -53,6 +70,9 @@ FilePage::FilePage(QWidget *parent) : QWidget(parent) { connect(dirTreeView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(fileTreeViewItemClicked(const QModelIndex &))); connect(dirTreeView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(fileTreeViewItemDoubleClicked(const QModelIndex &))); + connect(dirTreeView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onCustomContextMenu(const QPoint &))); + + emit pathChanged(mPath); } @@ -63,12 +83,14 @@ void FilePage::fileTreeViewItemClicked(const QModelIndex &index) { void FilePage::slotUpLevel() { QModelIndex currentRoot = dirTreeView->rootIndex(); - mPath = dirModel->fileInfo(currentRoot).absoluteFilePath(); + mPath = dirModel->fileInfo(currentRoot.parent()).absoluteFilePath(); auto fileInfo = QFileInfo(mPath); if(fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { dirTreeView->setRootIndex(currentRoot.parent()); + pathEdit->setText(mPath); } qDebug() << "Current Root mPath" << mPath; + emit pathChanged(mPath); } void FilePage::fileTreeViewItemDoubleClicked(const QModelIndex &index) { @@ -76,13 +98,129 @@ void FilePage::fileTreeViewItemDoubleClicked(const QModelIndex &index) { auto fileInfo = QFileInfo(mPath); if(fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { dirTreeView->setRootIndex(index); + pathEdit->setText(mPath); } qDebug() << "Index mPath" << mPath; + emit pathChanged(mPath); +} + +QString FilePage::getSelected() const { + return mPath; +} + +void FilePage::slotGoPath() { + qDebug() << "getSelected" << pathEdit->text(); + auto fileInfo = QFileInfo(pathEdit->text()); + if(fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { + qDebug() << "Set Path" << fileInfo.filePath(); + dirTreeView->setRootIndex(dirModel->index(fileInfo.filePath())); + } else { + QMessageBox::critical(this, "Error", "The path is unprivileged or unreachable."); + } + emit pathChanged(mPath); +} + +void FilePage::createPopupMenu() { + popUpMenu = new QMenu(); + + auto openItemAct = new QAction(tr("Open"), this); + connect(openItemAct, SIGNAL(triggered()), this, SLOT(slotOpenItem())); + auto deleteItemAct = new QAction(tr("Delete"), this); + connect(deleteItemAct, SIGNAL(triggered()), this, SLOT(slotDeleteItem())); + encryptItemAct = new QAction(tr("Encrypt and Sign"), this); + connect(encryptItemAct, SIGNAL(triggered()), this, SLOT(slotEncryptItem())); + decryptItemAct = new QAction(tr("Decrypt and Verify"), this); + connect(decryptItemAct, SIGNAL(triggered()), this, SLOT(slotDecryptItem())); + signItemAct = new QAction(tr("Only Sign"), this); + connect(signItemAct, SIGNAL(triggered()), this, SLOT(slotSignItem())); + verifyItemAct = new QAction(tr("Only Verify"), this); + connect(verifyItemAct, SIGNAL(triggered()), this, SLOT(slotVerifyItem())); + + popUpMenu->addAction(openItemAct); + popUpMenu->addAction(deleteItemAct); + popUpMenu->addSeparator(); + popUpMenu->addAction(encryptItemAct); + popUpMenu->addAction(decryptItemAct); + popUpMenu->addAction(signItemAct); + popUpMenu->addAction(verifyItemAct); + +} + +void FilePage::onCustomContextMenu(const QPoint &point) { + QModelIndex index = dirTreeView->indexAt(point); + mPath = dirModel->fileInfo(index).absoluteFilePath(); + qDebug() << "Right Click" << mPath; + if (index.isValid()) { + QFileInfo info(mPath); + encryptItemAct->setEnabled(info.isFile()); + decryptItemAct->setEnabled(info.isFile()); + signItemAct->setEnabled(info.isFile()); + verifyItemAct->setEnabled(info.isFile()); + + popUpMenu->exec(dirTreeView->viewport()->mapToGlobal(point)); + } +} + +void FilePage::slotOpenItem() { + QFileInfo info(mPath); + if(info.isDir()) { + qDebug() << "getSelected" << pathEdit->text(); + if(info.isReadable() && info.isExecutable()) { + qDebug() << "Set Path" << info.filePath(); + dirTreeView->setRootIndex(dirModel->index(info.filePath())); + } else { + QMessageBox::critical(this, "Error", "The path is unprivileged or unreachable."); + } + } else { + auto mainWindow = qobject_cast<MainWindow *>(firstParent); + qDebug() << "Open Item" << mPath; + if (mainWindow != nullptr) + mainWindow->slotOpenFile(mPath); + } + emit pathChanged(mPath); } -void FilePage::getSelected(QString &path) { +void FilePage::slotDeleteItem() { QModelIndex index = dirTreeView->currentIndex(); QVariant data = dirTreeView->model()->data(index); - path = data.toString(); - qDebug() << "Target Path" << mPath; + + auto ret = QMessageBox::warning(this, + tr("Warning"), + tr("Are you sure you want to delete it?"), + QMessageBox::Ok | QMessageBox::Cancel); + + if(ret == QMessageBox::Cancel) + return; + + qDebug() << "Delete Item" << data.toString(); + + if(!dirModel->remove(index)){ + QMessageBox::critical(this, + tr("Error"), + tr("Unable to delete the file or folder.")); + } +} + +void FilePage::slotEncryptItem() { + auto mainWindow = qobject_cast<MainWindow *>(firstParent); + if(mainWindow != nullptr) + mainWindow->slotFileEncryptSign(); +} + +void FilePage::slotDecryptItem() { + auto mainWindow = qobject_cast<MainWindow *>(firstParent); + if(mainWindow != nullptr) + mainWindow->slotFileDecryptVerify(); +} + +void FilePage::slotSignItem() { + auto mainWindow = qobject_cast<MainWindow *>(firstParent); + if(mainWindow != nullptr) + mainWindow->slotFileSign(); +} + +void FilePage::slotVerifyItem() { + auto mainWindow = qobject_cast<MainWindow *>(firstParent); + if(mainWindow != nullptr) + mainWindow->slotFileVerify(); } diff --git a/src/ui/widgets/InfoBoardWidget.cpp b/src/ui/widgets/InfoBoardWidget.cpp index 76f82505..f54bcf96 100644 --- a/src/ui/widgets/InfoBoardWidget.cpp +++ b/src/ui/widgets/InfoBoardWidget.cpp @@ -25,7 +25,7 @@ #include "ui/widgets/InfoBoardWidget.h" InfoBoardWidget::InfoBoardWidget(QWidget *parent, GpgME::GpgContext *ctx, KeyList *keyList) : - QWidget(parent), mCtx(ctx), mKeyList(keyList){ + QWidget(parent), mCtx(ctx), mKeyList(keyList) { infoBoard = new QTextEdit(this); infoBoard->setReadOnly(true); @@ -43,7 +43,7 @@ InfoBoardWidget::InfoBoardWidget(QWidget *parent, GpgME::GpgContext *ctx, KeyLis actionButtonLayout = new QHBoxLayout(); auto label = new QLabel("Optional Actions Menu"); - label->setMinimumHeight(16); + label->setFixedHeight(24); actionButtonLayout->addWidget(label); actionButtonLayout->addStretch(); @@ -96,15 +96,36 @@ void InfoBoardWidget::slotRefresh(const QString &text, InfoBoardStatus status) { } void InfoBoardWidget::associateTextEdit(QTextEdit *edit) { - this->mTextPage = edit; - if(mTextPage != nullptr) { + if (mTextPage != nullptr) disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset())); - } + this->mTextPage = edit; connect(edit, SIGNAL(textChanged()), this, SLOT(slotReset())); } -void InfoBoardWidget::addOptionalAction(const QString& name, const std::function<void()>& action) { +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) { + if (mTextPage != nullptr) + disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset())); +// if (mFileTreeView != nullptr) +// disconnect(mFileTreeView, &FilePage::pathChanged, this, &InfoBoardWidget::slotReset); + if (mTabWidget != nullptr) + disconnect(mTabWidget, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset())); + + mTextPage = nullptr; + mFileTreeView = nullptr; + mTabWidget = tab; + connect(tab, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset())); +} + +void InfoBoardWidget::addOptionalAction(const QString &name, const std::function<void()> &action) { auto actionButton = new QPushButton(name); + actionButton->setFixedHeight(24); actionButtonLayout->addWidget(actionButton); connect(actionButton, &QPushButton::clicked, this, [=]() { action(); @@ -113,7 +134,7 @@ void InfoBoardWidget::addOptionalAction(const QString& name, const std::function void InfoBoardWidget::resetOptionActionsMenu() { QLayoutItem *item; - while ((item = actionButtonLayout->layout()->takeAt( 2)) != nullptr ) { + while ((item = actionButtonLayout->layout()->takeAt(2)) != nullptr) { actionButtonLayout->removeItem(item); delete item->widget(); delete item; diff --git a/src/ui/widgets/TextEdit.cpp b/src/ui/widgets/TextEdit.cpp index 49049baa..9ca1b578 100644 --- a/src/ui/widgets/TextEdit.cpp +++ b/src/ui/widgets/TextEdit.cpp @@ -24,7 +24,7 @@ #include "ui/widgets/TextEdit.h" -TextEdit::TextEdit() { +TextEdit::TextEdit(QWidget *parent) : QWidget(parent) { countPage = 0; tabWidget = new QTabWidget(this); tabWidget->setMovable(true); @@ -66,53 +66,83 @@ void TextEdit::slotNewHelpTab(const QString &title, const QString &path) const { void TextEdit::slotNewFileTab() const { - auto *page = new FilePage(); - tabWidget->addTab(page, "File"); + auto *page = new FilePage(qobject_cast<QWidget *>(parent())); + tabWidget->addTab(page, "[File Browser]"); tabWidget->setCurrentIndex(tabWidget->count() - 1); + connect(page, SIGNAL(pathChanged(const QString &)), this, SLOT(slotFilePagePathChanged(const QString &))); } +void TextEdit::slotOpenFile(QString &path) { + + QFile file(path); + + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + auto *page = new EditorPage(path); + + QTextStream in(&file); + QApplication::setOverrideCursor(Qt::WaitCursor); + page->getTextPage()->setPlainText(in.readAll()); + page->setFilePath(path); + QTextDocument *document = page->getTextPage()->document(); + document->setModified(false); + + tabWidget->addTab(page, strippedName(path)); + tabWidget->setCurrentIndex(tabWidget->count() - 1); + QApplication::restoreOverrideCursor(); + page->getTextPage()->setFocus(); + connect(page->getTextPage()->document(), SIGNAL(modificationChanged(bool)), this, + SLOT(slotShowModified())); + //enableAction(true) + file.close(); + } else { + QMessageBox::warning(this, tr("Warning"), + tr("Cannot read file %1:\n%2.") + .arg(path).arg(file.errorString())); + } +} + void TextEdit::slotOpen() { QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open file"), QDir::currentPath()); - foreach (QString fileName, fileNames) { - if (!fileName.isEmpty()) { - QFile file(fileName); - - if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { - auto *page = new EditorPage(fileName); - - QTextStream in(&file); - QApplication::setOverrideCursor(Qt::WaitCursor); - page->getTextPage()->setPlainText(in.readAll()); - page->setFilePath(fileName); - QTextDocument *document = page->getTextPage()->document(); - document->setModified(false); - - tabWidget->addTab(page, strippedName(fileName)); - tabWidget->setCurrentIndex(tabWidget->count() - 1); - QApplication::restoreOverrideCursor(); - page->getTextPage()->setFocus(); - connect(page->getTextPage()->document(), SIGNAL(modificationChanged(bool)), this, - SLOT(slotShowModified())); - //enableAction(true) - file.close(); - } else { - QMessageBox::warning(this, tr("Application"), - tr("Cannot read file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - } + for (const auto &fileName : fileNames) { + if (!fileName.isEmpty()) { + QFile file(fileName); + + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + auto *page = new EditorPage(fileName); + + QTextStream in(&file); + QApplication::setOverrideCursor(Qt::WaitCursor); + page->getTextPage()->setPlainText(in.readAll()); + page->setFilePath(fileName); + QTextDocument *document = page->getTextPage()->document(); + document->setModified(false); + + tabWidget->addTab(page, strippedName(fileName)); + tabWidget->setCurrentIndex(tabWidget->count() - 1); + QApplication::restoreOverrideCursor(); + page->getTextPage()->setFocus(); + connect(page->getTextPage()->document(), SIGNAL(modificationChanged(bool)), this, + SLOT(slotShowModified())); + //enableAction(true) + file.close(); + } else { + QMessageBox::warning(this, tr("Warning"), + tr("Cannot read file %1:\n%2.") + .arg(fileName) + .arg(file.errorString())); } } + } } void TextEdit::slotSave() { - if (tabWidget->count() == 0 || slotCurPage() == 0) { + if (tabWidget->count() == 0 || slotCurPageTextEdit() == 0) { return; } - QString fileName = slotCurPage()->getFilePath(); + QString fileName = slotCurPageTextEdit()->getFilePath(); if (fileName.isEmpty()) { //QString docname = tabWidget->tabText(tabWidget->currentIndex()); @@ -131,7 +161,7 @@ bool TextEdit::saveFile(const QString &fileName) { QFile file(fileName); if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { - EditorPage *page = slotCurPage(); + EditorPage *page = slotCurPageTextEdit(); QTextStream outputStream(&file); QApplication::setOverrideCursor(Qt::WaitCursor); @@ -158,11 +188,11 @@ bool TextEdit::saveFile(const QString &fileName) { bool TextEdit::slotSaveAs() { - if (tabWidget->count() == 0 || slotCurPage() == 0) { + if (tabWidget->count() == 0 || slotCurPageTextEdit() == 0) { return true; } - EditorPage *page = slotCurPage(); + EditorPage *page = slotCurPageTextEdit(); QString path; if (page->getFilePath() != "") { path = page->getFilePath(); @@ -170,7 +200,7 @@ bool TextEdit::slotSaveAs() { path = tabWidget->tabText(tabWidget->currentIndex()).remove(0, 2); } - QString fileName = QFileDialog::getSaveFileName(this, tr("Save file "), + QString fileName = QFileDialog::getSaveFileName(this, tr("Save file"), path); return saveFile(fileName); } @@ -178,7 +208,7 @@ bool TextEdit::slotSaveAs() { void TextEdit::slotCloseTab() { removeTab(tabWidget->currentIndex()); if (tabWidget->count() != 0) { - slotCurPage()->getTextPage()->setFocus(); + slotCurPageTextEdit()->getTextPage()->setFocus(); } } @@ -218,7 +248,7 @@ void TextEdit::removeTab(int index) { */ bool TextEdit::maybeSaveCurrentTab(bool askToSave) { - EditorPage *page = slotCurPage(); + EditorPage *page = slotCurPageTextEdit(); // if this page is no textedit, there should be nothing to save if (page == nullptr) { return true; @@ -299,7 +329,8 @@ bool TextEdit::maybeSaveAnyTab() { bool allsaved = true; QList<int> tabIdsToSave = dialog->getTabIdsToSave(); - foreach (int tabId, tabIdsToSave) { + foreach(int + tabId, tabIdsToSave) { tabWidget->setCurrentIndex(tabId); if (!maybeSaveCurrentTab(false)) { allsaved = false; @@ -326,10 +357,10 @@ QTextEdit *TextEdit::curTextPage() const { } } -QTextBrowser *TextEdit::curHelpPage() const { - auto *curHelpPage = qobject_cast<HelpPage *>(tabWidget->currentWidget()); - if (curHelpPage != nullptr) { - return curHelpPage->getBrowser(); +FilePage * TextEdit::curFilePage() const { + auto *curFilePage = qobject_cast<FilePage *>(tabWidget->currentWidget()); + if (curFilePage != nullptr) { + return curFilePage; } else { return nullptr; } @@ -339,11 +370,16 @@ int TextEdit::tabCount() const { return tabWidget->count(); } -EditorPage *TextEdit::slotCurPage() const { +EditorPage *TextEdit::slotCurPageTextEdit() const { auto *curPage = qobject_cast<EditorPage *>(tabWidget->currentWidget()); return curPage; } +FilePage *TextEdit::slotCurPageFileTreeView() const { + auto *curPage = qobject_cast<FilePage *>(tabWidget->currentWidget()); + return curPage; +} + void TextEdit::slotQuote() const { if (tabWidget->count() == 0 || curTextPage() == nullptr) { return; @@ -386,7 +422,7 @@ void TextEdit::loadFile(const QString &fileName) { QApplication::setOverrideCursor(Qt::WaitCursor); curTextPage()->setPlainText(in.readAll()); QApplication::restoreOverrideCursor(); - slotCurPage()->setFilePath(fileName); + slotCurPageTextEdit()->setFilePath(fileName); tabWidget->setTabText(tabWidget->currentIndex(), strippedName(fileName)); file.close(); // statusBar()->showMessage(tr("File loaded"), 2000); @@ -403,9 +439,7 @@ void TextEdit::slotPrint() { #ifndef QT_NO_PRINTER QTextDocument *document; - if (curTextPage() == nullptr) { - document = curHelpPage()->document(); - } else { + if (curTextPage() != nullptr) { document = curTextPage()->document(); } QPrinter printer; @@ -479,8 +513,6 @@ void TextEdit::slotCopy() const { if (curTextPage() != nullptr) { curTextPage()->copy(); - } else { - curHelpPage()->copy(); } @@ -517,8 +549,6 @@ void TextEdit::slotZoomIn() const { if (curTextPage() != nullptr) { curTextPage()->zoomIn(); - } else { - curHelpPage()->zoomIn(); } } @@ -530,8 +560,6 @@ void TextEdit::slotZoomOut() const { if (curTextPage() != nullptr) { curTextPage()->zoomOut(); - } else { - curHelpPage()->zoomOut(); } } @@ -539,26 +567,20 @@ void TextEdit::slotSelectAll() const { if (tabWidget->count() == 0 || curTextPage() == nullptr) { return; } - curTextPage()->selectAll(); } -/*void TextEdit::dragEnterEvent(QDragEnterEvent *event) -{ - if (event->mimeData()->hasFormat("text/plain")) - qDebug() << "enter textedit drag action"; - event->acceptProposedAction(); -} - -void TextEdit::dropEvent(QDropEvent* event) -{ - curTextPage()->setPlainText(event->mimeData()->text()); - - foreach (QUrl tmp, event->mimeData()->urls()) - { - qDebug() << tmp; +void TextEdit::slotFilePagePathChanged(const QString &path) { + int index = tabWidget->currentIndex(); + QString mPath; + QFileInfo fileInfo(path); + QString tPath = fileInfo.path(); + if (path.size() > 16) { + mPath = tPath.mid(tPath.size() - 16, 16).prepend("..."); + } else { + mPath = tPath; } - - //event->acceptProposedAction(); -} -*/ + mPath.prepend("[File Browser]: "); + mPath.append("/"); + tabWidget->setTabText(index, mPath); +}
\ No newline at end of file |