mirror of
https://github.com/wf-group/wfview
synced 2026-08-13 17:32:59 -04:00
159 lines
5.3 KiB
C++
159 lines
5.3 KiB
C++
#ifndef LOGGINGCONTROLLER_H
|
|
#define LOGGINGCONTROLLER_H
|
|
|
|
#include "qtimer.h"
|
|
#include <QObject>
|
|
#include <QString>
|
|
#include <QMutex>
|
|
#include <QMutex>
|
|
#include <QFile>
|
|
#include <QTextStream>
|
|
|
|
#include "LogModel.h"
|
|
|
|
class LoggingController : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
Q_PROPERTY(QString logText READ logText WRITE setLogText NOTIFY logTextChanged)
|
|
Q_PROPERTY(bool debugEnabled READ debugEnabled WRITE setDebugEnabled NOTIFY debugEnabledChanged)
|
|
Q_PROPERTY(bool commDebugEnabled READ commDebugEnabled WRITE setCommDebugEnabled NOTIFY commDebugEnabledChanged)
|
|
Q_PROPERTY(bool rigctlDebugEnabled READ rigctlDebugEnabled WRITE setRigctlDebugEnabled NOTIFY rigctlDebugEnabledChanged)
|
|
|
|
Q_PROPERTY(QString logFilePath READ logFilePath WRITE setLogFilePath NOTIFY logFilePathChanged)
|
|
Q_PROPERTY(int flushIntervalMs READ flushIntervalMs WRITE setFlushIntervalMs NOTIFY flushIntervalMsChanged)
|
|
|
|
// Useful for UI enable/disable, status bars etc.
|
|
Q_PROPERTY(QString lastTermbinUrl READ lastTermbinUrl NOTIFY lastTermbinUrlChanged)
|
|
Q_PROPERTY(QString lastError READ lastError NOTIFY lastErrorChanged)
|
|
Q_PROPERTY(bool consoleLoggingEnabled READ consoleLoggingEnabled WRITE setConsoleLoggingEnabled NOTIFY consoleLoggingEnabledChanged)
|
|
Q_PROPERTY(LogModel* model READ model CONSTANT)
|
|
|
|
Q_PROPERTY(int debugMsg READ debugMsg CONSTANT)
|
|
Q_PROPERTY(int infoMsg READ infoMsg CONSTANT)
|
|
Q_PROPERTY(int warningMsg READ warningMsg CONSTANT)
|
|
Q_PROPERTY(int criticalMsg READ criticalMsg CONSTANT)
|
|
Q_PROPERTY(int fatalMsg READ fatalMsg CONSTANT)
|
|
|
|
public:
|
|
explicit LoggingController(QObject *parent = nullptr);
|
|
~LoggingController() override;
|
|
|
|
QString logText() const { return m_logText; }
|
|
void setLogText(const QString &t);
|
|
|
|
bool debugEnabled() const { return m_debugEnabled; }
|
|
void setDebugEnabled(bool v);
|
|
|
|
bool commDebugEnabled() const { return m_commDebugEnabled; }
|
|
void setCommDebugEnabled(bool v);
|
|
|
|
bool rigctlDebugEnabled() const { return m_rigctlDebugEnabled; }
|
|
void setRigctlDebugEnabled(bool v);
|
|
|
|
QString logFilePath() const { return m_logFilePath; }
|
|
void setLogFilePath(const QString &p);
|
|
|
|
QString lastTermbinUrl() const { return m_lastTermbinUrl; }
|
|
QString lastError() const { return m_lastError; }
|
|
|
|
int flushIntervalMs() const { return m_flushIntervalMs; }
|
|
void setFlushIntervalMs(int v);
|
|
|
|
bool consoleLoggingEnabled() const { return m_consoleLoggingEnabled; }
|
|
void setConsoleLoggingEnabled(bool v);
|
|
|
|
LogModel* model() { return &m_model; }
|
|
|
|
// Convenience for C++ side
|
|
Q_INVOKABLE void clearDisplay(); // clears display only (not file)
|
|
|
|
Q_INVOKABLE void installQtMessageHandler(bool alsoCaptureStderr = false);
|
|
Q_INVOKABLE void uninstallQtMessageHandler();
|
|
int debugMsg() const { return int(QtDebugMsg); }
|
|
int infoMsg() const { return int(QtInfoMsg); }
|
|
int warningMsg() const { return int(QtWarningMsg); }
|
|
int criticalMsg() const { return int(QtCriticalMsg); }
|
|
int fatalMsg() const { return int(QtFatalMsg); }
|
|
|
|
Q_INVOKABLE void debug(const QString &msg) { enqueueEntry(QtDebugMsg, msg); }
|
|
Q_INVOKABLE void info (const QString &msg) { enqueueEntry(QtInfoMsg, msg); }
|
|
Q_INVOKABLE void warn (const QString &msg) { enqueueEntry(QtWarningMsg, msg); }
|
|
Q_INVOKABLE void error(const QString &msg) { enqueueEntry(QtCriticalMsg, msg); }
|
|
Q_INVOKABLE void fatal(const QString &msg) { enqueueEntry(QtFatalMsg, msg); }
|
|
|
|
|
|
public slots:
|
|
// From QML button signals
|
|
void annotateRequested(const QString &text);
|
|
void scrollToBottomRequested();
|
|
void clearDisplayRequested();
|
|
void copyPathRequested();
|
|
void sendToTermbinRequested();
|
|
|
|
private slots:
|
|
void flushPendingToModel();
|
|
|
|
|
|
signals:
|
|
void logTextChanged();
|
|
void debugEnabledChanged();
|
|
void commDebugEnabledChanged();
|
|
void rigctlDebugEnabledChanged();
|
|
void logFilePathChanged();
|
|
void logDirPathChanged();
|
|
|
|
void lastTermbinUrlChanged();
|
|
void lastErrorChanged();
|
|
|
|
// Let QML do the scroll if you prefer (or connect in C++)
|
|
void requestScrollToBottom();
|
|
void flushIntervalMsChanged();
|
|
void consoleLoggingEnabledChanged();
|
|
|
|
private:
|
|
void beginShutdown();
|
|
void enqueueEntry(QtMsgType type, const QString& text);
|
|
void ensureLogFileOpen_locked();
|
|
void setError(const QString &msg);
|
|
void setTermbinUrl(const QString &url);
|
|
|
|
QString m_lastTermbinUrl;
|
|
QString m_lastError;
|
|
|
|
static void qtMessageHandler(QtMsgType type,
|
|
const QMessageLogContext &context,
|
|
const QString &msg);
|
|
|
|
static std::atomic<LoggingController*> s_instance; // <-- atomic, not raw
|
|
static QtMessageHandler s_prevHandler;
|
|
|
|
std::atomic_bool m_shuttingDown{false};
|
|
|
|
bool m_debugEnabled = false;
|
|
bool m_commDebugEnabled = false;
|
|
bool m_rigctlDebugEnabled = false;
|
|
|
|
QString m_logFilePath;
|
|
QFile m_logFile;
|
|
QTextStream m_logStream;
|
|
|
|
mutable QMutex m_textMutex;
|
|
|
|
QString m_logText;
|
|
QString m_pending; // accumulated since last flush
|
|
|
|
// throttling timer
|
|
QTimer m_flushTimer;
|
|
int m_flushIntervalMs = 100;
|
|
|
|
bool m_handlerInstalled = false;
|
|
bool m_consoleLoggingEnabled = false;
|
|
|
|
LogModel m_model;
|
|
QMutex m_pendingMutex;
|
|
QVector<LogEntry> m_pendingEntries;
|
|
};
|
|
|
|
|
|
#endif // LOGGINGCONTROLLER_H
|