diff options
Diffstat (limited to 'src/ui/widgets')
-rw-r--r-- | src/ui/widgets/EditorPage.cpp | 173 | ||||
-rw-r--r-- | src/ui/widgets/EditorPage.h | 113 | ||||
-rw-r--r-- | src/ui/widgets/FilePage.cpp | 408 | ||||
-rw-r--r-- | src/ui/widgets/FilePage.h | 90 | ||||
-rw-r--r-- | src/ui/widgets/GroupKeyList.cpp | 25 | ||||
-rw-r--r-- | src/ui/widgets/GroupKeyList.h | 34 | ||||
-rw-r--r-- | src/ui/widgets/HelpPage.cpp | 75 | ||||
-rw-r--r-- | src/ui/widgets/HelpPage.h | 49 | ||||
-rw-r--r-- | src/ui/widgets/InfoBoardWidget.cpp | 299 | ||||
-rw-r--r-- | src/ui/widgets/InfoBoardWidget.h | 115 | ||||
-rw-r--r-- | src/ui/widgets/KeyList.cpp | 637 | ||||
-rw-r--r-- | src/ui/widgets/KeyList.h | 124 | ||||
-rw-r--r-- | src/ui/widgets/SignersPicker.cpp | 60 | ||||
-rw-r--r-- | src/ui/widgets/SignersPicker.h | 48 | ||||
-rw-r--r-- | src/ui/widgets/TextEdit.cpp | 270 | ||||
-rw-r--r-- | src/ui/widgets/TextEdit.h | 282 | ||||
-rw-r--r-- | src/ui/widgets/VerifyKeyDetailBox.cpp | 332 | ||||
-rw-r--r-- | src/ui/widgets/VerifyKeyDetailBox.h | 55 |
18 files changed, 2082 insertions, 1107 deletions
diff --git a/src/ui/widgets/EditorPage.cpp b/src/ui/widgets/EditorPage.cpp index beb37b96..94c98036 100644 --- a/src/ui/widgets/EditorPage.cpp +++ b/src/ui/widgets/EditorPage.cpp @@ -1,7 +1,7 @@ /** - * This file is part of GPGFrontend. + * This file is part of GpgFrontend. * - * GPGFrontend is free software: you can redistribute it and/or modify + * 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. @@ -24,84 +24,131 @@ #include "ui/widgets/EditorPage.h" +#include <boost/filesystem.hpp> #include <utility> -EditorPage::EditorPage(QString filePath, QWidget *parent) : QWidget(parent), - fullFilePath(std::move(filePath)) { - // Set the Textedit properties - textPage = new QTextEdit(); - textPage->setAcceptRichText(false); +#include "ui/function/FileReadThread.h" - // Set the layout style - mainLayout = new QVBoxLayout(); - mainLayout->setSpacing(0); - mainLayout->addWidget(textPage); - mainLayout->setContentsMargins(0, 0, 0, 0); - setLayout(mainLayout); +namespace GpgFrontend::UI { - setAttribute(Qt::WA_DeleteOnClose); - textPage->setFocus(); +EditorPage::EditorPage(QString filePath, QWidget* parent) + : QWidget(parent), fullFilePath(std::move(filePath)) { + // Set the Textedit properties + textPage = new QTextEdit(); + textPage->setAcceptRichText(false); - // Front in same width - this->setFont({"Courier"}); -} + // Set the layout style + mainLayout = new QVBoxLayout(); + mainLayout->setSpacing(0); + mainLayout->addWidget(textPage); + mainLayout->setContentsMargins(0, 0, 0, 0); + setLayout(mainLayout); -const QString &EditorPage::getFilePath() const { - return fullFilePath; -} + textPage->setFocus(); -QTextEdit *EditorPage::getTextPage() { - return textPage; + // Front in same width + this->setFont({"Courier"}); + this->setAttribute(Qt::WA_DeleteOnClose); } -void EditorPage::setFilePath(const QString &filePath) { - fullFilePath = filePath; +const QString& EditorPage::getFilePath() const { return fullFilePath; } + +QTextEdit* EditorPage::getTextPage() { return textPage; } + +void EditorPage::setFilePath(const QString& filePath) { + fullFilePath = filePath; } -void EditorPage::showNotificationWidget(QWidget *widget, const char *className) { - widget->setProperty(className, true); - mainLayout->addWidget(widget); +void EditorPage::showNotificationWidget(QWidget* widget, + const char* className) { + widget->setProperty(className, true); + mainLayout->addWidget(widget); } -void EditorPage::closeNoteByClass(const char *className) { - QList<QWidget *> widgets = findChildren<QWidget *>(); - for (QWidget *widget: widgets) { - if (widget->property(className) == true) { - widget->close(); - } +void EditorPage::closeNoteByClass(const char* className) { + QList<QWidget*> widgets = findChildren<QWidget*>(); + for (QWidget* widget : widgets) { + if (widget->property(className) == true) { + widget->close(); } + } } void EditorPage::slotFormatGpgHeader() { + QString content = textPage->toPlainText(); + + // Get positions of the gpg-headers, if they exist + int start = content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNED_BEGIN); + int startSig = + content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNATURE_BEGIN); + int endSig = content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNATURE_END); + + if (start < 0 || startSig < 0 || endSig < 0 || signMarked) { + return; + } + + signMarked = true; + + // Set the fontstyle for the header + QTextCharFormat signFormat; + signFormat.setForeground(QBrush(QColor::fromRgb(80, 80, 80))); + signFormat.setFontPointSize(9); + + // set font style for the signature + QTextCursor cursor(textPage->document()); + cursor.setPosition(startSig, QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, endSig); + cursor.setCharFormat(signFormat); + + // set the font style for the header + int headEnd = content.indexOf("\n\n", start); + cursor.setPosition(start, QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, headEnd); + cursor.setCharFormat(signFormat); +} - QString content = textPage->toPlainText(); - - // Get positions of the gpg-headers, if they exist - int start = content.indexOf(GpgConstants::PGP_SIGNED_BEGIN); - int startSig = content.indexOf(GpgConstants::PGP_SIGNATURE_BEGIN); - int endSig = content.indexOf(GpgConstants::PGP_SIGNATURE_END); - - if (start < 0 || startSig < 0 || endSig < 0 || signMarked) { - return; - } - - signMarked = true; - - // Set the fontstyle for the header - QTextCharFormat signFormat; - signFormat.setForeground(QBrush(QColor::fromRgb(80, 80, 80))); - signFormat.setFontPointSize(9); - - // set font style for the signature - QTextCursor cursor(textPage->document()); - cursor.setPosition(startSig, QTextCursor::MoveAnchor); - cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, endSig); - cursor.setCharFormat(signFormat); - - // set the font style for the header - int headEnd = content.indexOf("\n\n", start); - cursor.setPosition(start, QTextCursor::MoveAnchor); - cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, headEnd); - cursor.setCharFormat(signFormat); +void EditorPage::ReadFile() { + LOG(INFO) << "Called"; + + readDone = false; + + auto text_page = this->getTextPage(); + text_page->setReadOnly(true); + auto thread = new FileReadThread(this->fullFilePath.toStdString()); + + connect(thread, &FileReadThread::sendReadBlock, this, + &EditorPage::slotInsertText); + + connect(thread, &FileReadThread::readDone, this, [=]() { + LOG(INFO) << "Thread read done"; + text_page->document()->setModified(false); + text_page->setReadOnly(false); + }); + + connect(thread, &FileReadThread::finished, this, [=]() { + LOG(INFO) << "Thread finished"; + thread->deleteLater(); + readDone = true; + readThread = nullptr; + }); + + connect(this, &EditorPage::destroyed, [=]() { + LOG(INFO) << "RequestInterruption for readThread"; + thread->requestInterruption(); + readThread = nullptr; + }); + this->readThread = thread; + thread->start(); +} +void EditorPage::slotInsertText(const QString& text) { + this->getTextPage()->insertPlainText(text); +} +void EditorPage::PrepareToDestroy() { + if (readThread) { + readThread->requestInterruption(); + readThread = nullptr; + } } + +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/EditorPage.h b/src/ui/widgets/EditorPage.h new file mode 100644 index 00000000..a0a05dab --- /dev/null +++ b/src/ui/widgets/EditorPage.h @@ -0,0 +1,113 @@ +/** + * 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. + * + */ + +#ifndef __EDITORPAGE_H__ +#define __EDITORPAGE_H__ + +#include "gpg/GpgConstants.h" +#include "ui/GpgFrontendUI.h" + +QT_BEGIN_NAMESPACE +class QVBoxLayout; +class QHBoxLayout; +class QString; +class QLabel; +QT_END_NAMESPACE + +namespace GpgFrontend::UI { + +/** + * @brief Class for handling a single tab of the tabwidget + * + */ +class EditorPage : public QWidget { + Q_OBJECT + public: + /** + * @details Add layout and add plaintextedit + * + * @param filePath Path of the file handled in this tab + * @param parent Pointer to the parent widget + */ + explicit EditorPage(QString filePath = "", QWidget* parent = nullptr); + + /** + * @details Get the filepath of the currently activated tab. + */ + [[nodiscard]] const QString& getFilePath() const; + + /** + * @details Set filepath of currently activated tab. + * + * @param filePath The path to be set + */ + void setFilePath(const QString& filePath); + + /** + * @details Return pointer tp the textedit of the currently activated tab. + */ + QTextEdit* getTextPage(); + + /** + * @details Show additional widget at buttom of currently active tab + * + * @param widget The widget to be added + * @param className The name to handle the added widget + */ + void showNotificationWidget(QWidget* widget, const char* className); + + /** + * @details Hide all widgets with the given className + * + * @param className The classname of the widgets to hide + */ + void closeNoteByClass(const char* className); + + void ReadFile(); + + [[nodiscard]] bool ReadDone() const { return this->readDone; } + + void PrepareToDestroy(); + + private: + QTextEdit* textPage; /** The textedit of the tab */ + QVBoxLayout* mainLayout; /** The layout for the tab */ + QString fullFilePath; /** The path to the file handled in the tab */ + bool signMarked{}; /** true, if the signed header is marked, false if not */ + bool readDone = false; + QThread* readThread = nullptr; + + private slots: + + /** + * @details Format the gpg header in another font-style + */ + void slotFormatGpgHeader(); + + void slotInsertText(const QString& text); +}; + +} // namespace GpgFrontend::UI + +#endif // __EDITORPAGE_H__ diff --git a/src/ui/widgets/FilePage.cpp b/src/ui/widgets/FilePage.cpp index b9602d58..2c8df5e4 100644 --- a/src/ui/widgets/FilePage.cpp +++ b/src/ui/widgets/FilePage.cpp @@ -1,7 +1,7 @@ /** - * This file is part of GPGFrontend. + * This file is part of GpgFrontend. * - * GPGFrontend is free software: you can redistribute it and/or modify + * 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. @@ -24,244 +24,258 @@ #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->setRootIndex(dirModel->index(QDir::currentPath())); - dirTreeView->setContextMenuPolicy(Qt::CustomContextMenu); - mPath = dirModel->rootPath(); - - createPopupMenu(); - - - upLevelButton = new QPushButton(); - connect(upLevelButton, SIGNAL(clicked(bool)), this, SLOT(slotUpLevel())); - - QString buttonStyle = "QPushButton{border:none;background-color:rgba(255, 255, 255,100);}"; - - - auto upPixmap = QPixmap(":up.png"); - upPixmap = upPixmap.scaled(18, 18, Qt::KeepAspectRatio, Qt::SmoothTransformation); - QIcon upButtonIcon(upPixmap); - upLevelButton->setIcon(upButtonIcon); - upLevelButton->setIconSize(upPixmap.rect().size()); - upLevelButton->setStyleSheet(buttonStyle); - - refreshButton = new QPushButton("Refresh"); - connect(refreshButton, SIGNAL(clicked(bool)), this, SLOT(slotGoPath())); - - goPathButton = new QPushButton(); - connect(goPathButton, SIGNAL(clicked(bool)), this, SLOT(slotGoPath())); - - auto updatePixmap = QPixmap(":refresh.png"); - updatePixmap = updatePixmap.scaled(18, 18, Qt::KeepAspectRatio, Qt::SmoothTransformation); - QIcon updateButtonIcon(updatePixmap); - goPathButton->setIcon(updateButtonIcon); - goPathButton->setIconSize(updatePixmap.rect().size()); - goPathButton->setStyleSheet(buttonStyle); - - pathEdit = new QLineEdit(); - pathEdit->setText(dirModel->rootPath()); +#include <boost/filesystem.hpp> - auto *menuLayout = new QHBoxLayout(); - menuLayout->addWidget(upLevelButton); - menuLayout->setStretchFactor(upLevelButton, 1); - menuLayout->addWidget(pathEdit); - menuLayout->setStretchFactor(pathEdit, 10); - menuLayout->addWidget(goPathButton); - menuLayout->setStretchFactor(goPathButton, 1); - // menuLayout->addWidget(refreshButton); - // menuLayout->setStretchFactor(refreshButton, 1); - - auto *layout = new QVBoxLayout(); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - layout->addLayout(menuLayout); - layout->setStretchFactor(menuLayout, 1); - layout->addWidget(dirTreeView); - layout->setStretchFactor(dirTreeView, 8); - - this->setLayout(layout); - - 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); +#include "MainWindow.h" +namespace GpgFrontend::UI { + +FilePage::FilePage(QWidget* parent) : QWidget(parent) { + firstParent = parent; + LOG(INFO) << "New File Page"; + + dirModel = new QFileSystemModel(); + dirModel->setRootPath(QDir::currentPath()); + + dirTreeView = new QTreeView(); + dirTreeView->setModel(dirModel); + dirTreeView->setAnimated(true); + dirTreeView->setIndentation(20); + dirTreeView->setContextMenuPolicy(Qt::CustomContextMenu); + dirTreeView->setColumnWidth(0, 320); + dirTreeView->setRootIndex(dirModel->index(QDir::currentPath())); + mPath = boost::filesystem::path(dirModel->rootPath().toStdString()); + + createPopupMenu(); + + upLevelButton = new QPushButton(); + connect(upLevelButton, SIGNAL(clicked(bool)), this, SLOT(slotUpLevel())); + + QString buttonStyle = + "QPushButton{border:none;background-color:rgba(255, 255, 255, 0);}"; + + auto upPixmap = QPixmap(":up.png"); + upPixmap = + upPixmap.scaled(18, 18, Qt::KeepAspectRatio, Qt::SmoothTransformation); + QIcon upButtonIcon(upPixmap); + upLevelButton->setIcon(upButtonIcon); + upLevelButton->setIconSize(upPixmap.rect().size()); + upLevelButton->setStyleSheet(buttonStyle); + + refreshButton = new QPushButton(_("Refresh")); + connect(refreshButton, SIGNAL(clicked(bool)), this, SLOT(slotGoPath())); + + goPathButton = new QPushButton(); + connect(goPathButton, SIGNAL(clicked(bool)), this, SLOT(slotGoPath())); + + auto updatePixmap = QPixmap(":refresh.png"); + updatePixmap = updatePixmap.scaled(18, 18, Qt::KeepAspectRatio, + Qt::SmoothTransformation); + QIcon updateButtonIcon(updatePixmap); + goPathButton->setIcon(updateButtonIcon); + goPathButton->setIconSize(updatePixmap.rect().size()); + goPathButton->setStyleSheet(buttonStyle); + + pathEdit = new QLineEdit(); + pathEdit->setText(dirModel->rootPath()); + + auto* menuLayout = new QHBoxLayout(); + menuLayout->addWidget(upLevelButton); + menuLayout->setStretchFactor(upLevelButton, 1); + menuLayout->addWidget(pathEdit); + menuLayout->setStretchFactor(pathEdit, 10); + menuLayout->addWidget(goPathButton); + menuLayout->setStretchFactor(goPathButton, 1); + // menuLayout->addWidget(refreshButton); + // menuLayout->setStretchFactor(refreshButton, 1); + + auto* layout = new QVBoxLayout(); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + layout->addLayout(menuLayout); + layout->setStretchFactor(menuLayout, 1); + layout->addWidget(dirTreeView); + layout->setStretchFactor(dirTreeView, 8); + + this->setLayout(layout); + + 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&))); + + // refresh + slotGoPath(); } -void FilePage::fileTreeViewItemClicked(const QModelIndex &index) { - selectedPath = dirModel->fileInfo(index).absoluteFilePath(); - qDebug() << "selectedPath" << selectedPath; +void FilePage::fileTreeViewItemClicked(const QModelIndex& index) { + selectedPath = boost::filesystem::path( + dirModel->fileInfo(index).absoluteFilePath().toStdString()); + LOG(INFO) << "selected path" << selectedPath; } void FilePage::slotUpLevel() { - QModelIndex currentRoot = dirTreeView->rootIndex(); - - mPath = dirModel->fileInfo(currentRoot).absoluteFilePath(); - QDir dir(mPath); - dir.makeAbsolute(); - dir.setPath(QDir::cleanPath(dir.filePath(QStringLiteral("..")))); - mPath = dir.absolutePath(); - auto fileInfo = QFileInfo(dir.absolutePath()); - if(fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { - pathEdit->setText(mPath); - slotGoPath(); - } - qDebug() << "Current Root mPath" << mPath; - emit pathChanged(mPath); -} + QModelIndex currentRoot = dirTreeView->rootIndex(); + + mPath = boost::filesystem::path( + dirModel->fileInfo(currentRoot).absoluteFilePath().toStdString()); -void FilePage::fileTreeViewItemDoubleClicked(const QModelIndex &index) { - mPath = dirModel->fileInfo(index).absoluteFilePath(); - auto fileInfo = QFileInfo(mPath); - auto targetModelIndex = dirTreeView->model()->index(index.row(), 0, index.parent()); - if(fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { - dirTreeView->setRootIndex(targetModelIndex); - pathEdit->setText(mPath); + if (mPath.has_parent_path()) { + mPath = mPath.parent_path(); + auto fileInfo = QFileInfo(QString::fromStdString(mPath.string())); + if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { + pathEdit->setText(QString::fromStdString(mPath.string())); + slotGoPath(); } - qDebug() << "Index mPath" << mPath; - emit pathChanged(mPath); + LOG(INFO) << "Current Root mPath" << mPath; + emit pathChanged(QString::fromStdString(mPath.string())); + } } -QString FilePage::getSelected() const { - return selectedPath; +void FilePage::fileTreeViewItemDoubleClicked(const QModelIndex& index) { + mPath = boost::filesystem::path( + dirModel->fileInfo(index).absoluteFilePath().toStdString()); + auto fileInfo = QFileInfo(QString::fromStdString(mPath.string())); + auto targetModelIndex = + dirTreeView->model()->index(index.row(), 0, index.parent()); + if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { + dirTreeView->setRootIndex(targetModelIndex); + pathEdit->setText(QString::fromStdString(mPath.string())); + } + for (int i = 1; i < dirModel->columnCount(); ++i) + dirTreeView->resizeColumnToContents(i); + LOG(INFO) << "Index mPath" << mPath; + emit pathChanged(QString::fromStdString(mPath.string())); } +QString FilePage::getSelected() const { return QString::fromStdString(selectedPath.string()); } + void FilePage::slotGoPath() { - qDebug() << "getSelected" << pathEdit->text(); - auto fileInfo = QFileInfo(pathEdit->text()); - if(fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { - mPath = fileInfo.filePath(); - qDebug() << "Set Path" << mPath; - dirTreeView->setRootIndex(dirModel->index(fileInfo.filePath())); - } else { - QMessageBox::critical(this, "Error", "The path is unprivileged or unreachable."); - } - emit pathChanged(mPath); + qDebug() << "getSelected" << pathEdit->text(); + auto fileInfo = QFileInfo(pathEdit->text()); + if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { + mPath = boost::filesystem::path(fileInfo.filePath().toStdString()); + LOG(INFO) << "Set Path" << mPath; + dirTreeView->setRootIndex(dirModel->index(fileInfo.filePath())); + for (int i = 1; i < dirModel->columnCount(); ++i) + dirTreeView->resizeColumnToContents(i); + } else { + QMessageBox::critical(this, "Error", + "The path is unprivileged or unreachable."); + } + emit pathChanged(QString::fromStdString(mPath.string())); } 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); - + popUpMenu = new QMenu(); + + auto openItemAct = new QAction(_("Open"), this); + connect(openItemAct, SIGNAL(triggered()), this, SLOT(slotOpenItem())); + auto deleteItemAct = new QAction(_("Delete"), this); + connect(deleteItemAct, SIGNAL(triggered()), this, SLOT(slotDeleteItem())); + encryptItemAct = new QAction(_("Encrypt and Sign"), this); + connect(encryptItemAct, SIGNAL(triggered()), this, SLOT(slotEncryptItem())); + decryptItemAct = new QAction(_("Decrypt and Verify"), this); + connect(decryptItemAct, SIGNAL(triggered()), this, SLOT(slotDecryptItem())); + signItemAct = new QAction(_("Only Sign"), this); + connect(signItemAct, SIGNAL(triggered()), this, SLOT(slotSignItem())); + verifyItemAct = new QAction(_("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); - selectedPath = dirModel->fileInfo(index).absoluteFilePath(); - qDebug() << "Right Click" << selectedPath; - if (index.isValid()) { - QFileInfo info(selectedPath); - encryptItemAct->setEnabled(info.isFile() && (info.suffix() != "gpg" && info.suffix() != "sig")); - decryptItemAct->setEnabled(info.isFile() && info.suffix() == "gpg"); - signItemAct->setEnabled(info.isFile() && (info.suffix() != "gpg" && info.suffix() != "sig")); - verifyItemAct->setEnabled(info.isFile() && (info.suffix() == "sig" || info.suffix() == "gpg")); - - popUpMenu->exec(dirTreeView->viewport()->mapToGlobal(point)); - } +void FilePage::onCustomContextMenu(const QPoint& point) { + QModelIndex index = dirTreeView->indexAt(point); + selectedPath = boost::filesystem::path( + dirModel->fileInfo(index).absoluteFilePath().toStdString()); + LOG(INFO) << "FilePage::onCustomContextMenu Right Click" << selectedPath; + if (index.isValid()) { + QFileInfo info(QString::fromStdString(selectedPath.string())); + encryptItemAct->setEnabled( + info.isFile() && (info.suffix() != "gpg" && info.suffix() != "sig")); + decryptItemAct->setEnabled(info.isFile() && info.suffix() == "gpg"); + signItemAct->setEnabled(info.isFile() && + (info.suffix() != "gpg" && info.suffix() != "sig")); + verifyItemAct->setEnabled( + info.isFile() && (info.suffix() == "sig" || info.suffix() == "gpg")); + + 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."); - } + QFileInfo info(QString::fromStdString(selectedPath.string())); + if (info.isDir()) { + LOG(INFO) << "FilePage::slotOpenItem getSelected" + << pathEdit->text().toStdString(); + if (info.isReadable() && info.isExecutable()) { + LOG(INFO) << "FilePage::slotOpenItem Set Path" + << info.filePath().toStdString(); + dirTreeView->setRootIndex(dirModel->index(info.filePath())); } else { - auto mainWindow = qobject_cast<MainWindow *>(firstParent); - qDebug() << "Open Item" << mPath; - if (mainWindow != nullptr) - mainWindow->slotOpenFile(mPath); + QMessageBox::critical(this, "Error", + "The path is unprivileged or unreachable."); } + } else { + auto mainWindow = qobject_cast<MainWindow*>(firstParent); + LOG(INFO) << "FilePage::slotOpenItem Open Item" << selectedPath; + auto qt_path = QString::fromStdString(selectedPath.string()); + if (mainWindow != nullptr) mainWindow->slotOpenFile(qt_path); + } } void FilePage::slotDeleteItem() { - QModelIndex index = dirTreeView->currentIndex(); - QVariant data = dirTreeView->model()->data(index); + QModelIndex index = dirTreeView->currentIndex(); + QVariant data = dirTreeView->model()->data(index); - auto ret = QMessageBox::warning(this, - tr("Warning"), - tr("Are you sure you want to delete it?"), - QMessageBox::Ok | QMessageBox::Cancel); + auto ret = QMessageBox::warning(this, _("Warning"), + _("Are you sure you want to delete it?"), + QMessageBox::Ok | QMessageBox::Cancel); - if(ret == QMessageBox::Cancel) - return; + if (ret == QMessageBox::Cancel) return; - qDebug() << "Delete Item" << data.toString(); + qDebug() << "Delete Item" << data.toString(); - if(!dirModel->remove(index)){ - QMessageBox::critical(this, - tr("Error"), - tr("Unable to delete the file or folder.")); - } + if (!dirModel->remove(index)) { + QMessageBox::critical(this, _("Error"), + _("Unable to delete the file or folder.")); + } } void FilePage::slotEncryptItem() { - auto mainWindow = qobject_cast<MainWindow *>(firstParent); - if(mainWindow != nullptr) - mainWindow->slotFileEncryptSign(); + 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(); + 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(); + 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(); + auto mainWindow = qobject_cast<MainWindow*>(firstParent); + if (mainWindow != nullptr) mainWindow->slotFileVerify(); } -void FilePage::keyPressEvent(QKeyEvent *event) { - qDebug() << "Key Press" << event->key(); - if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { - slotGoPath(); - } +void FilePage::keyPressEvent(QKeyEvent* event) { + qDebug() << "Key Press" << event->key(); + if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { + slotGoPath(); + } } + +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/FilePage.h b/src/ui/widgets/FilePage.h new file mode 100644 index 00000000..31be81f3 --- /dev/null +++ b/src/ui/widgets/FilePage.h @@ -0,0 +1,90 @@ +/** + * 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. + * + */ + +#ifndef GPGFRONTEND_FILEPAGE_H +#define GPGFRONTEND_FILEPAGE_H + +#include <boost/filesystem.hpp> + +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +class FilePage : public QWidget { + Q_OBJECT + public: + explicit FilePage(QWidget* parent = nullptr); + + [[nodiscard]] QString getSelected() const; + + void createPopupMenu(); + + signals: + void pathChanged(const QString& path); + + private slots: + + void fileTreeViewItemClicked(const QModelIndex& index); + void fileTreeViewItemDoubleClicked(const QModelIndex& index); + + void slotUpLevel(); + void slotGoPath(); + + void slotOpenItem(); + void slotDeleteItem(); + void slotEncryptItem(); + void slotDecryptItem(); + void slotSignItem(); + void slotVerifyItem(); + + void onCustomContextMenu(const QPoint& point); + + protected: + void keyPressEvent(QKeyEvent* event) override; + + private: + QFileSystemModel* dirModel; + QTreeView* dirTreeView; + QLineEdit* pathEdit; + + // using boost path + boost::filesystem::path mPath; + boost::filesystem::path selectedPath; + + QPushButton* upLevelButton; + QPushButton* goPathButton; + QPushButton* refreshButton; + + QMenu* popUpMenu{}; + QAction* encryptItemAct{}; + QAction* decryptItemAct{}; + QAction* signItemAct{}; + QAction* verifyItemAct{}; + + QWidget* firstParent; +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_FILEPAGE_H diff --git a/src/ui/widgets/GroupKeyList.cpp b/src/ui/widgets/GroupKeyList.cpp new file mode 100644 index 00000000..efba4428 --- /dev/null +++ b/src/ui/widgets/GroupKeyList.cpp @@ -0,0 +1,25 @@ +/** + * 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 "GroupKeyList.h" diff --git a/src/ui/widgets/GroupKeyList.h b/src/ui/widgets/GroupKeyList.h new file mode 100644 index 00000000..163c7126 --- /dev/null +++ b/src/ui/widgets/GroupKeyList.h @@ -0,0 +1,34 @@ +/** + * 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. + * + */ + +#ifndef GPGFRONTEND_GROUPKEYLIST_H +#define GPGFRONTEND_GROUPKEYLIST_H + +#include "ui/GpgFrontendUI.h" + +class GroupKeyList : public QWidget { + Q_OBJECT +}; + +#endif // GPGFRONTEND_GROUPKEYLIST_H diff --git a/src/ui/widgets/HelpPage.cpp b/src/ui/widgets/HelpPage.cpp index e018da81..7b1e86c0 100644 --- a/src/ui/widgets/HelpPage.cpp +++ b/src/ui/widgets/HelpPage.cpp @@ -1,7 +1,7 @@ /** - * This file is part of GPGFrontend. + * This file is part of GpgFrontend. * - * GPGFrontend is free software: you can redistribute it and/or modify + * 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. @@ -26,25 +26,24 @@ #include <utility> -HelpPage::HelpPage(const QString &path, QWidget *parent) : - QWidget(parent) { +namespace GpgFrontend::UI { - browser = new QTextBrowser(); - auto *mainLayout = new QVBoxLayout(); - mainLayout->setSpacing(0); - mainLayout->addWidget(browser); - mainLayout->setContentsMargins(0, 0, 0, 0); - setLayout(mainLayout); - - connect(browser, SIGNAL(anchorClicked(QUrl)), this, SLOT(slotOpenUrl(QUrl))); - browser->setOpenLinks(false); - browser->setSource(localizedHelp(QUrl(path))); - browser->setFocus(); +HelpPage::HelpPage(const QString& path, QWidget* parent) : QWidget(parent) { + browser = new QTextBrowser(); + auto* mainLayout = new QVBoxLayout(); + mainLayout->setSpacing(0); + mainLayout->addWidget(browser); + mainLayout->setContentsMargins(0, 0, 0, 0); + setLayout(mainLayout); + connect(browser, SIGNAL(anchorClicked(QUrl)), this, SLOT(slotOpenUrl(QUrl))); + browser->setOpenLinks(false); + browser->setSource(localizedHelp(QUrl(path))); + browser->setFocus(); } -void HelpPage::slotOpenUrl(const QUrl &url) { - browser->setSource(localizedHelp(url)); +void HelpPage::slotOpenUrl(const QUrl& url) { + browser->setSource(localizedHelp(url)); }; /** @@ -55,29 +54,29 @@ void HelpPage::slotOpenUrl(const QUrl &url) { * @param url * @return */ -QUrl HelpPage::localizedHelp(const QUrl &url) { - QString path = url.toLocalFile(); - QString filename = path.mid(path.lastIndexOf("/") + 1); - QString filepath = path.left(path.lastIndexOf("/") + 1); - QStringList fileparts = filename.split("."); - - //QSettings settings; - QString lang = QSettings().value("int/lang", QLocale::system().name()).toString(); - if (lang.isEmpty()) { - lang = QLocale::system().name(); - } +QUrl HelpPage::localizedHelp(const QUrl& url) { + QString path = url.toLocalFile(); + QString filename = path.mid(path.lastIndexOf("/") + 1); + QString filepath = path.left(path.lastIndexOf("/") + 1); + QStringList fileparts = filename.split("."); - fileparts.insert(1, lang); - QString langfile = filepath + fileparts.join("."); + // QSettings settings; + QString lang = + QSettings().value("int/lang", QLocale::system().name()).toString(); + if (lang.isEmpty()) { + lang = QLocale::system().name(); + } - if (QFile(QUrl(langfile).toLocalFile()).exists()) { - return langfile; - } else { - return path; - } + fileparts.insert(1, lang); + QString langfile = filepath + fileparts.join("."); + if (QFile(QUrl(langfile).toLocalFile()).exists()) { + return langfile; + } else { + return path; + } } -QTextBrowser *HelpPage::getBrowser() { - return browser; -} +QTextBrowser* HelpPage::getBrowser() { return browser; } + +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/HelpPage.h b/src/ui/widgets/HelpPage.h new file mode 100644 index 00000000..25490557 --- /dev/null +++ b/src/ui/widgets/HelpPage.h @@ -0,0 +1,49 @@ +/* + * helppage.h + * + * Copyright 2008 gpg4usb-team <[email protected]> + * + * This file is part of gpg4usb. + * + * Gpg4usb 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. + * + * Gpg4usb 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 gpg4usb. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef HELPPAGE_H +#define HELPPAGE_H + +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +class HelpPage : public QWidget { + Q_OBJECT + public: + explicit HelpPage(const QString& path, QWidget* parent = nullptr); + + QTextBrowser* getBrowser(); + + signals: + + public slots: + + void slotOpenUrl(const QUrl& url); + + private: + QTextBrowser* browser; /** The textbrowser of the tab */ + QUrl localizedHelp(const QUrl& path); +}; + +} // namespace GpgFrontend::UI + +#endif // HELPPAGE_H diff --git a/src/ui/widgets/InfoBoardWidget.cpp b/src/ui/widgets/InfoBoardWidget.cpp index b9372c59..cd469422 100644 --- a/src/ui/widgets/InfoBoardWidget.cpp +++ b/src/ui/widgets/InfoBoardWidget.cpp @@ -1,7 +1,7 @@ /** - * This file is part of GPGFrontend. + * This file is part of GpgFrontend. * - * GPGFrontend is free software: you can redistribute it and/or modify + * 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. @@ -24,170 +24,193 @@ #include "ui/widgets/InfoBoardWidget.h" -InfoBoardWidget::InfoBoardWidget(QWidget *parent, GpgME::GpgContext *ctx, KeyList *keyList) : - QWidget(parent), mCtx(ctx), mKeyList(keyList), appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", - QSettings::IniFormat) { - - infoBoard = new QTextEdit(this); - infoBoard->setReadOnly(true); - infoBoard->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); - infoBoard->setMinimumWidth(480); - infoBoard->setContentsMargins(0, 0, 0, 0); - - connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotReset())); - - importFromKeyserverAct = new QAction(tr("Import missing key from Keyserver"), this); - connect(importFromKeyserverAct, SIGNAL(triggered()), this, SLOT(slotImportFromKeyserver())); - - detailMenu = new QMenu(this); - detailMenu->addAction(importFromKeyserverAct); - importFromKeyserverAct->setVisible(false); - - auto *actionButtonMenu = new QWidget(); - actionButtonMenu->setContentsMargins(0, 0, 0, 0); - actionButtonMenu->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); - actionButtonMenu->setFixedHeight(36); - - actionButtonLayout = new QHBoxLayout(); - actionButtonLayout->setContentsMargins(5, 5, 5, 5); - actionButtonLayout->setSpacing(0); - actionButtonMenu->setLayout(actionButtonLayout); - - auto label = new QLabel(tr("Optional Actions")); - label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - label->setContentsMargins(0, 0, 0, 0); - - actionButtonLayout->addWidget(label); - actionButtonLayout->addStretch(); - - - QFrame *line; - line = new QFrame(this); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Sunken); - line->setContentsMargins(0, 0, 0, 0); - - auto *notificationWidgetLayout = new QVBoxLayout(this); - notificationWidgetLayout->setContentsMargins(0, 0, 0, 0); - notificationWidgetLayout->setSpacing(0); - - notificationWidgetLayout->addWidget(infoBoard); - notificationWidgetLayout->setStretchFactor(infoBoard, 10); - notificationWidgetLayout->addWidget(actionButtonMenu); - notificationWidgetLayout->setStretchFactor(actionButtonMenu, 1); - notificationWidgetLayout->addWidget(line); - notificationWidgetLayout->setStretchFactor(line, 1); - notificationWidgetLayout->addStretch(0); - this->setLayout(notificationWidgetLayout); +#include "ui/settings/GlobalSettingStation.h" + +namespace GpgFrontend::UI { + +InfoBoardWidget::InfoBoardWidget(QWidget* parent, KeyList* keyList) + : QWidget(parent), mKeyList(keyList) { + infoBoard = new QTextEdit(this); + infoBoard->setReadOnly(true); + infoBoard->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + infoBoard->setMinimumWidth(480); + infoBoard->setContentsMargins(0, 0, 0, 0); + + importFromKeyserverAct = + new QAction(_("Import missing key from Keyserver"), this); + connect(importFromKeyserverAct, SIGNAL(triggered()), this, + SLOT(slotImportFromKeyserver())); + + detailMenu = new QMenu(this); + detailMenu->addAction(importFromKeyserverAct); + importFromKeyserverAct->setVisible(false); + + auto* actionButtonMenu = new QWidget(); + actionButtonMenu->setContentsMargins(0, 0, 0, 0); + actionButtonMenu->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); + actionButtonMenu->setFixedHeight(36); + + actionButtonLayout = new QHBoxLayout(); + actionButtonLayout->setContentsMargins(5, 5, 5, 5); + actionButtonLayout->setSpacing(0); + actionButtonMenu->setLayout(actionButtonLayout); + + auto label = new QLabel(_("Optional Actions")); + label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + label->setContentsMargins(0, 0, 0, 0); + + actionButtonLayout->addWidget(label); + actionButtonLayout->addStretch(); + + QFrame* line; + line = new QFrame(this); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + line->setContentsMargins(0, 0, 0, 0); + + auto* notificationWidgetLayout = new QVBoxLayout(this); + notificationWidgetLayout->setContentsMargins(0, 0, 0, 0); + notificationWidgetLayout->setSpacing(0); + + notificationWidgetLayout->addWidget(infoBoard); + notificationWidgetLayout->setStretchFactor(infoBoard, 10); + notificationWidgetLayout->addWidget(actionButtonMenu); + notificationWidgetLayout->setStretchFactor(actionButtonMenu, 1); + notificationWidgetLayout->addWidget(line); + notificationWidgetLayout->setStretchFactor(line, 1); + notificationWidgetLayout->addStretch(0); + this->setLayout(notificationWidgetLayout); + + // set default size + infoBoard->resize(480, 120); + resize(480, 120); } void InfoBoardWidget::slotImportFromKeyserver() { - auto *importDialog = new KeyServerImportDialog(mCtx, mKeyList, false, this); - importDialog->slotImport(*keysNotInList); + auto* importDialog = new KeyServerImportDialog(false, this); + auto key_ids = std::make_unique<KeyIdArgsList>(); + for (const auto& key_id : *keysNotInList) { + key_ids->push_back(key_id.toStdString()); + } + importDialog->slotImport(key_ids); } -void InfoBoardWidget::setInfoBoard(const QString &text, InfoBoardStatus verifyLabelStatus) { - QString color; - infoBoard->clear(); - switch (verifyLabelStatus) { - case INFO_ERROR_OK: - color = "#008000"; - break; - case INFO_ERROR_WARN: - color = "#FF8C00"; - break; - case INFO_ERROR_CRITICAL: - color = "#DC143C"; - break; - default: - break; - } - infoBoard->append(text); - - infoBoard->setAutoFillBackground(true); - QPalette status = infoBoard->palette(); - status.setColor(QPalette::Text, color); - infoBoard->setPalette(status); - auto infoBoardFontSize = settings.value("informationBoard/fontSize", 10).toInt(); - infoBoard->setFont(QFont("Times", infoBoardFontSize)); +void InfoBoardWidget::setInfoBoard(const QString& text, + InfoBoardStatus verifyLabelStatus) { + QString color; + infoBoard->clear(); + switch (verifyLabelStatus) { + case INFO_ERROR_OK: + color = "#008000"; + break; + case INFO_ERROR_WARN: + color = "#FF8C00"; + break; + case INFO_ERROR_CRITICAL: + color = "#DC143C"; + break; + default: + break; + } + infoBoard->append(text); + + infoBoard->setAutoFillBackground(true); + QPalette status = infoBoard->palette(); + status.setColor(QPalette::Text, color); + infoBoard->setPalette(status); + + auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); + + // info board font size + auto info_font_size = 10; + try { + info_font_size = settings.lookup("window.info_font_size"); + if (info_font_size < 9 || info_font_size > 18) info_font_size = 10; + } catch (...) { + LOG(ERROR) << _("Setting Operation Error") << _("info_font_size"); + } + infoBoard->setFont(QFont("Times", info_font_size)); } -void InfoBoardWidget::slotRefresh(const QString &text, InfoBoardStatus status) { - infoBoard->clear(); - setInfoBoard(text, status); - infoBoard->verticalScrollBar()->setValue(0); +void InfoBoardWidget::slotRefresh(const QString& text, InfoBoardStatus status) { + infoBoard->clear(); + setInfoBoard(text, status); + infoBoard->verticalScrollBar()->setValue(0); } -void InfoBoardWidget::associateTextEdit(QTextEdit *edit) { - if (mTextPage != nullptr) - disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset())); - this->mTextPage = edit; - connect(edit, SIGNAL(textChanged()), this, SLOT(slotReset())); +void InfoBoardWidget::associateTextEdit(QTextEdit* edit) { + if (mTextPage != nullptr) + disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset())); + this->mTextPage = edit; + connect(edit, SIGNAL(textChanged()), this, SLOT(slotReset())); } -void InfoBoardWidget::associateFileTreeView(FilePage *treeView) { -// if (mFileTreeView != nullptr) -// disconnect(mFileTreeView, &FilePage::pathChanged, this, &InfoBoardWidget::slotReset); -// this->mFileTreeView = treeView; -// connect(treeView, &FilePage::pathChanged, this, &InfoBoardWidget::slotReset); +void InfoBoardWidget::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())); - connect(mTabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(slotReset())); - } - - mTextPage = nullptr; - mFileTreeView = nullptr; - mTabWidget = tab; - connect(tab, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset())); - connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(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())); + connect(mTabWidget, SIGNAL(tabCloseRequested(int)), this, + SLOT(slotReset())); + } + + mTextPage = nullptr; + mFileTreeView = nullptr; + mTabWidget = tab; + connect(tab, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset())); + connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(slotReset())); } - -void InfoBoardWidget::addOptionalAction(const QString &name, const std::function<void()> &action) { - auto actionButton = new QPushButton(name); - auto layout = new QHBoxLayout(); - layout->setContentsMargins(5, 0, 5, 0); - infoBoard->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - // set margin from surroundings - layout->addWidget(actionButton); - actionButtonLayout->addLayout(layout); - connect(actionButton, &QPushButton::clicked, this, [=]() { - action(); - }); +void InfoBoardWidget::addOptionalAction(const QString& name, + const std::function<void()>& action) { + auto actionButton = new QPushButton(name); + auto layout = new QHBoxLayout(); + layout->setContentsMargins(5, 0, 5, 0); + infoBoard->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + // set margin from surroundings + layout->addWidget(actionButton); + actionButtonLayout->addLayout(layout); + connect(actionButton, &QPushButton::clicked, this, [=]() { action(); }); } /** * Delete All item in actionButtonLayout */ void InfoBoardWidget::resetOptionActionsMenu() { - deleteWidgetsInLayout(actionButtonLayout, 2); + deleteWidgetsInLayout(actionButtonLayout, 2); } void InfoBoardWidget::slotReset() { - this->infoBoard->clear(); - resetOptionActionsMenu(); + this->infoBoard->clear(); + resetOptionActionsMenu(); } /** * Try Delete all widget from target layout * @param layout target layout */ -void InfoBoardWidget::deleteWidgetsInLayout(QLayout *layout, int start_index) { - QLayoutItem *item; - while ((item = layout->layout()->takeAt(start_index)) != nullptr) { - layout->removeItem(item); - if (item->layout() != nullptr) - deleteWidgetsInLayout(item->layout()); - else if (item->widget() != nullptr) - delete item->widget(); - delete item; - } +void InfoBoardWidget::deleteWidgetsInLayout(QLayout* layout, int start_index) { + QLayoutItem* item; + while ((item = layout->layout()->takeAt(start_index)) != nullptr) { + layout->removeItem(item); + if (item->layout() != nullptr) + deleteWidgetsInLayout(item->layout()); + else if (item->widget() != nullptr) + delete item->widget(); + delete item; + } } + +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/InfoBoardWidget.h b/src/ui/widgets/InfoBoardWidget.h new file mode 100644 index 00000000..1a13e1a2 --- /dev/null +++ b/src/ui/widgets/InfoBoardWidget.h @@ -0,0 +1,115 @@ +/** + * 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. + * + */ + +#ifndef __VERIFYNOTIFICATION_H__ +#define __VERIFYNOTIFICATION_H__ + +#include "EditorPage.h" +#include "FilePage.h" +#include "gpg/result_analyse/VerifyResultAnalyse.h" +#include "ui/VerifyDetailsDialog.h" + +namespace GpgFrontend::UI { +/** + * @details Enumeration for the status of Verifylabel + */ +typedef enum { + INFO_ERROR_OK = 0, + INFO_ERROR_WARN = 1, + INFO_ERROR_CRITICAL = 2, + INFO_ERROR_NEUTRAL = 3, +} InfoBoardStatus; + +/** + * @brief Class for handling the verifylabel shown at buttom of a textedit-page + */ +class InfoBoardWidget : public QWidget { + Q_OBJECT + public: + /** + * @brief + * + * @param ctx The GPGme-Context + * @param parent The parent widget + */ + explicit InfoBoardWidget(QWidget* parent, KeyList* keyList); + + void associateTextEdit(QTextEdit* edit); + + void associateFileTreeView(FilePage* treeView); + + void associateTabWidget(QTabWidget* tab); + + void addOptionalAction(const QString& name, + const std::function<void()>& action); + + void resetOptionActionsMenu(); + + /** + * @details Set the text and background-color of verify notification. + * + * @param text The text to be set. + * @param verifyLabelStatus The status of label to set the specified color. + */ + void setInfoBoard(const QString& text, InfoBoardStatus verifyLabelStatus); + + QStringList* keysNotInList; /** List with keys, which are in signature but not + in keylist */ + + public slots: + + /** + * @details Import the keys contained in keysNotInList from keyserver + * + */ + void slotImportFromKeyserver(); + + void slotReset(); + + /** + * @details Refresh the contents of dialog. + */ + void slotRefresh(const QString& text, InfoBoardStatus status); + + private: + QMenu* detailMenu; /** Menu for te Button in verfiyNotification */ + QAction* importFromKeyserverAct; /** Action for importing keys from keyserver + which are notin keylist */ + QTextEdit* infoBoard; + KeyList* mKeyList; /** Table holding the keys */ + + 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; + + void deleteWidgetsInLayout(QLayout* layout, int start_index = 0); +}; + +} // namespace GpgFrontend::UI + +#endif // __VERIFYNOTIFICATION_H__
\ No newline at end of file diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp index 9c9c6763..f9f33d78 100644 --- a/src/ui/widgets/KeyList.cpp +++ b/src/ui/widgets/KeyList.cpp @@ -1,7 +1,7 @@ /** - * This file is part of GPGFrontend. + * This file is part of GpgFrontend. * - * GPGFrontend is free software: you can redistribute it and/or modify + * 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. @@ -26,394 +26,385 @@ #include <utility> -KeyList::KeyList(GpgME::GpgContext *ctx, - KeyListRow::KeyType selectType, - KeyListColumn::InfoType infoType, - QWidget *parent) - : QWidget(parent), mSelectType(selectType), mInfoType(infoType), appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat) { - mCtx = ctx; - - - mKeyList = new QTableWidget(this); - mKeyList->setColumnCount(7); - mKeyList->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); - mKeyList->verticalHeader()->hide(); - mKeyList->setShowGrid(false); - mKeyList->sortByColumn(2, Qt::AscendingOrder); - mKeyList->setSelectionBehavior(QAbstractItemView::SelectRows); - mKeyList->setSelectionMode(QAbstractItemView::SingleSelection); - - // tableitems not editable - mKeyList->setEditTriggers(QAbstractItemView::NoEditTriggers); - // no focus (rectangle around tableitems) - // may be it should focus on whole row - mKeyList->setFocusPolicy(Qt::NoFocus); - - mKeyList->setAlternatingRowColors(true); - - // Hidden Column For Purpose - if (!(mInfoType & KeyListColumn::TYPE)) { - mKeyList->setColumnHidden(1, true); - } - if (!(mInfoType & KeyListColumn::NAME)) { - mKeyList->setColumnHidden(2, true); - } - if (!(mInfoType & KeyListColumn::EmailAddress)) { - mKeyList->setColumnHidden(3, true); - } - if (!(mInfoType & KeyListColumn::Usage)) { - mKeyList->setColumnHidden(4, true); - } - if (!(mInfoType & KeyListColumn::Validity)) { - mKeyList->setColumnHidden(5, true); - } - if (!(mInfoType & KeyListColumn::FingerPrint)) { - mKeyList->setColumnHidden(6, true); - } +#include "gpg/function/GpgKeyGetter.h" +#include "ui/SignalStation.h" + +namespace GpgFrontend::UI { + +KeyList::KeyList(KeyListRow::KeyType selectType, + KeyListColumn::InfoType infoType, QWidget* parent) + : QWidget(parent), + appPath(qApp->applicationDirPath()), + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat), + mSelectType(selectType), + mInfoType(infoType) { + mKeyList = new QTableWidget(this); + mKeyList->setColumnCount(7); + mKeyList->horizontalHeader()->setSectionResizeMode( + QHeaderView::ResizeToContents); + mKeyList->verticalHeader()->hide(); + mKeyList->setShowGrid(false); + mKeyList->sortByColumn(2, Qt::AscendingOrder); + mKeyList->setSelectionBehavior(QAbstractItemView::SelectRows); + mKeyList->setSelectionMode(QAbstractItemView::SingleSelection); + + // table items not editable + mKeyList->setEditTriggers(QAbstractItemView::NoEditTriggers); + // no focus (rectangle around table items) + // maybe it should focus on whole row + mKeyList->setFocusPolicy(Qt::NoFocus); + + mKeyList->setAlternatingRowColors(true); + + // Hidden Column For Purpose + if (!(mInfoType & KeyListColumn::TYPE)) { + mKeyList->setColumnHidden(1, true); + } + if (!(mInfoType & KeyListColumn::NAME)) { + mKeyList->setColumnHidden(2, true); + } + if (!(mInfoType & KeyListColumn::EmailAddress)) { + mKeyList->setColumnHidden(3, true); + } + if (!(mInfoType & KeyListColumn::Usage)) { + mKeyList->setColumnHidden(4, true); + } + if (!(mInfoType & KeyListColumn::Validity)) { + mKeyList->setColumnHidden(5, true); + } + if (!(mInfoType & KeyListColumn::FingerPrint)) { + mKeyList->setColumnHidden(6, true); + } + + QStringList labels; + labels << _("Select") << _("Type") << _("Name") << _("Email Address") + << _("Usage") << _("Validity") << _("Finger Print"); + + mKeyList->setHorizontalHeaderLabels(labels); + mKeyList->horizontalHeader()->setStretchLastSection(false); + + auto* layout = new QVBoxLayout; + layout->addWidget(mKeyList); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(3); + setLayout(layout); + + popupMenu = new QMenu(this); + + // register key database refresh signal + connect(SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()), this, + SLOT(slotRefresh())); + connect(mKeyList, SIGNAL(doubleClicked(const QModelIndex&)), this, + SLOT(slotDoubleClicked(const QModelIndex&))); + + setAcceptDrops(true); + slotRefresh(); +} - QStringList labels; - labels << tr("Select") << tr("Type") << tr("Name") << tr("Email Address") - << tr("Usage") << tr("Validity") << tr("Finger Print"); +void KeyList::slotRefresh() { + LOG(INFO) << "KeyList::slotRefresh Called"; - mKeyList->setHorizontalHeaderLabels(labels); - mKeyList->horizontalHeader()->setStretchLastSection(false); + auto keyList = getChecked(); + // while filling the table, sort enabled causes errors + mKeyList->setSortingEnabled(false); + mKeyList->clearContents(); - auto *layout = new QVBoxLayout; - layout->addWidget(mKeyList); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(3); - setLayout(layout); + auto keys = GpgKeyGetter::GetInstance().FetchKey(); - popupMenu = new QMenu(this); + auto it = keys->begin(); - connect(mKeyList, SIGNAL(doubleClicked(const QModelIndex &)), - this, SLOT(slotDoubleClicked(const QModelIndex &))); - connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotRefresh())); - setAcceptDrops(true); - slotRefresh(); -} + int row_count = 0; -void KeyList::slotRefresh() { - QStringList *keyList; - keyList = getChecked(); - // while filling the table, sort enabled causes errors - mKeyList->setSortingEnabled(false); - mKeyList->clearContents(); - - GpgKeyList keys = mCtx->getKeys(); - - auto it = keys.begin(); - - int row_count = 0; - - while (it != keys.end()) { - if (mFilter != nullptr) { - if (!mFilter(*it)) { - it = keys.erase(it); - continue; - } - } - if (!excluded_key_ids.isEmpty()) { - - auto iterator = std::find_if(excluded_key_ids.begin(), excluded_key_ids.end(), - [it](const auto &key_id) -> bool { - if (it->id == key_id) return true; - else return false; - }); - - if (iterator != excluded_key_ids.end()) { - it = keys.erase(it); - continue; - } - } - if (mSelectType == KeyListRow::ONLY_SECRET_KEY && !it->is_private_key) { - it = keys.erase(it); - continue; - } - row_count++; - it++; + while (it != keys->end()) { + if (mFilter != nullptr) { + if (!mFilter(*it)) { + it = keys->erase(it); + continue; + } + } + if (!excluded_key_ids.empty()) { + auto iterator = + std::find_if(excluded_key_ids.begin(), excluded_key_ids.end(), + [it](const auto& key_id) -> bool { + if (it->id() == key_id) + return true; + else + return false; + }); + + if (iterator != excluded_key_ids.end()) { + it = keys->erase(it); + continue; + } + } + if (mSelectType == KeyListRow::ONLY_SECRET_KEY && !it->is_private_key()) { + it = keys->erase(it); + continue; + } + row_count++; + it++; + } + + mKeyList->setRowCount(row_count); + + int row_index = 0; + it = keys->begin(); + buffered_keys.clear(); + + while (it != keys->end()) { + buffered_keys.push_back(GpgKeyGetter::GetInstance().GetKey(it->id())); + + auto* tmp0 = new QTableWidgetItem(QString::number(row_index)); + tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | + Qt::ItemIsSelectable); + tmp0->setTextAlignment(Qt::AlignCenter); + tmp0->setCheckState(Qt::Unchecked); + mKeyList->setItem(row_index, 0, tmp0); + + QString type_str; + QTextStream type_steam(&type_str); + if (it->is_private_key()) { + type_steam << "pub/sec"; + } else { + type_steam << "pub"; } - mKeyList->setRowCount(row_count); - - int row_index = 0; - it = keys.begin(); - buffered_keys.clear(); - - while (it != keys.end()) { - - buffered_keys.push_back(*it); - - auto *tmp0 = new QTableWidgetItem(QString::number(row_index)); - tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); - tmp0->setTextAlignment(Qt::AlignCenter); - tmp0->setCheckState(Qt::Unchecked); - mKeyList->setItem(row_index, 0, tmp0); - - QString type_str; - QTextStream type_steam(&type_str); - if (it->is_private_key) { - type_steam << "pub/sec"; - } else { - type_steam << "pub"; - } - - if (it->is_private_key && !it->has_master_key) { - type_steam << "#"; - } - auto *tmp1 = new QTableWidgetItem(type_str); - mKeyList->setItem(row_index, 1, tmp1); - - auto *tmp2 = new QTableWidgetItem(it->name); - tmp2->setToolTip(it->name); - mKeyList->setItem(row_index, 2, tmp2); - auto *tmp3 = new QTableWidgetItem(it->email); - tmp3->setToolTip(it->email); - mKeyList->setItem(row_index, 3, tmp3); - - QString usage; - QTextStream usage_steam(&usage); - - if (GpgME::GpgContext::checkIfKeyCanCert(*it)) - usage_steam << "C"; - if (GpgME::GpgContext::checkIfKeyCanEncr(*it)) - usage_steam << "E"; - if (GpgME::GpgContext::checkIfKeyCanSign(*it)) - usage_steam << "S"; - if (GpgME::GpgContext::checkIfKeyCanAuth(*it)) - usage_steam << "A"; - - auto *temp_usage = new QTableWidgetItem(usage); - temp_usage->setTextAlignment(Qt::AlignCenter); - mKeyList->setItem(row_index, 4, temp_usage); - - auto *temp_validity = new QTableWidgetItem(it->owner_trust); - temp_validity->setTextAlignment(Qt::AlignCenter); - mKeyList->setItem(row_index, 5, temp_validity); - - auto *temp_fpr = new QTableWidgetItem(it->fpr); - temp_fpr->setTextAlignment(Qt::AlignCenter); - mKeyList->setItem(row_index, 6, temp_fpr); - - // strike out expired keys - if (it->expired || it->revoked) { - QFont strike = tmp2->font(); - strike.setStrikeOut(true); - tmp0->setFont(strike); - temp_usage->setFont(strike); - temp_fpr->setFont(strike); - temp_validity->setFont(strike); - tmp1->setFont(strike); - tmp2->setFont(strike); - tmp3->setFont(strike); - } - - it++; - ++row_index; + if (it->is_private_key() && !it->has_master_key()) { + type_steam << "#"; + } + auto* tmp1 = new QTableWidgetItem(type_str); + mKeyList->setItem(row_index, 1, tmp1); + + auto* tmp2 = new QTableWidgetItem(QString::fromStdString(it->name())); + mKeyList->setItem(row_index, 2, tmp2); + auto* tmp3 = new QTableWidgetItem(QString::fromStdString(it->email())); + mKeyList->setItem(row_index, 3, tmp3); + + QString usage; + QTextStream usage_steam(&usage); + + if (it->CanCertActual()) usage_steam << "C"; + if (it->CanEncrActual()) usage_steam << "E"; + if (it->CanSignActual()) usage_steam << "S"; + if (it->CanAuthActual()) usage_steam << "A"; + + auto* temp_usage = new QTableWidgetItem(usage); + temp_usage->setTextAlignment(Qt::AlignCenter); + mKeyList->setItem(row_index, 4, temp_usage); + + auto* temp_validity = + new QTableWidgetItem(QString::fromStdString(it->owner_trust())); + temp_validity->setTextAlignment(Qt::AlignCenter); + mKeyList->setItem(row_index, 5, temp_validity); + + auto* temp_fpr = new QTableWidgetItem(QString::fromStdString(it->fpr())); + temp_fpr->setTextAlignment(Qt::AlignCenter); + mKeyList->setItem(row_index, 6, temp_fpr); + + // strike out expired keys + if (it->expired() || it->revoked()) { + QFont strike = tmp2->font(); + strike.setStrikeOut(true); + tmp0->setFont(strike); + temp_usage->setFont(strike); + temp_fpr->setFont(strike); + temp_validity->setFont(strike); + tmp1->setFont(strike); + tmp2->setFont(strike); + tmp3->setFont(strike); } + it++; + ++row_index; + } - setChecked(keyList); + setChecked(keyList); } -QStringList *KeyList::getChecked() { - auto *ret = new QStringList(); - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (mKeyList->item(i, 0)->checkState() == Qt::Checked) { - *ret << buffered_keys[i].id; - } +KeyIdArgsListPtr KeyList::getChecked() { + auto ret = std::make_unique<KeyIdArgsList>(); + for (int i = 0; i < mKeyList->rowCount(); i++) { + if (mKeyList->item(i, 0)->checkState() == Qt::Checked) { + ret->push_back(buffered_keys[i].id()); } - return ret; + } + return ret; } -QStringList *KeyList::getAllPrivateKeys() { - auto *ret = new QStringList(); - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (mKeyList->item(i, 1) && buffered_keys[i].is_private_key) { - *ret << buffered_keys[i].id; - } +KeyIdArgsListPtr KeyList::getAllPrivateKeys() { + auto ret = std::make_unique<KeyIdArgsList>(); + for (int i = 0; i < mKeyList->rowCount(); i++) { + if (mKeyList->item(i, 1) && buffered_keys[i].is_private_key()) { + ret->push_back(buffered_keys[i].id()); } - return ret; + } + return ret; } -QStringList *KeyList::getPrivateChecked() { - auto *ret = new QStringList(); - for (int i = 0; i < mKeyList->rowCount(); i++) { - if ((mKeyList->item(i, 0)->checkState() == Qt::Checked) && (mKeyList->item(i, 1))) { - *ret << buffered_keys[i].id; - } +KeyIdArgsListPtr KeyList::getPrivateChecked() { + auto ret = std::make_unique<KeyIdArgsList>(); + for (int i = 0; i < mKeyList->rowCount(); i++) { + if ((mKeyList->item(i, 0)->checkState() == Qt::Checked) && + (mKeyList->item(i, 1))) { + ret->push_back(buffered_keys[i].id()); } - return ret; + } + return ret; } -void KeyList::setChecked(QStringList *keyIds) { - if (!keyIds->isEmpty()) { - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (keyIds->contains(buffered_keys[i].id)) { - mKeyList->item(i, 0)->setCheckState(Qt::Checked); - } - } +void KeyList::setChecked(const KeyIdArgsListPtr& keyIds) { + if (!keyIds->empty()) { + for (int i = 0; i < mKeyList->rowCount(); i++) { + if (std::find(keyIds->begin(), keyIds->end(), buffered_keys[i].id()) != + keyIds->end()) { + mKeyList->item(i, 0)->setCheckState(Qt::Checked); + } } + } } -QStringList *KeyList::getSelected() { - auto *ret = new QStringList(); +KeyIdArgsListPtr KeyList::getSelected() { + auto ret = std::make_unique<KeyIdArgsList>(); - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (mKeyList->item(i, 0)->isSelected() == 1) { - *ret << buffered_keys[i].id; - } + for (int i = 0; i < mKeyList->rowCount(); i++) { + if (mKeyList->item(i, 0)->isSelected() == 1) { + ret->push_back(buffered_keys[i].id()); } - return ret; + } + return ret; } [[maybe_unused]] bool KeyList::containsPrivateKeys() { - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (mKeyList->item(i, 1)) { - return true; - } + for (int i = 0; i < mKeyList->rowCount(); i++) { + if (mKeyList->item(i, 1)) { + return true; } - return false; + } + return false; } void KeyList::setColumnWidth(int row, int size) { - mKeyList->setColumnWidth(row, size); -} - -void KeyList::contextMenuEvent(QContextMenuEvent *event) { - if (mKeyList->selectedItems().length() > 0) { - popupMenu->exec(event->globalPos()); - } - + mKeyList->setColumnWidth(row, size); } -void KeyList::addSeparator() { - popupMenu->addSeparator(); +void KeyList::contextMenuEvent(QContextMenuEvent* event) { + if (mKeyList->selectedItems().length() > 0) { + popupMenu->exec(event->globalPos()); + } } -void KeyList::addMenuAction(QAction *act) { - popupMenu->addAction(act); -} - -void KeyList::dropEvent(QDropEvent *event) { +void KeyList::addSeparator() { popupMenu->addSeparator(); } - auto *dialog = new QDialog(); +void KeyList::addMenuAction(QAction* act) { popupMenu->addAction(act); } - dialog->setWindowTitle(tr("Import Keys")); - QLabel *label; - label = new QLabel( - tr("You've dropped something on the table.\n GpgFrontend will now try to import key(s).") + "\n"); +void KeyList::dropEvent(QDropEvent* event) { + auto* dialog = new QDialog(); - // "always import keys"-CheckBox - auto *checkBox = new QCheckBox(tr("Always import without bothering.")); - if (settings.value("general/confirmImportKeys").toBool()) checkBox->setCheckState(Qt::Unchecked); + dialog->setWindowTitle(_("Import Keys")); + QLabel* label; + label = + new QLabel(QString(_("You've dropped something on the table.")) + "\n " + + _("GpgFrontend " + "will now try to import key(s).") + + "\n"); - // Buttons for ok and cancel - auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject())); + // "always import keys"-CheckBox + auto* checkBox = new QCheckBox(_("Always import without bothering.")); + if (settings.value("general/confirmImportKeys").toBool()) + checkBox->setCheckState(Qt::Unchecked); - auto *vbox = new QVBoxLayout(); - vbox->addWidget(label); - vbox->addWidget(checkBox); - vbox->addWidget(buttonBox); + // Buttons for ok and cancel + auto* buttonBox = + new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject())); - dialog->setLayout(vbox); + auto* vbox = new QVBoxLayout(); + vbox->addWidget(label); + vbox->addWidget(checkBox); + vbox->addWidget(buttonBox); - if (settings.value("general/confirmImportKeys", Qt::Checked).toBool()) { - dialog->exec(); - if (dialog->result() == QDialog::Rejected) { - return; - } - if (checkBox->isChecked()) { - settings.setValue("general/confirmImportKeys", false); - } else { - settings.setValue("general/confirmImportKeys", true); + dialog->setLayout(vbox); - } + if (settings.value("general/confirmImportKeys", Qt::Checked).toBool()) { + dialog->exec(); + if (dialog->result() == QDialog::Rejected) { + return; } - - if (event->mimeData()->hasUrls()) { - for (const QUrl &tmp : event->mimeData()->urls()) { - QFile file; - file.setFileName(tmp.toLocalFile()); - if (!file.open(QIODevice::ReadOnly)) { - qDebug() << tr("Couldn't Open File: ") + tmp.toString(); - } - QByteArray inBuffer = file.readAll(); - this->importKeys(inBuffer); - file.close(); - } + if (checkBox->isChecked()) { + settings.setValue("general/confirmImportKeys", false); } else { - QByteArray inBuffer(event->mimeData()->text().toUtf8()); - this->importKeys(inBuffer); + settings.setValue("general/confirmImportKeys", true); } + } + + if (event->mimeData()->hasUrls()) { + for (const QUrl& tmp : event->mimeData()->urls()) { + QFile file; + file.setFileName(tmp.toLocalFile()); + if (!file.open(QIODevice::ReadOnly)) { + LOG(INFO) << _("Couldn't Open File") << ":" + << tmp.toString().toStdString(); + } + QByteArray inBuffer = file.readAll(); + this->importKeys(inBuffer); + file.close(); + } + } else { + QByteArray inBuffer(event->mimeData()->text().toUtf8()); + this->importKeys(inBuffer); + } } -void KeyList::dragEnterEvent(QDragEnterEvent *event) { - event->acceptProposedAction(); +void KeyList::dragEnterEvent(QDragEnterEvent* event) { + event->acceptProposedAction(); } /** set background color for Keys and put them to top * */ -[[maybe_unused]] void KeyList::markKeys(QStringList *keyIds) { - foreach(QString id, *keyIds) { - qDebug() << "marked: " << id; - } -} - -void KeyList::importKeys(QByteArray inBuffer) { - GpgImportInformation result = mCtx->importKey(std::move(inBuffer)); - new KeyImportDetailDialog(mCtx, result, false, this); +[[maybe_unused]] void KeyList::markKeys(QStringList* keyIds) { + foreach (QString id, *keyIds) { qDebug() << "marked: " << id; } } -void KeyList::getCheckedKeys(QVector<GpgKey> &keys) { - keys.clear(); - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (mKeyList->item(i, 0)->checkState() == Qt::Checked) { - keys.push_back(buffered_keys[i]); - } - } +void KeyList::importKeys(const QByteArray& inBuffer) { + auto std_buffer = std::make_unique<ByteArray>(inBuffer.toStdString()); + GpgImportInformation result = + GpgKeyImportExportor::GetInstance().ImportKey(std::move(std_buffer)); + new KeyImportDetailDialog(result, false, this); } -void KeyList::setExcludeKeys(std::initializer_list<QString> key_ids) { - excluded_key_ids.clear(); - for (auto &key_id : key_ids) { - excluded_key_ids.push_back(key_id); - } +void KeyList::setExcludeKeys(std::initializer_list<std::string> key_ids) { + excluded_key_ids.clear(); + for (auto& key_id : key_ids) { + excluded_key_ids.push_back(key_id); + } } -void KeyList::setFilter(std::function<bool(const GpgKey &)> filter) { - this->mFilter = std::move(filter); +void KeyList::setFilter(std::function<bool(const GpgKey&)> filter) { + this->mFilter = std::move(filter); } -void KeyList::slotDoubleClicked(const QModelIndex &index) { - if (mAction != nullptr) { - const auto key = mCtx->getKeyById(buffered_keys[index.row()].id); - mAction(key, this); - } - +void KeyList::slotDoubleClicked(const QModelIndex& index) { + if (mAction != nullptr) { + const auto key = + GpgKeyGetter::GetInstance().GetKey(buffered_keys[index.row()].id()); + mAction(key, this); + } } -void KeyList::setDoubleClickedAction(std::function<void(const GpgKey &, QWidget *)> action) { - this->mAction = std::move(action); +void KeyList::setDoubleClickedAction( + std::function<void(const GpgKey&, QWidget*)> action) { + this->mAction = std::move(action); } -void KeyList::getPrivateCheckedKeys(QVector<GpgKey> &keys) { - keys.clear(); - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (mKeyList->item(i, 0)->checkState() == Qt::Checked && buffered_keys[i].is_private_key) { - keys.push_back(buffered_keys[i]); - } +std::string KeyList::getSelectedKey() { + for (int i = 0; i < mKeyList->rowCount(); i++) { + if (mKeyList->item(i, 0)->isSelected() == 1) { + return buffered_keys[i].id(); } + } + return {}; } -GpgKey KeyList::getSelectedKey() { - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (mKeyList->item(i, 0)->isSelected() == 1) { - return buffered_keys[i]; - } - } - return GpgKey(); -} +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/KeyList.h b/src/ui/widgets/KeyList.h new file mode 100644 index 00000000..524b2bd0 --- /dev/null +++ b/src/ui/widgets/KeyList.h @@ -0,0 +1,124 @@ +/** + * 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. + * + */ + +#ifndef __KEYLIST_H__ +#define __KEYLIST_H__ + +#include "gpg/GpgContext.h" +#include "ui/KeyImportDetailDialog.h" +namespace GpgFrontend::UI { + +struct KeyListRow { + using KeyType = unsigned int; + + static const KeyType SECRET_OR_PUBLIC_KEY = 0; + static const KeyType ONLY_SECRET_KEY = 1; +}; + +struct KeyListColumn { + using InfoType = unsigned int; + + static constexpr InfoType ALL = ~0; + static constexpr InfoType TYPE = 1 << 0; + static constexpr InfoType NAME = 1 << 1; + static constexpr InfoType EmailAddress = 1 << 2; + static constexpr InfoType Usage = 1 << 3; + static constexpr InfoType Validity = 1 << 4; + static constexpr InfoType FingerPrint = 1 << 5; +}; + +class KeyList : public QWidget { + Q_OBJECT + + public: + explicit KeyList( + KeyListRow::KeyType selectType = KeyListRow::SECRET_OR_PUBLIC_KEY, + KeyListColumn::InfoType infoType = KeyListColumn::ALL, + QWidget* parent = nullptr); + + void setExcludeKeys(std::initializer_list<std::string> key_ids); + + void setFilter(std::function<bool(const GpgKey&)> filter); + + void setDoubleClickedAction( + std::function<void(const GpgKey&, QWidget*)> action); + + void setColumnWidth(int row, int size); + + void addMenuAction(QAction* act); + + void addSeparator(); + + KeyIdArgsListPtr getChecked(); + + KeyIdArgsListPtr getPrivateChecked(); + + KeyIdArgsListPtr getAllPrivateKeys(); + + void setChecked(const KeyIdArgsListPtr& keyIds); + + KeyIdArgsListPtr getSelected(); + + std::string getSelectedKey(); + + [[maybe_unused]] static void markKeys(QStringList* keyIds); + + [[maybe_unused]] bool containsPrivateKeys(); + + public slots: + + void slotRefresh(); + + private: + void importKeys(const QByteArray& inBuffer); + + QString appPath; + QSettings settings; + + QTableWidget* mKeyList; + QMenu* popupMenu; + QNetworkAccessManager* qnam{}; + std::vector<GpgKey> buffered_keys; + KeyListRow::KeyType mSelectType; + KeyListColumn::InfoType mInfoType; + std::vector<std::string> excluded_key_ids; + + std::function<bool(const GpgKey&)> mFilter = nullptr; + std::function<void(const GpgKey&, QWidget*)> mAction = nullptr; + + private slots: + + void slotDoubleClicked(const QModelIndex& index); + + protected: + void contextMenuEvent(QContextMenuEvent* event) override; + + void dragEnterEvent(QDragEnterEvent* event) override; + + void dropEvent(QDropEvent* event) override; +}; + +} // namespace GpgFrontend::UI + +#endif // __KEYLIST_H__ diff --git a/src/ui/widgets/SignersPicker.cpp b/src/ui/widgets/SignersPicker.cpp index 00df5fdd..3e4b3bb5 100644 --- a/src/ui/widgets/SignersPicker.cpp +++ b/src/ui/widgets/SignersPicker.cpp @@ -1,7 +1,7 @@ /** - * This file is part of GPGFrontend. + * This file is part of GpgFrontend. * - * GPGFrontend is free software: you can redistribute it and/or modify + * 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. @@ -24,36 +24,46 @@ #include "ui/widgets/SignersPicker.h" -SignersPicker::SignersPicker(GpgME::GpgContext *ctx, QWidget *parent) : mCtx(ctx), QDialog(parent) { - auto confirmButton = new QPushButton(tr("Confirm")); - connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(accept())); +namespace GpgFrontend::UI { - /*Setup KeyList*/ - mKeyList = new KeyList(mCtx, KeyListRow::ONLY_SECRET_KEY, - KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage); +SignersPicker::SignersPicker(QWidget* parent) : QDialog(parent) { + auto confirmButton = new QPushButton(_("Confirm")); + connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(accept())); - mKeyList->setFilter([](const GpgKey &key) -> bool { - if (!GpgME::GpgContext::checkIfKeyCanSign(key)) return false; - else return true; - }); + /*Setup KeyList*/ + mKeyList = new KeyList( + KeyListRow::ONLY_SECRET_KEY, + KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage); - mKeyList->slotRefresh(); + mKeyList->setFilter([](const GpgKey& key) -> bool { + if (!key.CanSignActual()) + return false; + else + return true; + }); - auto *vbox2 = new QVBoxLayout(); - vbox2->addWidget(new QLabel("Select Signer(s): ")); - vbox2->addWidget(mKeyList); - vbox2->addWidget(confirmButton); - vbox2->addStretch(0); - setLayout(vbox2); + mKeyList->slotRefresh(); - this->setModal(true); - this->setWindowTitle("Signers Picker"); - this->setMinimumWidth(480); - this->show(); + auto* vbox2 = new QVBoxLayout(); + vbox2->addWidget(new QLabel(QString(_("Select Signer(s)")) + ": ")); + vbox2->addWidget(mKeyList); + vbox2->addWidget(new QLabel( + _("Selecting Nothing will eventually use default key to sign."))); + vbox2->addWidget(confirmButton); + vbox2->addStretch(0); + setLayout(vbox2); + this->setWindowFlags(Qt::Window | Qt::WindowTitleHint | + Qt::CustomizeWindowHint); + this->setModal(true); + this->setWindowTitle("Signers Picker"); + this->setMinimumWidth(480); + this->show(); } -void SignersPicker::getCheckedSigners(QVector<GpgKey> &keys) { - mKeyList->getPrivateCheckedKeys(keys); +GpgFrontend::KeyIdArgsListPtr SignersPicker::getCheckedSigners() { + return mKeyList->getPrivateChecked(); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/SignersPicker.h b/src/ui/widgets/SignersPicker.h new file mode 100644 index 00000000..055b6ef6 --- /dev/null +++ b/src/ui/widgets/SignersPicker.h @@ -0,0 +1,48 @@ +/** + * 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. + * + */ + +#ifndef GPGFRONTEND_ZH_CN_TS_SIGNERSPIRCKER_H +#define GPGFRONTEND_ZH_CN_TS_SIGNERSPIRCKER_H + +#include "GpgFrontend.h" +#include "gpg/GpgContext.h" +#include "ui/widgets/KeyList.h" + +namespace GpgFrontend::UI { + +class SignersPicker : public QDialog { + Q_OBJECT + + public: + explicit SignersPicker(QWidget* parent = nullptr); + + GpgFrontend::KeyIdArgsListPtr getCheckedSigners(); + + private: + KeyList* mKeyList; +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_ZH_CN_TS_SIGNERSPIRCKER_H diff --git a/src/ui/widgets/TextEdit.cpp b/src/ui/widgets/TextEdit.cpp index eab0f799..8d4ea4a0 100644 --- a/src/ui/widgets/TextEdit.cpp +++ b/src/ui/widgets/TextEdit.cpp @@ -1,7 +1,7 @@ /** - * This file is part of GPGFrontend. + * This file is part of GpgFrontend. * - * GPGFrontend is free software: you can redistribute it and/or modify + * 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. @@ -24,14 +24,18 @@ #include "ui/widgets/TextEdit.h" -TextEdit::TextEdit(QWidget *parent) : QWidget(parent) { +#include <boost/format.hpp> + +namespace GpgFrontend::UI { + +TextEdit::TextEdit(QWidget* parent) : QWidget(parent) { countPage = 0; tabWidget = new QTabWidget(this); tabWidget->setMovable(true); tabWidget->setTabsClosable(true); tabWidget->setDocumentMode(true); - auto *layout = new QVBoxLayout; + auto* layout = new QVBoxLayout; layout->addWidget(tabWidget); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); @@ -39,20 +43,14 @@ TextEdit::TextEdit(QWidget *parent) : QWidget(parent) { connect(tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(removeTab(int))); - connect(this, &TextEdit::insertTargetTextPage, this, - &TextEdit::slotInsertTargetTextPage); - connect(this, &TextEdit::readTargetTextPageStart, this, - &TextEdit::slotReadTargetTextPageStart); - connect(this, &TextEdit::readTargetTextPageDone, this, - &TextEdit::slotReadTargetTextPageDone); slotNewTab(); setAcceptDrops(false); } void TextEdit::slotNewTab() { - QString header = tr("untitled") + QString::number(++countPage) + ".txt"; + QString header = _("untitled") + QString::number(++countPage) + ".txt"; - auto *page = new EditorPage(); + auto* page = new EditorPage(); tabWidget->addTab(page, header); tabWidget->setCurrentIndex(tabWidget->count() - 1); page->getTextPage()->setFocus(); @@ -60,131 +58,59 @@ void TextEdit::slotNewTab() { this, SLOT(slotShowModified())); } -void TextEdit::slotNewHelpTab(const QString &title, const QString &path) const { - - auto *page = new HelpPage(path); +void TextEdit::slotNewHelpTab(const QString& title, const QString& path) const { + auto* page = new HelpPage(path); tabWidget->addTab(page, title); tabWidget->setCurrentIndex(tabWidget->count() - 1); } void TextEdit::slotNewFileTab() const { - - auto *page = new FilePage(qobject_cast<QWidget *>(parent())); + auto* page = new FilePage(qobject_cast<QWidget*>(parent())); tabWidget->addTab(page, "[Browser]"); tabWidget->setCurrentIndex(tabWidget->count() - 1); - connect(page, SIGNAL(pathChanged(const QString &)), this, - SLOT(slotFilePagePathChanged(const QString &))); + connect(page, SIGNAL(pathChanged(const QString&)), this, + SLOT(slotFilePagePathChanged(const QString&))); } -void TextEdit::slotOpenFile(QString &path) { - +void TextEdit::slotOpenFile(QString& path) { QFile file(path); - - if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { - auto *page = new EditorPage(path); - pagesHashMap.insert(page->uuid, page); + LOG(INFO) << " path" << path.toStdString(); + auto result = file.open(QIODevice::ReadOnly | QIODevice::Text); + if (result) { + auto* page = new EditorPage(path); QApplication::setOverrideCursor(Qt::WaitCursor); - - auto read_thread = QThread::create([&, page]() { - QFile targetFile(path); - - if (targetFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - emit readTargetTextPageStart(page->uuid); - QTextStream in(&targetFile); - QString readText; - qDebug() << "Thread Start Reading" << path; - while (!((readText = in.read(8192)).isEmpty())) { - emit insertTargetTextPage(page->uuid, readText); - QThread::msleep(64); - } - targetFile.close(); - emit readTargetTextPageDone(page->uuid); - qDebug() << "Thread End Reading" << path; - } - }); - - 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(); - - file.close(); - read_thread->start(); - + page->ReadFile(); } else { - QMessageBox::warning( - this, tr("Warning"), - tr("Cannot read file %1:\n%2.").arg(path).arg(file.errorString())); + QMessageBox::warning(this, _("Warning"), + (boost::format(_("Cannot read file %1%:\n%2%.")) % + path.toStdString() % file.errorString().toStdString()) + .str() + .c_str()); } -} -void TextEdit::slotInsertTargetTextPage(const QString &pagePtr, - const QString &text) { - auto it = pagesHashMap.find(pagePtr); - if (it != pagesHashMap.end()) { - auto *taregtTextPage = qobject_cast<EditorPage *>(it.value()); - if (taregtTextPage != nullptr) { - taregtTextPage->getTextPage()->insertPlainText(text); - taregtTextPage->getTextPage()->document()->setModified(false); - } - } -} - -void TextEdit::slotReadTargetTextPageStart(const QString &pagePtr) { - auto it = pagesHashMap.find(pagePtr); - if (it != pagesHashMap.end()) { - auto *taregtTextPage = qobject_cast<EditorPage *>(it.value()); - if (taregtTextPage != nullptr) { - qDebug() << "Setting TextEdit At Start" << pagePtr; - taregtTextPage->getTextPage()->setReadOnly(true); - auto index = tabWidget->indexOf(taregtTextPage); - if (index != -1) { - tabWidget->setTabText( - index, "[Loading] " + strippedName(taregtTextPage->getFilePath())); - } - } - } -} - -void TextEdit::slotReadTargetTextPageDone(const QString &pagePtr) { - auto it = pagesHashMap.find(pagePtr); - if (it != pagesHashMap.end()) { - auto *taregtTextPage = qobject_cast<EditorPage *>(it.value()); - if (taregtTextPage != nullptr) { - qDebug() << "Setting TextEdit At End" << pagePtr; - taregtTextPage->getTextPage()->setReadOnly(false); - auto index = tabWidget->indexOf(taregtTextPage); - if (index != -1) { - tabWidget->setTabText(index, - strippedName(taregtTextPage->getFilePath())); - } - taregtTextPage->getTextPage()->document()->setModified(false); - connect(taregtTextPage->getTextPage()->document(), - SIGNAL(modificationChanged(bool)), this, - SLOT(slotShowModified())); - } - } + file.close(); + LOG(INFO) << "done"; } void TextEdit::slotOpen() { QStringList fileNames = - QFileDialog::getOpenFileNames(this, tr("Open file"), QDir::currentPath()); - for (const auto &fileName : fileNames) { + QFileDialog::getOpenFileNames(this, _("Open file"), QDir::currentPath()); + for (const auto& fileName : fileNames) { if (!fileName.isEmpty()) { QFile file(fileName); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { - auto *page = new EditorPage(fileName); + 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(); + QTextDocument* document = page->getTextPage()->document(); document->setModified(false); tabWidget->addTab(page, strippedName(fileName)); @@ -197,10 +123,12 @@ void TextEdit::slotOpen() { // enableAction(true) file.close(); } else { - QMessageBox::warning(this, tr("Warning"), - tr("Cannot read file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); + QMessageBox::warning( + this, _("Warning"), + (boost::format(_("Cannot read file %1%:\n%2%.")) % + fileName.toStdString() % file.errorString().toStdString()) + .str() + .c_str()); } } } @@ -222,7 +150,7 @@ void TextEdit::slotSave() { } } -bool TextEdit::saveFile(const QString &fileName) { +bool TextEdit::saveFile(const QString& fileName) { if (fileName.isEmpty()) { return false; } @@ -230,44 +158,47 @@ bool TextEdit::saveFile(const QString &fileName) { QFile file(fileName); if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { - EditorPage *page = slotCurPageTextEdit(); + EditorPage* page = slotCurPageTextEdit(); QTextStream outputStream(&file); QApplication::setOverrideCursor(Qt::WaitCursor); outputStream << page->getTextPage()->toPlainText(); QApplication::restoreOverrideCursor(); - QTextDocument *document = page->getTextPage()->document(); + QTextDocument* document = page->getTextPage()->document(); document->setModified(false); int curIndex = tabWidget->currentIndex(); tabWidget->setTabText(curIndex, strippedName(fileName)); page->setFilePath(fileName); - // statusBar()->showMessage(tr("File saved"), 2000); + // statusBar()->showMessage(_("File saved"), 2000); file.close(); return true; } else { QMessageBox::warning( - this, tr("File"), - tr("Cannot write file %1:\n%2.").arg(fileName).arg(file.errorString())); + this, _("Warning"), + (boost::format(_("Cannot read file %1%:\n%2%.")) % + fileName.toStdString() % file.errorString().toStdString()) + .str() + .c_str()); return false; } } bool TextEdit::slotSaveAs() { - if (tabWidget->count() == 0 || slotCurPageTextEdit() == 0) { + if (tabWidget->count() == 0 || slotCurPageTextEdit() == nullptr) { return true; } - EditorPage *page = slotCurPageTextEdit(); + EditorPage* page = slotCurPageTextEdit(); QString path; - if (page->getFilePath() != "") { + if (!page->getFilePath().isEmpty()) { path = page->getFilePath(); } else { path = tabWidget->tabText(tabWidget->currentIndex()).remove(0, 2); } - QString fileName = QFileDialog::getSaveFileName(this, tr("Save file"), path); + QString fileName = QFileDialog::getSaveFileName(this, _("Save file"), path); return saveFile(fileName); } @@ -312,34 +243,35 @@ void TextEdit::removeTab(int index) { * If it returns false, the close event should be aborted. */ bool TextEdit::maybeSaveCurrentTab(bool askToSave) { - - EditorPage *page = slotCurPageTextEdit(); + EditorPage* page = slotCurPageTextEdit(); // if this page is no textedit, there should be nothing to save if (page == nullptr) { return true; } - QTextDocument *document = page->getTextPage()->document(); + QTextDocument* document = page->getTextPage()->document(); - if (document->isModified()) { + if (page->ReadDone() && document->isModified()) { QMessageBox::StandardButton result = QMessageBox::Cancel; // write title of tab to docname and remove the leading * QString docname = tabWidget->tabText(tabWidget->currentIndex()); docname.remove(0, 2); - const QString &filePath = page->getFilePath(); + const QString& filePath = page->getFilePath(); if (askToSave) { result = QMessageBox::warning( - this, tr("Unsaved document"), - tr("The document \"%1\" has been modified. Do you want to " - "save your changes?<br/>") + this, _("Unsaved document"), + QString(_("The document \"%1\" has been modified. Do you want to " + "save your changes?")) .arg(docname) + - tr("<b>Note:</b> If you don't save these files, all changes are " - "lost.<br/>"), + "<br/><b>" + _("Note:") + "</b>" + + _("If you don't save these files, all changes are " + "lost.") + + "<br/>", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); } if ((result == QMessageBox::Save) || (!askToSave)) { - if (filePath == "") { + if (filePath.isEmpty()) { // QString docname = tabWidget->tabText(tabWidget->currentIndex()); // docname.remove(0,2); return slotSaveAs(); @@ -352,6 +284,9 @@ bool TextEdit::maybeSaveCurrentTab(bool askToSave) { return false; } } + + // destroy + page->PrepareToDestroy(); return true; } @@ -381,7 +316,7 @@ bool TextEdit::maybeSaveAnyTab() { if (unsavedDocs.size() > 1) { QHashIterator<int, QString> i(unsavedDocs); - QuitDialog *dialog; + QuitDialog* dialog; dialog = new QuitDialog(this, unsavedDocs); int result = dialog->exec(); @@ -394,28 +329,24 @@ bool TextEdit::maybeSaveAnyTab() { return false; } } else { - bool allsaved = true; + bool all_saved = true; QList<int> tabIdsToSave = dialog->getTabIdsToSave(); - foreach (int tabId, tabIdsToSave) { + for (const auto& tabId : tabIdsToSave) { tabWidget->setCurrentIndex(tabId); if (!maybeSaveCurrentTab(false)) { - allsaved = false; + all_saved = false; } } - if (allsaved) { - return true; - } else { - return false; - } + return all_saved; } } // code should never reach this statement return false; } -QTextEdit *TextEdit::curTextPage() const { - auto *curTextPage = qobject_cast<EditorPage *>(tabWidget->currentWidget()); +QTextEdit* TextEdit::curTextPage() const { + auto* curTextPage = qobject_cast<EditorPage*>(tabWidget->currentWidget()); if (curTextPage != nullptr) { return curTextPage->getTextPage(); } else { @@ -423,8 +354,8 @@ QTextEdit *TextEdit::curTextPage() const { } } -FilePage *TextEdit::curFilePage() const { - auto *curFilePage = qobject_cast<FilePage *>(tabWidget->currentWidget()); +FilePage* TextEdit::curFilePage() const { + auto* curFilePage = qobject_cast<FilePage*>(tabWidget->currentWidget()); if (curFilePage != nullptr) { return curFilePage; } else { @@ -434,13 +365,13 @@ FilePage *TextEdit::curFilePage() const { int TextEdit::tabCount() const { return tabWidget->count(); } -EditorPage *TextEdit::slotCurPageTextEdit() const { - auto *curPage = qobject_cast<EditorPage *>(tabWidget->currentWidget()); +EditorPage* TextEdit::slotCurPageTextEdit() const { + auto* curPage = qobject_cast<EditorPage*>(tabWidget->currentWidget()); return curPage; } -FilePage *TextEdit::slotCurPageFileTreeView() const { - auto *curPage = qobject_cast<FilePage *>(tabWidget->currentWidget()); +FilePage* TextEdit::slotCurPageFileTreeView() const { + auto* curPage = qobject_cast<FilePage*>(tabWidget->currentWidget()); return curPage; } @@ -466,7 +397,7 @@ void TextEdit::slotQuote() const { cursor.endEditBlock(); } -void TextEdit::slotFillTextEditWithText(const QString &text) const { +void TextEdit::slotFillTextEditWithText(const QString& text) const { QTextCursor cursor(curTextPage()->document()); cursor.beginEditBlock(); this->curTextPage()->selectAll(); @@ -474,12 +405,15 @@ void TextEdit::slotFillTextEditWithText(const QString &text) const { cursor.endEditBlock(); } -void TextEdit::loadFile(const QString &fileName) { +void TextEdit::loadFile(const QString& fileName) { QFile file(fileName); if (!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning( - this, tr("Application"), - tr("Cannot read file %1:\n%2.").arg(fileName).arg(file.errorString())); + this, _("Warning"), + (boost::format(_("Cannot read file %1%:\n%2%.")) % + fileName.toStdString() % file.errorString().toStdString()) + .str() + .c_str()); return; } QTextStream in(&file); @@ -489,10 +423,10 @@ void TextEdit::loadFile(const QString &fileName) { slotCurPageTextEdit()->setFilePath(fileName); tabWidget->setTabText(tabWidget->currentIndex(), strippedName(fileName)); file.close(); - // statusBar()->showMessage(tr("File loaded"), 2000); + // statusBar()->showMessage(_("File loaded"), 2000); } -QString TextEdit::strippedName(const QString &fullFileName) { +QString TextEdit::strippedName(const QString& fullFileName) { return QFileInfo(fullFileName).fileName(); } @@ -502,19 +436,19 @@ void TextEdit::slotPrint() { } #ifndef QT_NO_PRINTER - QTextDocument *document; + QTextDocument* document; if (curTextPage() != nullptr) { document = curTextPage()->document(); } QPrinter printer; - auto *dlg = new QPrintDialog(&printer, this); + auto* dlg = new QPrintDialog(&printer, this); if (dlg->exec() != QDialog::Accepted) { return; } document->print(&printer); - // statusBar()->showMessage(tr("Ready"), 2000); + // statusBar()->showMessage(_("Ready"), 2000); #endif } @@ -549,16 +483,19 @@ void TextEdit::slotSwitchTabDown() const { * return a hash of tabindexes and title of unsaved tabs */ QHash<int, QString> TextEdit::unsavedDocuments() const { - QHash<int, QString> unsavedDocs; // this list could be used to implement gedit - // like "unsaved changed"-dialog + QHash<int, QString> unsavedDocs; // this list could be used to implement + // gedit like "unsaved changed"-dialog for (int i = 0; i < tabWidget->count(); i++) { - auto *ep = qobject_cast<EditorPage *>(tabWidget->widget(i)); - if (ep != nullptr && ep->getTextPage()->document()->isModified()) { - QString docname = tabWidget->tabText(i); + auto* ep = qobject_cast<EditorPage*>(tabWidget->widget(i)); + if (ep != nullptr && ep->ReadDone() && + ep->getTextPage()->document()->isModified()) { + QString doc_name = tabWidget->tabText(i); + LOG(INFO) << "unsaved" << doc_name.toStdString(); + // remove * before name of modified doc - docname.remove(0, 2); - unsavedDocs.insert(i, docname); + doc_name.remove(0, 2); + unsavedDocs.insert(i, doc_name); } } return unsavedDocs; @@ -633,7 +570,7 @@ void TextEdit::slotSelectAll() const { curTextPage()->selectAll(); } -void TextEdit::slotFilePagePathChanged(const QString &path) { +void TextEdit::slotFilePagePathChanged(const QString& path) const { int index = tabWidget->currentIndex(); QString mPath; QFileInfo fileInfo(path); @@ -644,6 +581,7 @@ void TextEdit::slotFilePagePathChanged(const QString &path) { mPath = tPath; } mPath.prepend("[Browser] "); - mPath.append("/"); tabWidget->setTabText(index, mPath); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/TextEdit.h b/src/ui/widgets/TextEdit.h new file mode 100644 index 00000000..3cff74e7 --- /dev/null +++ b/src/ui/widgets/TextEdit.h @@ -0,0 +1,282 @@ +/** + * 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. + * + */ + +#ifndef __TEXTEDIT_H__ +#define __TEXTEDIT_H__ + +#include "ui/QuitDialog.h" +#include "ui/widgets/EditorPage.h" +#include "ui/widgets/FilePage.h" +#include "ui/widgets/HelpPage.h" + +namespace GpgFrontend::UI { +/** + * @brief TextEdit class + */ +class TextEdit : public QWidget { + Q_OBJECT + public: + /** + * @brief + */ + TextEdit(QWidget* parent); + + /** + * @details Load the content of file into the current textpage + * + * @param fileName QString containing the filename to load + * @return nothing + */ + void loadFile(const QString& fileName); + + /** + * @details Checks if there are unsaved documents in any tab, + * which may need to be saved. Call this function before + * closing the programme or all tabs. + * @return \li false, if the close event should be aborted. + * \li true, otherwise + */ + bool maybeSaveAnyTab(); + + [[nodiscard]] int tabCount() const; + + /** + * @details textpage of the currently activated tab + * @return \li reference to QTextEdit if tab has one + * \li 0 otherwise (e.g. if helppage) + */ + [[nodiscard]] QTextEdit* curTextPage() const; + + [[nodiscard]] FilePage* curFilePage() const; + + /** + * @details List of currently unsaved tabs. + * @returns QHash<int, QString> Hash of tabindexes and title of unsaved tabs. + */ + [[nodiscard]] QHash<int, QString> unsavedDocuments() const; + + QTabWidget* tabWidget; /** Widget containing the tabs of the editor */ + + public slots: + + /** + * @details Return pointer to the currently activated text edit tab page. + * + */ + EditorPage* slotCurPageTextEdit() const; + + /** + * @details Return pointer to the currently activated file treeview tab page. + * + */ + FilePage* slotCurPageFileTreeView() const; + + /** + * @details Insert a ">" at the begining of every line of current textedit. + */ + void slotQuote() const; + + /** + * @details replace the text of currently active textedit with given text. + * @param text to fill on. + */ + void slotFillTextEditWithText(const QString& text) const; + + /** + * @details Saves the content of the current tab, if it has a filepath + * otherwise it calls saveAs for the current tab + */ + void slotSave(); + + /** + * @details Opens a savefiledialog and calls saveFile with the choosen + * filename. + * + * @return Return the return value of the savefile method + */ + bool slotSaveAs(); + + /** + * @details Show an OpenFileDoalog and open the file in a new tab. + * Shows an error dialog, if the open fails. + * Set the focus to the tab of the opened file. + */ + void slotOpen(); + + /** + * @details Open a print-dialog for the current tab + */ + void slotPrint(); + + /** + * @details Adds a new tab with the title "untitled"+countpage+".txt" + * Sets the focus to the new tab. Increase Tab-Count by + * one + */ + void slotNewTab(); + + /** + * @details Adds a new tab with opening file by path + */ + void slotOpenFile(QString& path); + + /** + * @details Adds a new tab with the given title and opens given html file. + * Increase Tab-Count by one + * @param title title for the tab + * @param path path for html file to show + */ + void slotNewHelpTab(const QString& title, const QString& path) const; + + /** + * New File Tab to do file operation + */ + void slotNewFileTab() const; + + /** + * @details put a * in front of current tabs title, if current textedit is + * modified + */ + void slotShowModified() const; + + /** + * @details close the current tab and decrease TabWidget->count by \a 1 + * + */ + void slotCloseTab(); + + /** + * @details Switch to the next tab. + * + */ + void slotSwitchTabUp() const; + + /** + * @details Switch to the previous tab. + * + */ + void slotSwitchTabDown() const; + + private: + /** + * @details return just a filename stripped of a whole path + * + * @param a filename path + * @return QString containing the filename + */ + static QString strippedName(const QString& fullFileName); + + /** + * @brief + * + * @param askToSave + */ + bool maybeSaveCurrentTab(bool askToSave); + + /**************************************************************************************** + * Name: countPage + * Description: int cotaining the number of added tabs + */ + int countPage; /* TODO */ + + private slots: + + void slotFilePagePathChanged(const QString& path) const; + + /** + * @details Remove the tab with given index + * + * @param index Tab-number to remove + */ + void removeTab(int index); + + /** + * @details Cut selected text in current textpage. + */ + void slotCut() const; + + /** + * @details Copy selected text of current textpage to clipboard. + */ + void slotCopy() const; + + /** + * @details Paste text from clipboard to current textpage. + */ + void slotPaste() const; + + /** + * @details Undo last change in current textpage. + * + */ + void slotUndo() const; + /**************************************************************************************** + * Name: redo + * Description: redo last change in current textpage + * Parameters: none + * Return Values: none + * Change on members: none + */ + /** + * @brief + * + */ + void slotRedo() const; + + void slotZoomIn() const; + + void slotZoomOut() const; + /**************************************************************************************** + * Name: selectAll + * Description: select all in current textpage + * Parameters: none + * Return Values: none + * Change on members: none + */ + /** + * @brief + * + */ + void slotSelectAll() const; + + protected: + /**************************************************************************************** + * Name: saveFile + * Description: Saves the content of currentTab to the file filename + * Parameters: QString filename contains the full path of the file to + * save Return Values: true, if the file was saved succesfully false, if + * parameter filename is empty or the saving failed Change on members: sets + * isModified of the current tab to false + */ + /** + * @brief + * + * @param fileName + */ + bool saveFile(const QString& fileName); +}; + +} // namespace GpgFrontend::UI + +#endif // __TEXTEDIT_H__ diff --git a/src/ui/widgets/VerifyKeyDetailBox.cpp b/src/ui/widgets/VerifyKeyDetailBox.cpp index e0f79c3e..cd5b6641 100644 --- a/src/ui/widgets/VerifyKeyDetailBox.cpp +++ b/src/ui/widgets/VerifyKeyDetailBox.cpp @@ -1,7 +1,7 @@ /** - * This file is part of GPGFrontend. + * This file is part of GpgFrontend. * - * GPGFrontend is free software: you can redistribute it and/or modify + * 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. @@ -24,180 +24,198 @@ #include "ui/widgets/VerifyKeyDetailBox.h" -VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget *parent, GpgME::GpgContext *ctx, KeyList *keyList, - gpgme_signature_t signature) : - QGroupBox(parent), mCtx(ctx), mKeyList(keyList), fpr(signature->fpr) { +#include "gpg/function/GpgKeyGetter.h" - auto *vbox = new QVBoxLayout(); +namespace GpgFrontend::UI { - switch (gpg_err_code(signature->status)) { - case GPG_ERR_NO_PUBKEY: { - this->setTitle("A Error Signature"); - auto *importButton = new QPushButton(tr("Import from keyserver")); - connect(importButton, SIGNAL(clicked()), this, SLOT(slotImportFormKeyserver())); +VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget* parent, KeyList* keyList, + gpgme_signature_t signature) + : QGroupBox(parent), mKeyList(keyList), fpr(signature->fpr) { + auto* vbox = new QVBoxLayout(); - this->setTitle(tr("Key not present with id 0x") + signature->fpr); + switch (gpg_err_code(signature->status)) { + case GPG_ERR_NO_PUBKEY: { + this->setTitle("A Error Signature"); + auto* importButton = new QPushButton(_("Import from keyserver")); + connect(importButton, SIGNAL(clicked()), this, + SLOT(slotImportFormKeyserver())); - auto grid = new QGridLayout(); + this->setTitle(QString(_("Key not present with id 0x")) + signature->fpr); - grid->addWidget(new QLabel(tr("Status:")), 0, 0); - //grid->addWidget(new QLabel(tr("Fingerprint:")), 1, 0); - grid->addWidget(new QLabel(tr("Key not present in keylist")), 0, 1); - //grid->addWidget(new QLabel(signature->fpr), 1, 1); - grid->addWidget(importButton, 2, 0, 2, 1); + auto grid = new QGridLayout(); - vbox->addLayout(grid); - break; - } - case GPG_ERR_NO_ERROR: { - this->setTitle("A Signature:"); - auto gird = createKeyInfoGrid(signature); - if(gird != nullptr) { - vbox->addLayout(gird); - } else { - vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); - if(signature->fpr != nullptr) { - vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); - } - } - break; + grid->addWidget(new QLabel(QString(_("Status")) + _(":")), 0, 0); + // grid->addWidget(new QLabel(_("Fingerprint:")), 1, 0); + grid->addWidget(new QLabel(_("Key not present in key list")), 0, 1); + // grid->addWidget(new QLabel(signature->fpr), 1, 1); + grid->addWidget(importButton, 2, 0, 2, 1); + + vbox->addLayout(grid); + break; + } + case GPG_ERR_NO_ERROR: { + this->setTitle(QString(_("A Signature")) + ":"); + auto gird = createKeyInfoGrid(signature); + if (gird != nullptr) { + vbox->addLayout(gird); + } else { + vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); + if (signature->fpr != nullptr) { + vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + + QString(signature->fpr))); } - case GPG_ERR_CERT_REVOKED: { - this->setTitle("An Error Signature"); - vbox->addWidget(new QLabel(tr("Status: Cert Revoked"))); - auto gird = createKeyInfoGrid(signature); - if (gird != nullptr) { - vbox->addLayout(gird); - } else { - vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); - if(signature->fpr != nullptr) { - vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); - } - } - break; + } + break; + } + case GPG_ERR_CERT_REVOKED: { + this->setTitle("An Error Signature"); + vbox->addWidget( + new QLabel(QString(_("Status")) + ":" + _("Cert Revoked"))); + auto gird = createKeyInfoGrid(signature); + if (gird != nullptr) { + vbox->addLayout(gird); + } else { + vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); + if (signature->fpr != nullptr) { + vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + + QString(signature->fpr))); } - case GPG_ERR_SIG_EXPIRED: { - this->setTitle("An Error Signature"); - vbox->addWidget(new QLabel(tr("Status: Signature Expired"))); - auto gird = createKeyInfoGrid(signature); - if (gird != nullptr) { - vbox->addLayout(gird); - } else { - vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); - if(signature->fpr != nullptr) { - vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); - } - } - break; + } + break; + } + case GPG_ERR_SIG_EXPIRED: { + this->setTitle("An Error Signature"); + vbox->addWidget( + new QLabel(QString(_("Status")) + ":" + _("Signature Expired"))); + auto gird = createKeyInfoGrid(signature); + if (gird != nullptr) { + vbox->addLayout(gird); + } else { + vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); + if (signature->fpr != nullptr) { + vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + + QString(signature->fpr))); } - case GPG_ERR_KEY_EXPIRED: { - this->setTitle("An Error Signature"); - vbox->addWidget(new QLabel(tr("Status: Signature Expired"))); - vbox->addWidget(new QLabel(tr("Status: Key Expired"))); - auto gird = createKeyInfoGrid(signature); - if (gird != nullptr) { - vbox->addLayout(gird); - } else { - vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); - if(signature->fpr != nullptr) { - vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); - } - } - break; + } + break; + } + case GPG_ERR_KEY_EXPIRED: { + this->setTitle("An Error Signature"); + vbox->addWidget( + new QLabel(QString(_("Status")) + ":" + _("Key Expired"))); + vbox->addWidget( + new QLabel(QString(_("Status")) + ":" + _("Key Expired"))); + auto gird = createKeyInfoGrid(signature); + if (gird != nullptr) { + vbox->addLayout(gird); + } else { + vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); + if (signature->fpr != nullptr) { + vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + + QString(signature->fpr))); } - case GPG_ERR_GENERAL: { - this->setTitle("An Error Signature"); - vbox->addWidget(new QLabel(tr("Status: General Error"))); - auto gird = createKeyInfoGrid(signature); - if (gird != nullptr) { - vbox->addLayout(gird); - } else { - vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); - if(signature->fpr != nullptr) { - vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); - } - } - break; + } + break; + } + case GPG_ERR_GENERAL: { + this->setTitle("An Error Signature"); + vbox->addWidget( + new QLabel(QString(_("Status")) + ":" + _("General Error"))); + auto gird = createKeyInfoGrid(signature); + if (gird != nullptr) { + vbox->addLayout(gird); + } else { + vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); + if (signature->fpr != nullptr) { + vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + + QString(signature->fpr))); } - default: { - this->setTitle("An Error Signature"); - this->setTitle(tr("Status: Unknown Error")); - auto gird = createKeyInfoGrid(signature); - if (gird != nullptr) { - vbox->addLayout(gird); - } else { - vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); - if(signature->fpr != nullptr) { - vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); - } - } - break; + } + break; + } + default: { + this->setTitle("An Error Signature"); + this->setTitle(QString(_("Status")) + ":" + _("Unknown Error ")); + auto gird = createKeyInfoGrid(signature); + if (gird != nullptr) { + vbox->addLayout(gird); + } else { + vbox->addWidget(new QLabel(_("Key Information is NOT Available"))); + if (signature->fpr != nullptr) { + vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " + + QString(signature->fpr))); } + } + break; } - this->setLayout(vbox); + } + this->setLayout(vbox); } void VerifyKeyDetailBox::slotImportFormKeyserver() { - auto *importDialog = new KeyServerImportDialog(mCtx, mKeyList, false, this); - importDialog->slotImport(QStringList(fpr)); + auto* importDialog = new KeyServerImportDialog(false, this); + auto key_ids = std::make_unique<KeyIdArgsList>(); + key_ids->push_back(fpr.toStdString()); + importDialog->slotImport(key_ids); } QString VerifyKeyDetailBox::beautifyFingerprint(QString fingerprint) { - uint len = fingerprint.length(); - if ((len > 0) && (len % 4 == 0)) - for (uint n = 0; 4 * (n + 1) < len; ++n) - fingerprint.insert(static_cast<int>(5u * n + 4u), ' '); - return fingerprint; + uint len = fingerprint.length(); + if ((len > 0) && (len % 4 == 0)) + for (uint n = 0; 4 * (n + 1) < len; ++n) + fingerprint.insert(static_cast<int>(5u * n + 4u), ' '); + return fingerprint; } -QGridLayout *VerifyKeyDetailBox::createKeyInfoGrid(gpgme_signature_t &signature) { - - auto grid = new QGridLayout(); - GpgKey key = mCtx->getKeyByFpr(signature->fpr); - - if(!key.good) return nullptr; - grid->addWidget(new QLabel(tr("Signer Name:")), 0, 0); - grid->addWidget(new QLabel(tr("Signer Email:")), 1, 0); - grid->addWidget(new QLabel(tr("Key's Fingerprint:")), 2, 0); - grid->addWidget(new QLabel(tr("Valid:")), 3, 0); - grid->addWidget(new QLabel(tr("Flags:")), 4, 0); - - grid->addWidget(new QLabel(key.name), 0, 1); - grid->addWidget(new QLabel(key.email), 1, 1); - grid->addWidget(new QLabel(beautifyFingerprint(signature->fpr)), 2, 1); - - - if(signature->summary & GPGME_SIGSUM_VALID) { - grid->addWidget(new QLabel(tr("Fully Valid")), 3, 1); - } else { - grid->addWidget(new QLabel(tr("NOT Fully Valid")), 3, 1); - } - - QString flags; - QTextStream textStream(&flags); - - if(signature->summary & GPGME_SIGSUM_GREEN) { - textStream << tr("Good "); - } - if(signature->summary & GPGME_SIGSUM_RED) { - textStream << tr("Bad "); - } - if(signature->summary & GPGME_SIGSUM_SIG_EXPIRED) { - textStream << tr("Expired "); - } - if(signature->summary & GPGME_SIGSUM_KEY_MISSING) { - textStream << tr("Missing Key "); - } - if(signature->summary & GPGME_SIGSUM_KEY_REVOKED) { - textStream << tr("Revoked Key "); - } - if(signature->summary & GPGME_SIGSUM_KEY_EXPIRED) { - textStream << tr("Expired Key "); - } - if(signature->summary & GPGME_SIGSUM_CRL_MISSING) { - textStream << tr("Missing CRL "); - } - - grid->addWidget(new QLabel(tr(flags.toUtf8().constData())), 4, 1); - return grid; +QGridLayout* VerifyKeyDetailBox::createKeyInfoGrid( + gpgme_signature_t& signature) { + auto grid = new QGridLayout(); + GpgKey key = GpgKeyGetter::GetInstance().GetKey(signature->fpr); + + if (!key.good()) return nullptr; + grid->addWidget(new QLabel(QString(_("Signer Name")) + ":"), 0, 0); + grid->addWidget(new QLabel(QString(_("Signer Email")) + ":"), 1, 0); + grid->addWidget(new QLabel(QString(_("Key's Fingerprint")) + ":"), 2, 0); + grid->addWidget(new QLabel(QString(_("Valid")) + ":"), 3, 0); + grid->addWidget(new QLabel(QString(_("Flags")) + ":"), 4, 0); + + grid->addWidget(new QLabel(QString::fromStdString(key.name())), 0, 1); + grid->addWidget(new QLabel(QString::fromStdString(key.email())), 1, 1); + grid->addWidget(new QLabel(beautifyFingerprint(signature->fpr)), 2, 1); + + if (signature->summary & GPGME_SIGSUM_VALID) { + grid->addWidget(new QLabel(_("Fully Valid")), 3, 1); + } else { + grid->addWidget(new QLabel(_("NOT Fully Valid")), 3, 1); + } + + QString flags; + QTextStream textStream(&flags); + + if (signature->summary & GPGME_SIGSUM_GREEN) { + textStream << _("Good") << " "; + } + if (signature->summary & GPGME_SIGSUM_RED) { + textStream << _("Bad") << " "; + } + if (signature->summary & GPGME_SIGSUM_SIG_EXPIRED) { + textStream << _("Expired") << " "; + } + if (signature->summary & GPGME_SIGSUM_KEY_MISSING) { + textStream << _("Missing Key") << " "; + } + if (signature->summary & GPGME_SIGSUM_KEY_REVOKED) { + textStream << _("Revoked Key") << " "; + } + if (signature->summary & GPGME_SIGSUM_KEY_EXPIRED) { + textStream << _("Expired Key") << " "; + } + if (signature->summary & GPGME_SIGSUM_CRL_MISSING) { + textStream << _("Missing CRL") << " "; + } + + grid->addWidget(new QLabel(_(flags.toUtf8().constData())), 4, 1); + return grid; } + +} // namespace GpgFrontend::UI
\ No newline at end of file diff --git a/src/ui/widgets/VerifyKeyDetailBox.h b/src/ui/widgets/VerifyKeyDetailBox.h new file mode 100644 index 00000000..c1b26bb2 --- /dev/null +++ b/src/ui/widgets/VerifyKeyDetailBox.h @@ -0,0 +1,55 @@ +/** + * 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. + * + */ + +#ifndef __VERIFYKEYDETAILBOX_H__ +#define __VERIFYKEYDETAILBOX_H__ + +#include "ui/KeyServerImportDialog.h" +#include "ui/widgets/KeyList.h" + +namespace GpgFrontend::UI { + +class VerifyKeyDetailBox : public QGroupBox { + Q_OBJECT + public: + explicit VerifyKeyDetailBox(QWidget* parent, KeyList* mKeyList, + gpgme_signature_t signature); + + private slots: + + void slotImportFormKeyserver(); + + private: + KeyList* mKeyList; + + static QString beautifyFingerprint(QString fingerprint); + + static QGridLayout* createKeyInfoGrid(gpgme_signature_t& signature); + + QString fpr; +}; + +} // namespace GpgFrontend::UI + +#endif // __VERIFYKEYDETAILBOX_H__ |