diff options
author | Saturneric <[email protected]> | 2021-06-27 20:00:05 +0000 |
---|---|---|
committer | Saturneric <[email protected]> | 2021-06-27 20:00:05 +0000 |
commit | 5143c2d56255dec8ca618bc9acaf054781dd8746 (patch) | |
tree | c2861c182fc59bbf5d505bc87929cdd118a5297e | |
parent | Develop File Opera Functions (diff) | |
download | GpgFrontend-5143c2d56255dec8ca618bc9acaf054781dd8746.tar.gz GpgFrontend-5143c2d56255dec8ca618bc9acaf054781dd8746.zip |
Add and improve file operation functions.
Diffstat (limited to '')
-rw-r--r-- | include/MainWindow.h | 30 | ||||
-rw-r--r-- | include/gpg/GpgFileOpera.h | 16 | ||||
-rw-r--r-- | include/ui/widgets/FilePage.h | 5 | ||||
-rw-r--r-- | include/ui/widgets/InfoBoardWidget.h | 11 | ||||
-rw-r--r-- | include/ui/widgets/TextEdit.h | 2 | ||||
-rw-r--r-- | resource/ts/gpg_frontend_fr.ts | 26 | ||||
-rw-r--r-- | resource/ts/gpg_frontend_ru.ts | 26 | ||||
-rw-r--r-- | resource/ts/gpgfrontend_en_us.ts | 26 | ||||
-rw-r--r-- | resource/ts/gpgfrontend_zh_chs.ts | 26 | ||||
-rw-r--r-- | resource/ts/gpgfrontend_zh_cht.ts | 26 | ||||
-rw-r--r-- | src/gpg/GpgFileOpera.cpp | 201 | ||||
-rw-r--r-- | src/gpg/result_analyse/VerifyResultAnalyse.cpp | 2 | ||||
-rw-r--r-- | src/ui/main_window/MainWindowSlotFunction.cpp | 692 | ||||
-rw-r--r-- | src/ui/main_window/MainWindowUI.cpp | 8 | ||||
-rw-r--r-- | src/ui/widgets/FilePage.cpp | 22 | ||||
-rw-r--r-- | src/ui/widgets/InfoBoardWidget.cpp | 35 | ||||
-rw-r--r-- | src/ui/widgets/TextEdit.cpp | 34 |
17 files changed, 927 insertions, 261 deletions
diff --git a/include/MainWindow.h b/include/MainWindow.h index af6b1560..8c88a301 100644 --- a/include/MainWindow.h +++ b/include/MainWindow.h @@ -96,6 +96,16 @@ public slots: */ void slotFileVerify(); + /** + * @details Open dialog for signing file. + */ + void slotFileEncryptSign(); + + /** + * @details Open dialog for verifying file. + */ + void slotFileDecryptVerify(); + private slots: @@ -135,6 +145,26 @@ private slots: void slotDecryptVerify(); /** + * @details Open dialog for encrypting file. + */ + void slotFileEncryptCustom(); + + /** + * @details Open dialog for decrypting file. + */ + void slotFileDecryptCustom(); + + /** + * @details Open dialog for signing file. + */ + void slotFileSignCustom(); + + /** + * @details Open dialog for verifying file. + */ + void slotFileVerifyCustom(); + + /** * @details Show the details of the first of the first of selected keys */ void slotShowKeyDetails(); diff --git a/include/gpg/GpgFileOpera.h b/include/gpg/GpgFileOpera.h index c6b4aec8..9b5e118c 100644 --- a/include/gpg/GpgFileOpera.h +++ b/include/gpg/GpgFileOpera.h @@ -30,7 +30,21 @@ class GpgFileOpera { public: - static bool encryptFile(GpgME::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath); + static gpgme_error_t encryptFile(GpgME::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath, + gpgme_encrypt_result_t *result); + + static gpgme_error_t decryptFile(GpgME::GpgContext *ctx, const QString &mPath, gpgme_decrypt_result_t *result); + + static gpgme_error_t signFile(GpgME::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath, + gpgme_sign_result_t *result); + + static gpgme_error_t verifyFile(GpgME::GpgContext *ctx, const QString &mPath, gpgme_verify_result_t *result); + + static gpg_error_t + encryptSignFile(GpgME::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath, gpgme_encrypt_result_t *encr_res, gpgme_sign_result_t *sign_res); + + static gpg_error_t decryptVerifyFile(GpgME::GpgContext *ctx, const QString &mPath, gpgme_decrypt_result_t *decr_res, gpgme_verify_result_t *verify_res); + }; diff --git a/include/ui/widgets/FilePage.h b/include/ui/widgets/FilePage.h index d7ce51d7..5a4331be 100644 --- a/include/ui/widgets/FilePage.h +++ b/include/ui/widgets/FilePage.h @@ -38,9 +38,7 @@ public: void createPopupMenu(); signals: - - void pathChanged(QString path); - + void pathChanged(const QString &path); private slots: @@ -78,7 +76,6 @@ private: QWidget *firstParent; - }; diff --git a/include/ui/widgets/InfoBoardWidget.h b/include/ui/widgets/InfoBoardWidget.h index 9d3dbd16..f487b72c 100644 --- a/include/ui/widgets/InfoBoardWidget.h +++ b/include/ui/widgets/InfoBoardWidget.h @@ -26,6 +26,7 @@ #define __VERIFYNOTIFICATION_H__ #include "EditorPage.h" +#include "FilePage.h" #include "ui/VerifyDetailsDialog.h" #include "gpg/result_analyse/VerifyResultAnalyse.h" @@ -56,6 +57,10 @@ public: void associateTextEdit(QTextEdit *edit); + void associateFileTreeView(FilePage *treeView); + + void associateTabWidget(QTabWidget *tab); + void addOptionalAction(const QString& name, const std::function<void()>& action); void resetOptionActionsMenu(); @@ -95,7 +100,11 @@ private: QTextEdit *infoBoard; GpgME::GpgContext *mCtx; /** GpgME Context */ KeyList *mKeyList; /** Table holding the keys */ - QTextEdit *mTextPage{ nullptr }; /** Textedit associated to the notification */ + + QTextEdit *mTextPage{ nullptr }; /** TextEdit associated to the notification */ + FilePage *mFileTreeView{nullptr }; /** TreeView associated to the notification */ + QTabWidget *mTabWidget{ nullptr }; /** TreeView associated to the notification */ + QHBoxLayout *actionButtonLayout; diff --git a/include/ui/widgets/TextEdit.h b/include/ui/widgets/TextEdit.h index 8e1df675..b807d6c6 100644 --- a/include/ui/widgets/TextEdit.h +++ b/include/ui/widgets/TextEdit.h @@ -69,7 +69,7 @@ public: */ [[nodiscard]] QTextEdit *curTextPage() const; - [[nodiscard]] QTextBrowser *curHelpPage() const; + [[nodiscard]] FilePage * curFilePage() const; /** * @details List of currently unsaved tabs. diff --git a/resource/ts/gpg_frontend_fr.ts b/resource/ts/gpg_frontend_fr.ts index 33f8b53d..c452ae46 100644 --- a/resource/ts/gpg_frontend_fr.ts +++ b/resource/ts/gpg_frontend_fr.ts @@ -2811,57 +2811,57 @@ This is NOT your Public Key, so DON'T give it away.<br />Do you REALL <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="100"/> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="132"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="99"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="131"/> <source>Warning</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="107"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="106"/> <source>Open file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="204"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="203"/> <source>Save file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="416"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="415"/> <source>Application</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="101"/> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="133"/> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="417"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="100"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="132"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="416"/> <source>Cannot read file %1: %2.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="182"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="181"/> <source>File</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="183"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="182"/> <source>Cannot write file %1: %2.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="268"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="267"/> <source>Unsaved document</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="269"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="268"/> <source><h3>The document "%1" has been modified.<br/>Do you want to save your changes?</h3></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="271"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="270"/> <source><b>Note:</b> If you don't save these files, all changes are lost.<br/></source> <translation type="unfinished"></translation> </message> diff --git a/resource/ts/gpg_frontend_ru.ts b/resource/ts/gpg_frontend_ru.ts index 392479ea..0bc0514a 100644 --- a/resource/ts/gpg_frontend_ru.ts +++ b/resource/ts/gpg_frontend_ru.ts @@ -2811,57 +2811,57 @@ This is NOT your Public Key, so DON'T give it away.<br />Do you REALL <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="100"/> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="132"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="99"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="131"/> <source>Warning</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="107"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="106"/> <source>Open file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="204"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="203"/> <source>Save file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="416"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="415"/> <source>Application</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="101"/> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="133"/> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="417"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="100"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="132"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="416"/> <source>Cannot read file %1: %2.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="182"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="181"/> <source>File</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="183"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="182"/> <source>Cannot write file %1: %2.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="268"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="267"/> <source>Unsaved document</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="269"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="268"/> <source><h3>The document "%1" has been modified.<br/>Do you want to save your changes?</h3></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="271"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="270"/> <source><b>Note:</b> If you don't save these files, all changes are lost.<br/></source> <translation type="unfinished"></translation> </message> diff --git a/resource/ts/gpgfrontend_en_us.ts b/resource/ts/gpgfrontend_en_us.ts index 58c7e8ff..dd8139ac 100644 --- a/resource/ts/gpgfrontend_en_us.ts +++ b/resource/ts/gpgfrontend_en_us.ts @@ -2811,57 +2811,57 @@ This is NOT your Public Key, so DON'T give it away.<br />Do you REALL <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="100"/> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="132"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="99"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="131"/> <source>Warning</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="107"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="106"/> <source>Open file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="204"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="203"/> <source>Save file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="416"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="415"/> <source>Application</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="101"/> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="133"/> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="417"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="100"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="132"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="416"/> <source>Cannot read file %1: %2.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="182"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="181"/> <source>File</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="183"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="182"/> <source>Cannot write file %1: %2.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="268"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="267"/> <source>Unsaved document</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="269"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="268"/> <source><h3>The document "%1" has been modified.<br/>Do you want to save your changes?</h3></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="271"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="270"/> <source><b>Note:</b> If you don't save these files, all changes are lost.<br/></source> <translation type="unfinished"></translation> </message> diff --git a/resource/ts/gpgfrontend_zh_chs.ts b/resource/ts/gpgfrontend_zh_chs.ts index 9464f39c..dbf05389 100644 --- a/resource/ts/gpgfrontend_zh_chs.ts +++ b/resource/ts/gpgfrontend_zh_chs.ts @@ -2811,57 +2811,57 @@ This is NOT your Public Key, so DON'T give it away.<br />Do you REALL <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="100"/> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="132"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="99"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="131"/> <source>Warning</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="107"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="106"/> <source>Open file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="204"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="203"/> <source>Save file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="416"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="415"/> <source>Application</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="101"/> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="133"/> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="417"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="100"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="132"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="416"/> <source>Cannot read file %1: %2.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="182"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="181"/> <source>File</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="183"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="182"/> <source>Cannot write file %1: %2.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="268"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="267"/> <source>Unsaved document</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="269"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="268"/> <source><h3>The document "%1" has been modified.<br/>Do you want to save your changes?</h3></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="271"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="270"/> <source><b>Note:</b> If you don't save these files, all changes are lost.<br/></source> <translation type="unfinished"></translation> </message> diff --git a/resource/ts/gpgfrontend_zh_cht.ts b/resource/ts/gpgfrontend_zh_cht.ts index 9464f39c..dbf05389 100644 --- a/resource/ts/gpgfrontend_zh_cht.ts +++ b/resource/ts/gpgfrontend_zh_cht.ts @@ -2811,57 +2811,57 @@ This is NOT your Public Key, so DON'T give it away.<br />Do you REALL <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="100"/> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="132"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="99"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="131"/> <source>Warning</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="107"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="106"/> <source>Open file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="204"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="203"/> <source>Save file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="416"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="415"/> <source>Application</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="101"/> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="133"/> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="417"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="100"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="132"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="416"/> <source>Cannot read file %1: %2.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="182"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="181"/> <source>File</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="183"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="182"/> <source>Cannot write file %1: %2.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="268"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="267"/> <source>Unsaved document</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="269"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="268"/> <source><h3>The document "%1" has been modified.<br/>Do you want to save your changes?</h3></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../src/ui/widgets/TextEdit.cpp" line="271"/> + <location filename="../../src/ui/widgets/TextEdit.cpp" line="270"/> <source><b>Note:</b> If you don't save these files, all changes are lost.<br/></source> <translation type="unfinished"></translation> </message> diff --git a/src/gpg/GpgFileOpera.cpp b/src/gpg/GpgFileOpera.cpp index c3a9b5d0..f7db9d44 100644 --- a/src/gpg/GpgFileOpera.cpp +++ b/src/gpg/GpgFileOpera.cpp @@ -23,30 +23,215 @@ */ #include "gpg/GpgFileOpera.h" -bool GpgFileOpera::encryptFile(GpgME::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath) { +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()) return false; + if (!fileInfo.isFile() || !fileInfo.isReadable()) + throw std::runtime_error("no permission"); QFile infile; infile.setFileName(mPath); if (!infile.open(QIODevice::ReadOnly)) - return false; + throw std::runtime_error("cannot open file"); QByteArray inBuffer = infile.readAll(); - auto *outBuffer = new QByteArray(); + auto outBuffer = QByteArray(); infile.close(); - if (gpg_err_code(ctx->encrypt(keys, inBuffer, outBuffer, nullptr)) != GPG_ERR_NO_ERROR) return false; + 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)) - return false; + 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()); + out.writeRawData(outBuffer.data(), outBuffer.length()); outfile.close(); - return true; + + 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 023b3d73..106c3cd1 100644 --- a/src/ui/main_window/MainWindowSlotFunction.cpp +++ b/src/ui/main_window/MainWindowSlotFunction.cpp @@ -28,7 +28,7 @@ void MainWindow::slotEncrypt() { if (edit->tabCount() == 0) return; - if(edit->slotCurPageTextEdit() != nullptr) { + if (edit->slotCurPageTextEdit() != nullptr) { QVector<GpgKey> keys; mKeyList->getCheckedKeys(keys); @@ -69,84 +69,91 @@ void MainWindow::slotEncrypt() { infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); delete resultAnalyse; - } else if(edit->slotCurPageFileTreeView() != nullptr) { + } else if (edit->slotCurPageFileTreeView() != nullptr) { this->slotFileEncrypt(); } } void MainWindow::slotSign() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { - return; - } - QVector<GpgKey> keys; + if (edit->tabCount() == 0) return; - mKeyList->getPrivateCheckedKeys(keys); + if (edit->slotCurPageTextEdit() != nullptr) { - if (keys.isEmpty()) { - QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected")); - return; - } + QVector<GpgKey> keys; - 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); + 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); - 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->slotFileSign(); + } } void MainWindow::slotDecrypt() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == 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() { @@ -163,39 +170,136 @@ void MainWindow::slotFind() { } void MainWindow::slotVerify() { + + 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 (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() { + if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { return; } - // If an unknown key is found, enable the importfromkeyserveraction - + auto *decrypted = new QByteArray(); QByteArray text = edit->curTextPage()->toPlainText().toUtf8(); GpgME::GpgContext::preventNoDataErr(&text); + 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()); - gpgme_verify_result_t result; - - auto error = mCtx->verify(&text, nullptr, &result); + if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) + edit->slotFillTextEditWithText(QString::fromUtf8(*decrypted)); - auto resultAnalyse = new VerifyResultAnalyse(mCtx, error, result); - infoBoard->associateTextEdit(edit->curTextPage()); + auto resultAnalyseDecrypt = new DecryptResultAnalyse(mCtx, error, d_result); + auto resultAnalyseVerify = new VerifyResultAnalyse(mCtx, error, v_result); - auto &reportText = resultAnalyse->getResultReport(); - if (resultAnalyse->getStatus() < 0) + 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; } /* @@ -254,21 +358,27 @@ void MainWindow::slotFileEncrypt() { auto path = fileTreeView->getSelected(); QFileInfo fileInfo(path); - if(!fileInfo.isFile()) { + QFileInfo pathInfo(fileInfo.absolutePath()); + + if (!fileInfo.isFile()) { QMessageBox::critical(this, tr("Error"), tr("Select a file before doing it.")); return; } - if(!fileInfo.isReadable()) { + if (!fileInfo.isReadable()) { QMessageBox::critical(this, tr("Error"), tr("No permission to read this file.")); return; } - if(QFile::exists(path + ".asc")) { + 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); + tr("Warning"), + tr("The target file already exists, do you need to overwrite it?"), + QMessageBox::Ok | QMessageBox::Cancel); - if(ret == QMessageBox::Cancel) + if (ret == QMessageBox::Cancel) return; } @@ -276,7 +386,7 @@ void MainWindow::slotFileEncrypt() { mKeyList->getCheckedKeys(keys); - if(keys.empty()) { + if (keys.empty()) { QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected")); return; } @@ -292,121 +402,419 @@ void MainWindow::slotFileEncrypt() { } } - if(!GpgFileOpera::encryptFile(mCtx, keys, path)) { + 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.")); } - fileTreeView->update(); - } 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->slotCurPageTextEdit() == 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->slotCurPageTextEdit() == 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 { - if (resultAnalyseVerify->getStatus() >= 0) { - infoBoard->resetOptionActionsMenu(); - infoBoard->addOptionalAction("Show Verify Details", [this, error, v_result]() { - VerifyDetailsDialog(this, mCtx, mKeyList, error, v_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 = 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; + + 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) { diff --git a/src/ui/main_window/MainWindowUI.cpp b/src/ui/main_window/MainWindowUI.cpp index fba2fe62..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); diff --git a/src/ui/widgets/FilePage.cpp b/src/ui/widgets/FilePage.cpp index e4226bcf..16724f40 100644 --- a/src/ui/widgets/FilePage.cpp +++ b/src/ui/widgets/FilePage.cpp @@ -127,13 +127,13 @@ void FilePage::createPopupMenu() { 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 File"), this); + encryptItemAct = new QAction(tr("Encrypt and Sign"), this); connect(encryptItemAct, SIGNAL(triggered()), this, SLOT(slotEncryptItem())); - decryptItemAct = new QAction(tr("Decrypt File"), this); + decryptItemAct = new QAction(tr("Decrypt and Verify"), this); connect(decryptItemAct, SIGNAL(triggered()), this, SLOT(slotDecryptItem())); - signItemAct = new QAction(tr("Sign File"), this); + signItemAct = new QAction(tr("Only Sign"), this); connect(signItemAct, SIGNAL(triggered()), this, SLOT(slotSignItem())); - verifyItemAct = new QAction(tr("Verify File"), this); + verifyItemAct = new QAction(tr("Only Verify"), this); connect(verifyItemAct, SIGNAL(triggered()), this, SLOT(slotVerifyItem())); popUpMenu->addAction(openItemAct); @@ -204,17 +204,23 @@ void FilePage::slotDeleteItem() { void FilePage::slotEncryptItem() { auto mainWindow = qobject_cast<MainWindow *>(firstParent); if(mainWindow != nullptr) - mainWindow->slotFileEncrypt(); + 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 2394b694..9ca1b578 100644 --- a/src/ui/widgets/TextEdit.cpp +++ b/src/ui/widgets/TextEdit.cpp @@ -67,9 +67,9 @@ void TextEdit::slotNewHelpTab(const QString &title, const QString &path) const { void TextEdit::slotNewFileTab() const { auto *page = new FilePage(qobject_cast<QWidget *>(parent())); - tabWidget->addTab(page, "File"); + tabWidget->addTab(page, "[File Browser]"); tabWidget->setCurrentIndex(tabWidget->count() - 1); - connect(page, SIGNAL(pathChanged(QString)), this, SLOT(slotFilePagePathChanged(QString))); + connect(page, SIGNAL(pathChanged(const QString &)), this, SLOT(slotFilePagePathChanged(const QString &))); } @@ -357,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; } @@ -439,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; @@ -515,8 +513,6 @@ void TextEdit::slotCopy() const { if (curTextPage() != nullptr) { curTextPage()->copy(); - } else { - curHelpPage()->copy(); } @@ -553,8 +549,6 @@ void TextEdit::slotZoomIn() const { if (curTextPage() != nullptr) { curTextPage()->zoomIn(); - } else { - curHelpPage()->zoomIn(); } } @@ -566,8 +560,6 @@ void TextEdit::slotZoomOut() const { if (curTextPage() != nullptr) { curTextPage()->zoomOut(); - } else { - curHelpPage()->zoomOut(); } } @@ -578,13 +570,17 @@ void TextEdit::slotSelectAll() const { curTextPage()->selectAll(); } -void TextEdit::slotFilePagePathChanged(const QString& path) { +void TextEdit::slotFilePagePathChanged(const QString &path) { int index = tabWidget->currentIndex(); QString mPath; - if(path.size() > 8) { - mPath = path.mid(path.size()-8,8).prepend("..."); + QFileInfo fileInfo(path); + QString tPath = fileInfo.path(); + if (path.size() > 16) { + mPath = tPath.mid(tPath.size() - 16, 16).prepend("..."); } else { - mPath = path; + mPath = tPath; } + mPath.prepend("[File Browser]: "); + mPath.append("/"); tabWidget->setTabText(index, mPath); }
\ No newline at end of file |