File indexing completed on 2025-01-05 04:55:46
0001 /* 0002 SPDX-FileCopyrightText: 2015-2021 Laurent Montel <montel@kde.org> 0003 SPDX-FileCopyrightText: 2021 g10 Code GmbH 0004 SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include <config-libkleo.h> 0010 0011 #include "auditlogviewer.h" 0012 0013 #include <libkleo/auditlogentry.h> 0014 #include <libkleo/formatting.h> 0015 0016 #include <KConfigGroup> 0017 #include <KGuiItem> 0018 #include <KLocalizedString> 0019 #include <KMessageBox> 0020 #include <KSharedConfig> 0021 #include <KStandardGuiItem> 0022 0023 #ifdef HAVE_PIMTEXTEDIT 0024 #include <TextCustomEditor/RichTextEditor> 0025 #else 0026 #include <QTextEdit> 0027 #endif 0028 0029 #include <QDebug> 0030 #include <QDialogButtonBox> 0031 #include <QFileDialog> 0032 #include <QPushButton> 0033 #include <QSaveFile> 0034 #include <QStyle> 0035 #include <QTextStream> 0036 #include <QVBoxLayout> 0037 0038 #include <gpgme++/error.h> 0039 0040 using namespace Kleo; 0041 0042 AuditLogViewer::AuditLogViewer(const QString &log, QWidget *parent) 0043 : QDialog(parent) 0044 , m_log(/* sic */) 0045 , 0046 #ifdef HAVE_PIMTEXTEDIT 0047 m_textEdit(new TextCustomEditor::RichTextEditorWidget(this)) 0048 #else 0049 m_textEdit(new QTextEdit(this)) 0050 #endif 0051 { 0052 setWindowTitle(i18nc("@title:window", "View GnuPG Audit Log")); 0053 QDialogButtonBox *buttonBox = new QDialogButtonBox{}; 0054 0055 auto copyClipBtn = buttonBox->addButton(i18n("&Copy to Clipboard"), QDialogButtonBox::ActionRole); 0056 copyClipBtn->setObjectName(QLatin1StringView("copyClipBtn")); 0057 copyClipBtn->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy"))); 0058 connect(copyClipBtn, &QPushButton::clicked, this, &AuditLogViewer::slotCopyClip); 0059 0060 auto saveAsBtn = buttonBox->addButton(i18n("&Save to Disk..."), QDialogButtonBox::ActionRole); 0061 saveAsBtn->setObjectName(QLatin1StringView("saveAsBtn")); 0062 saveAsBtn->setIcon(QIcon::fromTheme(QStringLiteral("document-save-as"))); 0063 connect(saveAsBtn, &QPushButton::clicked, this, &AuditLogViewer::slotSaveAs); 0064 0065 auto closeBtn = buttonBox->addButton(QString{}, QDialogButtonBox::AcceptRole); 0066 closeBtn->setObjectName(QLatin1StringView("Close")); 0067 KGuiItem::assign(closeBtn, KStandardGuiItem::close()); 0068 0069 m_textEdit->setObjectName(QLatin1StringView("m_textEdit")); 0070 m_textEdit->setReadOnly(true); 0071 0072 auto mainLayout = new QVBoxLayout(this); 0073 mainLayout->addWidget(m_textEdit); 0074 mainLayout->addWidget(buttonBox); 0075 0076 #if 0 0077 qDebug() << "buttonBox->style()->styleHint(QStyle::SH_DialogButtonLayout, ...):" << buttonBox->style()->styleHint(QStyle::SH_DialogButtonLayout, nullptr, buttonBox); 0078 qDebug() << __func__ << "buttonBox->focusProxy():" << buttonBox->focusProxy(); 0079 qDebug() << __func__ << "copyClipBtn->nextInFocusChain():" << copyClipBtn->nextInFocusChain(); 0080 qDebug() << __func__ << "saveAsBtn->nextInFocusChain():" << saveAsBtn->nextInFocusChain(); 0081 qDebug() << __func__ << "closeBtn->nextInFocusChain():" << closeBtn->nextInFocusChain(); 0082 #endif 0083 0084 connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); 0085 connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); 0086 0087 setAuditLog(log); 0088 0089 readConfig(); 0090 } 0091 0092 AuditLogViewer::~AuditLogViewer() 0093 { 0094 writeConfig(); 0095 } 0096 0097 // static 0098 void AuditLogViewer::showAuditLog(QWidget *parent, const AuditLogEntry &auditLog, const QString &title) 0099 { 0100 const GpgME::Error err = auditLog.error(); 0101 if (err.code() == GPG_ERR_NOT_IMPLEMENTED) { 0102 KMessageBox::information(parent, i18n("Your system does not have support for GnuPG Audit Logs"), i18n("System Error")); 0103 return; 0104 } 0105 if (err && err.code() != GPG_ERR_NO_DATA) { 0106 KMessageBox::information(parent, 0107 i18n("An error occurred while trying to retrieve the GnuPG Audit Log:\n%1", Formatting::errorAsString(err)), 0108 i18n("GnuPG Audit Log Error")); 0109 return; 0110 } 0111 if (auditLog.text().isEmpty()) { 0112 KMessageBox::information(parent, i18n("No GnuPG Audit Log available for this operation."), i18n("No GnuPG Audit Log")); 0113 return; 0114 } 0115 0116 const auto alv = new AuditLogViewer{auditLog.text(), parent}; 0117 alv->setAttribute(Qt::WA_DeleteOnClose); 0118 alv->setWindowTitle(title.isEmpty() ? i18n("GnuPG Audit Log Viewer") : title); 0119 alv->show(); 0120 } 0121 0122 void AuditLogViewer::setAuditLog(const QString &log) 0123 { 0124 if (log == m_log) { 0125 return; 0126 } 0127 m_log = log; 0128 m_textEdit->setHtml(QLatin1StringView("<qt>") + log + QLatin1String("</qt>")); 0129 } 0130 0131 void AuditLogViewer::slotSaveAs() 0132 { 0133 const QString fileName = QFileDialog::getSaveFileName(this, i18n("Choose File to Save GnuPG Audit Log to")); 0134 if (fileName.isEmpty()) { 0135 return; 0136 } 0137 0138 QSaveFile file(fileName); 0139 0140 if (file.open(QIODevice::WriteOnly)) { 0141 QTextStream s(&file); 0142 s << "<html><head>"; 0143 if (!windowTitle().isEmpty()) { 0144 s << "\n<title>" << windowTitle().toHtmlEscaped() << "</title>\n"; 0145 } 0146 s << "</head><body>\n" << m_log << "\n</body></html>\n"; 0147 s.flush(); 0148 file.commit(); 0149 } 0150 0151 if (const int err = file.error()) { 0152 KMessageBox::error(this, i18n("Could not save to file \"%1\": %2", file.fileName(), QString::fromLocal8Bit(strerror(err))), i18n("File Save Error")); 0153 } 0154 } 0155 0156 void AuditLogViewer::slotCopyClip() 0157 { 0158 #ifdef HAVE_PIMTEXTEDIT 0159 m_textEdit->editor()->selectAll(); 0160 m_textEdit->editor()->copy(); 0161 m_textEdit->editor()->textCursor().clearSelection(); 0162 #else 0163 m_textEdit->selectAll(); 0164 m_textEdit->copy(); 0165 m_textEdit->textCursor().clearSelection(); 0166 #endif 0167 } 0168 0169 void AuditLogViewer::readConfig() 0170 { 0171 KConfigGroup group(KSharedConfig::openConfig(), QStringLiteral("AuditLogViewer")); 0172 const QSize size = group.readEntry("Size", QSize()); 0173 if (size.isValid()) { 0174 resize(size); 0175 } else { 0176 resize(600, 400); 0177 } 0178 } 0179 0180 void AuditLogViewer::writeConfig() 0181 { 0182 KConfigGroup group(KSharedConfig::openConfig(), QStringLiteral("AuditLogViewer")); 0183 group.writeEntry("Size", size()); 0184 group.sync(); 0185 } 0186 0187 #include "moc_auditlogviewer.cpp"