This commit is contained in:
Cyril Anisimov 2025-07-05 10:45:58 +00:00 committed by GitHub
commit 1f339f6a85
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 194 additions and 161 deletions

View file

@ -4,6 +4,12 @@
#include <QQmlApplicationEngine> #include <QQmlApplicationEngine>
#include <QQuickWindow> #include <QQuickWindow>
#include "logger.h"
namespace {
Logger logger("FocusController");
}
FocusController::FocusController(QQmlApplicationEngine *engine, QObject *parent) FocusController::FocusController(QQmlApplicationEngine *engine, QObject *parent)
: QObject { parent }, : QObject { parent },
m_engine { engine }, m_engine { engine },
@ -85,7 +91,7 @@ void FocusController::dropRootObject(QObject *object)
dropListView(); dropListView();
setFocusOnDefaultItem(); setFocusOnDefaultItem();
} else { } else {
qWarning() << "===>> TRY TO DROP WRONG ROOT OBJECT: " << m_rootObjects.top() << " SHOULD BE: " << object; logger.warning() << "TRY TO DROP WRONG ROOT OBJECT: " << m_rootObjects.top() << " SHOULD BE: " << object;
} }
} }
@ -101,7 +107,7 @@ void FocusController::reload(Direction direction)
QObject *rootObject = (m_rootObjects.empty() ? m_engine->rootObjects().value(0) : m_rootObjects.top()); QObject *rootObject = (m_rootObjects.empty() ? m_engine->rootObjects().value(0) : m_rootObjects.top());
if (!rootObject) { if (!rootObject) {
qCritical() << "No ROOT OBJECT found!"; logger.error() << "No ROOT OBJECT found!";
resetRootObject(); resetRootObject();
dropListView(); dropListView();
return; return;
@ -113,7 +119,7 @@ void FocusController::reload(Direction direction)
direction == Direction::Forward ? FocusControl::isLess : FocusControl::isMore); direction == Direction::Forward ? FocusControl::isLess : FocusControl::isMore);
if (m_focusChain.empty()) { if (m_focusChain.empty()) {
qWarning() << "Focus chain is empty!"; logger.warning() << "Focus chain is empty!";
resetRootObject(); resetRootObject();
dropListView(); dropListView();
return; return;
@ -131,7 +137,7 @@ void FocusController::nextItem(Direction direction)
} }
if (m_focusChain.empty()) { if (m_focusChain.empty()) {
qWarning() << "There are no items to navigate"; logger.warning() << "There are no items to navigate";
setFocusOnDefaultItem(); setFocusOnDefaultItem();
return; return;
} }
@ -149,7 +155,7 @@ void FocusController::nextItem(Direction direction)
const auto focusedItem = qobject_cast<QQuickItem *>(m_focusChain.at(focusedItemIndex)); const auto focusedItem = qobject_cast<QQuickItem *>(m_focusChain.at(focusedItemIndex));
if (focusedItem == nullptr) { if (focusedItem == nullptr) {
qWarning() << "Failed to get item to focus on. Setting focus on default"; logger.warning() << "Failed to get item to focus on. Setting focus on default";
setFocusOnDefaultItem(); setFocusOnDefaultItem();
return; return;
} }

View file

@ -9,8 +9,6 @@
#include <QStandardPaths> #include <QStandardPaths>
#include <QUrl> #include <QUrl>
#include <iostream>
#include "utilities.h" #include "utilities.h"
#include "version.h" #include "version.h"
@ -27,7 +25,7 @@ QTextStream Logger::m_textStream;
QString Logger::m_logFileName = QString("%1.log").arg(APPLICATION_NAME); QString Logger::m_logFileName = QString("%1.log").arg(APPLICATION_NAME);
QString Logger::m_serviceLogFileName = QString("%1.log").arg(SERVICE_NAME); QString Logger::m_serviceLogFileName = QString("%1.log").arg(SERVICE_NAME);
void debugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{ {
if (msg.simplified().isEmpty()) { if (msg.simplified().isEmpty()) {
return; return;
@ -38,14 +36,21 @@ void debugMessageHandler(QtMsgType type, const QMessageLogContext &context, cons
return; return;
} }
if (msg.startsWith("Unknown property") || msg.startsWith("Could not create pixmap") || msg.startsWith("Populating font") if (msg.startsWith("Unknown property") || msg.startsWith("Could not create pixmap")
|| msg.startsWith("stale focus object")) { || msg.startsWith("Populating font") || msg.startsWith("stale focus object")) {
return; return;
} }
Logger::m_textStream << qFormatLogMessage(type, context, msg) << Qt::endl << Qt::flush; switch (type) {
case QtDebugMsg: Logger::Instance().debug() << msg; break;
std::cout << qFormatLogMessage(type, context, msg).toStdString() << std::endl << std::flush; case QtInfoMsg: Logger::Instance().info() << msg; break;
case QtWarningMsg: Logger::Instance().warning() << msg; break;
case QtCriticalMsg: Logger::Instance().error() << msg; break;
case QtFatalMsg: {
Logger::Instance().error() << msg;
} // Brackets are needed to ensure the destructor of LogStreamer is called before abort()
abort();
}
} }
Logger &Logger::Instance() Logger &Logger::Instance()
@ -57,7 +62,7 @@ Logger &Logger::Instance()
bool Logger::init(bool isServiceLogger) bool Logger::init(bool isServiceLogger)
{ {
QString path = isServiceLogger ? systemLogDir() : userLogsDir(); QString path = isServiceLogger ? systemLogDir() : userLogsDir();
QString logFileName = isServiceLogger ? m_serviceLogFileName : m_logFileName ; QString logFileName = isServiceLogger ? m_serviceLogFileName : m_logFileName;
QDir appDir(path); QDir appDir(path);
if (!appDir.mkpath(path)) { if (!appDir.mkpath(path)) {
return false; return false;
@ -71,19 +76,14 @@ bool Logger::init(bool isServiceLogger)
m_file.setTextModeEnabled(true); m_file.setTextModeEnabled(true);
m_textStream.setDevice(&m_file); m_textStream.setDevice(&m_file);
qSetMessagePattern("%{time yyyy-MM-dd hh:mm:ss} %{type} %{message}");
#if !defined(QT_DEBUG) || defined(Q_OS_IOS) qInstallMessageHandler(messageHandler);
qInstallMessageHandler(debugMessageHandler);
#endif
return true; return true;
} }
void Logger::deInit() void Logger::deInit()
{ {
qInstallMessageHandler(nullptr);
qSetMessagePattern("%{message}");
m_textStream.setDevice(nullptr); m_textStream.setDevice(nullptr);
m_file.close(); m_file.close();
} }
@ -234,76 +234,101 @@ void Logger::cleanUp()
clearLogs(true); clearLogs(true);
} }
Logger::Log::Log(Logger *logger, LogLevel logLevel) : m_logger(logger), m_logLevel(logLevel), m_data(new Data()) Logger::LogStreamer::LogStreamer(Logger *logger, LogLevel logLevel)
: m_logger(logger), m_logLevel(logLevel), m_data(new Data())
{ {
} }
Logger::Log::~Log() Logger::LogStreamer::~LogStreamer()
{ {
qDebug() << "Amnezia" << m_logger->className() << m_data->m_buffer.trimmed(); QString logLevelString;
switch (m_logLevel) {
case LogLevel::Trace: logLevelString = "[TRACE]"; break;
case LogLevel::Debug: logLevelString = "[DEBUG]"; break;
case LogLevel::Info: logLevelString = "[INFO]"; break;
case LogLevel::Warning: logLevelString = "[WARNING]"; break;
case LogLevel::Error: logLevelString = "[ERROR]"; break;
}
const QString message = QString("%1 %2 Amnezia %3 : %4")
.arg(QDateTime::currentDateTimeUtc().toString("[yyyy-MM-dd hh:mm:ss.zzzZ]"),
logLevelString, m_logger->className(), m_data->m_buffer.trimmed());
if (m_file.isOpen()) {
QTextStream logToFile(&m_file);
logToFile << message << Qt::endl << Qt::flush;
}
QTextStream logToOutput((m_logLevel == LogLevel::Error) ? stderr : stdout);
logToOutput << message << Qt::endl << Qt::flush;
delete m_data; delete m_data;
} }
Logger::Log Logger::error() Logger::LogStreamer Logger::error()
{ {
return Log(this, LogLevel::Error); return { this, LogLevel::Error };
} }
Logger::Log Logger::warning()
Logger::LogStreamer Logger::warning()
{ {
return Log(this, LogLevel::Warning); return { this, LogLevel::Warning };
} }
Logger::Log Logger::info()
Logger::LogStreamer Logger::info()
{ {
return Log(this, LogLevel::Info); return { this, LogLevel::Info };
} }
Logger::Log Logger::debug()
Logger::LogStreamer Logger::debug()
{ {
return Log(this, LogLevel::Debug); return { this, LogLevel::Debug };
} }
QString Logger::sensitive(const QString &input) QString Logger::sensitive(const QString &input)
{ {
#ifdef Q_DEBUG #ifdef Q_DEBUG
return input; return input;
#else #else
Q_UNUSED(input); Q_UNUSED(input);
return QString(8, 'X'); return { 8, 'X' };
#endif #endif
} }
#define CREATE_LOG_OP_REF(x) \ #define CREATE_LOGSTREAMER_OP_REF(x) \
Logger::Log &Logger::Log::operator<<(x t) \ Logger::LogStreamer &Logger::LogStreamer::operator<<(x t) \
{ \ { \
m_data->m_ts << t << ' '; \ m_data->m_ts << t << ' '; \
return *this; \ return *this; \
} }
CREATE_LOG_OP_REF(uint64_t); CREATE_LOGSTREAMER_OP_REF(uint64_t);
CREATE_LOG_OP_REF(const char *); CREATE_LOGSTREAMER_OP_REF(const char *);
CREATE_LOG_OP_REF(const QString &); CREATE_LOGSTREAMER_OP_REF(const QString &);
CREATE_LOG_OP_REF(const QByteArray &); CREATE_LOGSTREAMER_OP_REF(const QByteArray &);
CREATE_LOG_OP_REF(const void *); CREATE_LOGSTREAMER_OP_REF(const void *);
#undef CREATE_LOG_OP_REF #undef CREATE_LOGSTREAMER_OP_REF
Logger::Log &Logger::Log::operator<<(const QStringList &t) Logger::LogStreamer &Logger::LogStreamer::operator<<(const QStringList &t)
{ {
m_data->m_ts << '[' << t.join(",") << ']' << ' '; m_data->m_ts << '[' << t.join(",") << ']' << ' ';
return *this; return *this;
} }
Logger::Log &Logger::Log::operator<<(const QJsonObject &t) Logger::LogStreamer &Logger::LogStreamer::operator<<(const QJsonObject &t)
{ {
m_data->m_ts << QJsonDocument(t).toJson(QJsonDocument::Indented) << ' '; m_data->m_ts << QJsonDocument(t).toJson(QJsonDocument::Indented) << ' ';
return *this; return *this;
} }
Logger::Log &Logger::Log::operator<<(QTextStreamFunction t) Logger::LogStreamer &Logger::LogStreamer::operator<<(QTextStreamFunction t)
{ {
m_data->m_ts << t; m_data->m_ts << t;
return *this; return *this;
} }
void Logger::Log::addMetaEnum(quint64 value, const QMetaObject *meta, const char *name) void Logger::LogStreamer::addMetaEnum(quint64 value, const QMetaObject *meta, const char *name)
{ {
QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name)); QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name));

View file

@ -39,28 +39,32 @@ public:
{ {
m_className = className; m_className = className;
} }
Logger(Logger const &) = delete;
Logger &operator=(Logger const &) = delete;
const QString &className() const const QString &className() const
{ {
return m_className; return m_className;
} }
class Log class LogStreamer
{ {
public: public:
Log(Logger *logger, LogLevel level); LogStreamer(Logger *logger, LogLevel level);
~Log(); ~LogStreamer();
Log &operator<<(uint64_t t); LogStreamer &operator<<(uint64_t t);
Log &operator<<(const char *t); LogStreamer &operator<<(const char *t);
Log &operator<<(const QString &t); LogStreamer &operator<<(const QString &t);
Log &operator<<(const QStringList &t); LogStreamer &operator<<(const QStringList &t);
Log &operator<<(const QByteArray &t); LogStreamer &operator<<(const QByteArray &t);
Log &operator<<(const QJsonObject &t); LogStreamer &operator<<(const QJsonObject &t);
Log &operator<<(QTextStreamFunction t); LogStreamer &operator<<(QTextStreamFunction t);
Log &operator<<(const void *t); LogStreamer &operator<<(const void *t);
// Q_ENUM // Q_ENUM
template<typename T> typename std::enable_if<QtPrivate::IsQEnumHelper<T>::Value, Log &>::type operator<<(T t) template<typename T> typename std::enable_if<QtPrivate::IsQEnumHelper<T>::Value, LogStreamer &>::type operator<<(T t)
{ {
const QMetaObject *meta = qt_getEnumMetaObject(t); const QMetaObject *meta = qt_getEnumMetaObject(t);
const char *name = qt_getEnumName(t); const char *name = qt_getEnumName(t);
@ -87,16 +91,14 @@ public:
Data *m_data; Data *m_data;
}; };
Log error(); LogStreamer error();
Log warning(); LogStreamer warning();
Log info(); LogStreamer info();
Log debug(); LogStreamer debug();
QString sensitive(const QString &input); QString sensitive(const QString &input);
private: private:
Logger() {}; Logger() = default;
Logger(Logger const &) = delete;
Logger &operator=(Logger const &) = delete;
static QString userLogsDir(); static QString userLogsDir();
@ -105,7 +107,7 @@ private:
static QString m_logFileName; static QString m_logFileName;
static QString m_serviceLogFileName; static QString m_serviceLogFileName;
friend void debugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg); friend void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);
// compat with Mozilla logger // compat with Mozilla logger
QString m_className; QString m_className;