Libkleo

auditlogviewer.cpp
1 /*
2  SPDX-FileCopyrightText: 2015-2021 Laurent Montel <montel@kde.org>
3  SPDX-FileCopyrightText: 2021 g10 Code GmbH
4  SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
5 
6  SPDX-License-Identifier: LGPL-2.0-or-later
7 */
8 
9 #include <config-libkleo.h>
10 
11 #include "auditlogviewer.h"
12 
13 #include <libkleo/auditlogentry.h>
14 #include <libkleo/formatting.h>
15 
16 #include <KConfigGroup>
17 #include <KGuiItem>
18 #include <KLocalizedString>
19 #include <KMessageBox>
20 #include <KSharedConfig>
21 #include <KStandardGuiItem>
22 
23 #ifdef HAVE_PIMTEXTEDIT
24 #include <TextCustomEditor/RichTextEditor>
25 #else
26 #include <QTextEdit>
27 #endif
28 
29 #include <QDebug>
30 #include <QDialogButtonBox>
31 #include <QFileDialog>
32 #include <QPushButton>
33 #include <QSaveFile>
34 #include <QStyle>
35 #include <QTextStream>
36 #include <QVBoxLayout>
37 
38 #include <gpgme++/error.h>
39 
40 using namespace Kleo;
41 
42 AuditLogViewer::AuditLogViewer(const QString &log, QWidget *parent)
43  : QDialog(parent)
44  , m_log(/* sic */)
45  ,
46 #ifdef HAVE_PIMTEXTEDIT
47  m_textEdit(new TextCustomEditor::RichTextEditorWidget(this))
48 #else
49  m_textEdit(new QTextEdit(this))
50 #endif
51 {
52  setWindowTitle(i18nc("@title:window", "View GnuPG Audit Log"));
53  QDialogButtonBox *buttonBox = new QDialogButtonBox{};
54 
55  auto copyClipBtn = buttonBox->addButton(i18n("&Copy to Clipboard"), QDialogButtonBox::ActionRole);
56  copyClipBtn->setObjectName(QLatin1StringView("copyClipBtn"));
57  copyClipBtn->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy")));
58  connect(copyClipBtn, &QPushButton::clicked, this, &AuditLogViewer::slotCopyClip);
59 
60  auto saveAsBtn = buttonBox->addButton(i18n("&Save to Disk..."), QDialogButtonBox::ActionRole);
61  saveAsBtn->setObjectName(QLatin1StringView("saveAsBtn"));
62  saveAsBtn->setIcon(QIcon::fromTheme(QStringLiteral("document-save-as")));
63  connect(saveAsBtn, &QPushButton::clicked, this, &AuditLogViewer::slotSaveAs);
64 
65  auto closeBtn = buttonBox->addButton(QString{}, QDialogButtonBox::AcceptRole);
66  closeBtn->setObjectName(QLatin1StringView("Close"));
68 
69  m_textEdit->setObjectName(QLatin1StringView("m_textEdit"));
70  m_textEdit->setReadOnly(true);
71 
72  auto mainLayout = new QVBoxLayout(this);
73  mainLayout->addWidget(m_textEdit);
74  mainLayout->addWidget(buttonBox);
75 
76 #if 0
77  qDebug() << "buttonBox->style()->styleHint(QStyle::SH_DialogButtonLayout, ...):" << buttonBox->style()->styleHint(QStyle::SH_DialogButtonLayout, nullptr, buttonBox);
78  qDebug() << __func__ << "buttonBox->focusProxy():" << buttonBox->focusProxy();
79  qDebug() << __func__ << "copyClipBtn->nextInFocusChain():" << copyClipBtn->nextInFocusChain();
80  qDebug() << __func__ << "saveAsBtn->nextInFocusChain():" << saveAsBtn->nextInFocusChain();
81  qDebug() << __func__ << "closeBtn->nextInFocusChain():" << closeBtn->nextInFocusChain();
82 #endif
83 
84  connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
85  connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
86 
87  setAuditLog(log);
88 
89  readConfig();
90 }
91 
92 AuditLogViewer::~AuditLogViewer()
93 {
94  writeConfig();
95 }
96 
97 // static
98 void AuditLogViewer::showAuditLog(QWidget *parent, const AuditLogEntry &auditLog, const QString &title)
99 {
100  const GpgME::Error err = auditLog.error();
101  if (err.code() == GPG_ERR_NOT_IMPLEMENTED) {
102  KMessageBox::information(parent, i18n("Your system does not have support for GnuPG Audit Logs"), i18n("System Error"));
103  return;
104  }
105  if (err && err.code() != GPG_ERR_NO_DATA) {
107  i18n("An error occurred while trying to retrieve the GnuPG Audit Log:\n%1", Formatting::errorAsString(err)),
108  i18n("GnuPG Audit Log Error"));
109  return;
110  }
111  if (auditLog.text().isEmpty()) {
112  KMessageBox::information(parent, i18n("No GnuPG Audit Log available for this operation."), i18n("No GnuPG Audit Log"));
113  return;
114  }
115 
116  const auto alv = new AuditLogViewer{auditLog.text(), parent};
118  alv->setWindowTitle(title.isEmpty() ? i18n("GnuPG Audit Log Viewer") : title);
119  alv->show();
120 }
121 
122 void AuditLogViewer::setAuditLog(const QString &log)
123 {
124  if (log == m_log) {
125  return;
126  }
127  m_log = log;
128  m_textEdit->setHtml(QLatin1StringView("<qt>") + log + QLatin1String("</qt>"));
129 }
130 
131 void AuditLogViewer::slotSaveAs()
132 {
133  const QString fileName = QFileDialog::getSaveFileName(this, i18n("Choose File to Save GnuPG Audit Log to"));
134  if (fileName.isEmpty()) {
135  return;
136  }
137 
138  QSaveFile file(fileName);
139 
140  if (file.open(QIODevice::WriteOnly)) {
141  QTextStream s(&file);
142  s << "<html><head>";
143  if (!windowTitle().isEmpty()) {
144  s << "\n<title>" << windowTitle().toHtmlEscaped() << "</title>\n";
145  }
146  s << "</head><body>\n" << m_log << "\n</body></html>\n";
147  s.flush();
148  file.commit();
149  }
150 
151  if (const int err = file.error()) {
152  KMessageBox::error(this, i18n("Could not save to file \"%1\": %2", file.fileName(), QString::fromLocal8Bit(strerror(err))), i18n("File Save Error"));
153  }
154 }
155 
156 void AuditLogViewer::slotCopyClip()
157 {
158 #ifdef HAVE_PIMTEXTEDIT
159  m_textEdit->editor()->selectAll();
160  m_textEdit->editor()->copy();
161  m_textEdit->editor()->textCursor().clearSelection();
162 #else
163  m_textEdit->selectAll();
164  m_textEdit->copy();
165  m_textEdit->textCursor().clearSelection();
166 #endif
167 }
168 
169 void AuditLogViewer::readConfig()
170 {
171  KConfigGroup group(KSharedConfig::openConfig(), QStringLiteral("AuditLogViewer"));
172  const QSize size = group.readEntry("Size", QSize());
173  if (size.isValid()) {
174  resize(size);
175  } else {
176  resize(600, 400);
177  }
178 }
179 
180 void AuditLogViewer::writeConfig()
181 {
182  KConfigGroup group(KSharedConfig::openConfig(), QStringLiteral("AuditLogViewer"));
183  group.writeEntry("Size", size());
184  group.sync();
185 }
186 
187 #include "moc_auditlogviewer.cpp"
bool isValid() const const
virtual void reject()
void clicked(bool checked)
QIcon fromTheme(const QString &name)
void setAttribute(Qt::WidgetAttribute attribute, bool on)
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
KGuiItem close()
static void assign(QPushButton *button, const KGuiItem &item)
QString i18n(const char *text, const TYPE &arg...)
QString fromLocal8Bit(const char *str, int size)
QStyle * style() const const
QWidget * nextInFocusChain() const const
bool isEmpty() const const
QWidget * focusProxy() const const
virtual void accept()
void addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role)
virtual int styleHint(QStyle::StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const const=0
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
SH_DialogButtonLayout
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
void information(QWidget *parent, const QString &text, const QString &title=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
WA_DeleteOnClose
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Thu Feb 15 2024 03:56:13 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.