gboard
Loading...
Searching...
No Matches
gboard.cc
Go to the documentation of this file.
1// G4Dialog
2#include "gboard.h"
3#include "gui_session.h"
4
5// qt
6#include <QVBoxLayout>
7#include <QRegularExpression>
8
9
10GBoard::GBoard(const std::shared_ptr<GOptions>& gopt, QWidget* parent)
11 : QWidget(parent),
12 GBase(gopt, GBOARD_LOGGER) {
13 // --- Create top bar widgets ---
14 // The top bar provides a lightweight "console" UX: filter, clear, save.
15 searchLineEdit = new QLineEdit(this);
16 searchLineEdit->setObjectName("searchLineEdit");
17 searchLineEdit->setPlaceholderText("Filter log lines (case insensitive)...");
18 searchLineEdit->setClearButtonEnabled(true); // Allows quickly removing the filter text.
19
20 clearButton = new QToolButton(this);
21 clearButton->setObjectName("clearButton");
22 clearButton->setIcon(style()->standardIcon(QStyle::SP_DialogResetButton));
23 clearButton->setToolTip("Clear Log");
24 clearButton->setText("Clear");
25 // for some reason, the SP_TrashIcon icon is not showing, so using SP_DialogResetButton
26 clearButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); // Or other style
27 clearButton->setEnabled(true);
28
29 saveButton = new QToolButton(this);
30 saveButton->setIcon(style()->standardIcon(QStyle::SP_DialogSaveButton));
31 saveButton->setToolTip("Save Log to File");
32 saveButton->setEnabled(true);
33
34
35 // Create a horizontal layout for the top bar.
36 auto* topBarLayout = new QHBoxLayout;
37 topBarLayout->addWidget(searchLineEdit);
38 topBarLayout->addWidget(clearButton);
39 topBarLayout->addWidget(saveButton);
40 topBarLayout->setSpacing(5);
41
42 // Create a QTextEdit for log messages.
43 // Rich text is enabled so that HTML fragments (for example ANSI-to-HTML conversions) render correctly.
44 logTextEdit = new QTextEdit(this);
45 logTextEdit->setAcceptRichText(true);
46 logTextEdit->setReadOnly(true);
47 logTextEdit->setMinimumHeight(200);
48 logTextEdit->setMinimumWidth(400);
49
50 auto* layout = new QVBoxLayout(this);
51 layout->addLayout(topBarLayout);
52 layout->addWidget(logTextEdit, 1); // 1: stretchable
53 setLayout(layout);
54
55 // --- Connect signals to slots ---
56 // UI changes (typing, clicking) are translated into operations on the stored log history.
57 connect(searchLineEdit, &QLineEdit::textChanged, this, &GBoard::filterLog);
58 connect(clearButton, &QToolButton::clicked, this, &GBoard::clearLog);
59 connect(saveButton, &QToolButton::clicked, this, &GBoard::saveLog);
60
61 log->info(1, "GBoard initialized");
62}
63
64void GBoard::appendLog(const QString& htmlFragment) {
65 // See header for API docs.
66 if (htmlFragment.trimmed().isEmpty()) { return; }
67
68 // Append to the source of truth, the full log line list.
69 // NOTE: We intentionally store all lines (even when filtered out) so the user can change filters later.
70 fullLogLines.append(htmlFragment);
71
72 // Refresh the view so the new line appears if it matches the current filter.
73 updateDisplay();
74}
75
76void GBoard::updateDisplay() {
77 // See header for API docs.
78 if (!logTextEdit) return;
79
80 // Ensure QTextEdit manipulation occurs on the GUI thread.
81 // This protects typical usage where log lines arrive from worker threads or external callbacks.
82 if (QThread::currentThread() != logTextEdit->thread()) {
83 QMetaObject::invokeMethod(this, "updateDisplay", Qt::QueuedConnection);
84 return;
85 }
86
87 logTextEdit->clear(); // Rebuild from scratch using the stored history.
88
89 const bool filtering = !currentFilterText.isEmpty();
90 Qt::CaseSensitivity cs = Qt::CaseInsensitive;
91
92 // Re-append only the matching HTML fragments.
93 for (const QString& line : fullLogLines) {
94 bool matches = true;
95
96 if (filtering) { matches = (line.indexOf(currentFilterText, 0, cs) >= 0); }
97
98 if (matches) { logTextEdit->append(line); }
99 }
100
101 // Auto-scroll to the bottom after updating the display.
102 logTextEdit->verticalScrollBar()->setValue(logTextEdit->verticalScrollBar()->maximum());
103}
104
105void GBoard::filterLog(const QString& searchText) {
106 // See header for API docs.
107 // Keep the filter string normalized so repeated updates remain stable.
108 currentFilterText = searchText.trimmed();
109 updateDisplay();
110}
111
112void GBoard::clearLog() {
113 // See header for API docs.
114 if (logTextEdit) {
115 fullLogLines.clear();
116 updateDisplay();
117 log->info(1, "Log cleared by user.");
118 }
119}
120
121// Slot to Save the Log
122void GBoard::saveLog() {
123 // See header for API docs.
124 if (!logTextEdit) return;
125
126 QString defaultFileName = "gboard_log.log"; // Suggest a default name
127 QString fileName = QFileDialog::getSaveFileName(this,
128 tr("Save Log File"),
129 defaultFileName, // Default file/path suggestion
130 tr("Log Files (*.log);;Text Files (*.txt);;All Files (*)"));
131
132 if (fileName.isEmpty()) {
133 return; // User cancelled
134 }
135
136 QFile file(fileName);
137 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
138 QMessageBox::warning(this, tr("Save Log Error"),
139 tr("Could not open file %1 for writing:\n%2.")
140 .arg(QDir::toNativeSeparators(fileName), file.errorString()));
141 log->warning("Failed to save log to ", fileName.toStdString(), ". Error: ", file.errorString().toStdString());
142 return;
143 }
144
145 QTextStream out(&file);
146 // Save the plain text content (most common for logs).
147 // This captures exactly what the user sees (including filtering) in a portable log-friendly format.
148 out << logTextEdit->toPlainText();
149 file.close(); // Stream destructor closes it, but explicit is fine
150
151 log->info("Log saved successfully to ", fileName.toStdString());
152 // Optional: Show a status bar message or brief confirmation dialog
153}
std::shared_ptr< GLogger > log
GBoard(const std::shared_ptr< GOptions > &gopt, QWidget *parent=nullptr)
Constructs a new GBoard widget.
Definition gboard.cc:10
void appendLog(const QString &text)
Appends a log line to the internal history and updates the display.
Definition gboard.cc:64
void warning(Args &&... args) const
void info(int level, Args &&... args) const
constexpr const char * GBOARD_LOGGER
Definition gboard.h:10
int line