refactor: better logger
This commit is contained in:
+1
-1
@@ -28,7 +28,7 @@ if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
|||||||
${PROJECT_SOURCES}
|
${PROJECT_SOURCES}
|
||||||
src/images_carousel.h src/images_carousel.cpp src/designer/images_carousel.ui
|
src/images_carousel.h src/images_carousel.cpp src/designer/images_carousel.ui
|
||||||
src/config.h src/config.cpp
|
src/config.h src/config.cpp
|
||||||
src/logger.h
|
src/logger.h src/logger.cpp
|
||||||
src/loading_indicator.h src/loading_indicator.cpp src/designer/loading_indicator.ui
|
src/loading_indicator.h src/loading_indicator.cpp src/designer/loading_indicator.ui
|
||||||
)
|
)
|
||||||
# Define target properties for Android with Qt 6 as:
|
# Define target properties for Android with Qt 6 as:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: Uyanide pywang0608@foxmail.com
|
* @Author: Uyanide pywang0608@foxmail.com
|
||||||
* @Date: 2025-08-05 01:22:53
|
* @Date: 2025-08-05 01:22:53
|
||||||
* @LastEditTime: 2025-08-07 00:50:11
|
* @LastEditTime: 2025-08-07 02:01:23
|
||||||
* @Description: Animated carousel widget for displaying and selecting images.
|
* @Description: Animated carousel widget for displaying and selecting images.
|
||||||
*/
|
*/
|
||||||
#include "images_carousel.h"
|
#include "images_carousel.h"
|
||||||
@@ -172,6 +172,7 @@ void ImageLoader::run() {
|
|||||||
ImageData::ImageData(const QString& p, const int initWidth, const int initHeight) : file(p) {
|
ImageData::ImageData(const QString& p, const int initWidth, const int initHeight) : file(p) {
|
||||||
if (!image.load(p)) {
|
if (!image.load(p)) {
|
||||||
warn(QString("Failed to load image from path: %1").arg(p));
|
warn(QString("Failed to load image from path: %1").arg(p));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// resize in "cover" mode
|
// resize in "cover" mode
|
||||||
const QSize targetSize(initWidth, initHeight);
|
const QSize targetSize(initWidth, initHeight);
|
||||||
@@ -290,7 +291,12 @@ ImageItem::ImageItem(const ImageData* data,
|
|||||||
m_itemSize(itemWidth, itemHeight),
|
m_itemSize(itemWidth, itemHeight),
|
||||||
m_itemFocusSize(itemFocusWidth, itemFocusHeight) {
|
m_itemFocusSize(itemFocusWidth, itemFocusHeight) {
|
||||||
setScaledContents(true);
|
setScaledContents(true);
|
||||||
setPixmap(QPixmap::fromImage(data->image));
|
if (data->image.isNull()) {
|
||||||
|
setText(":(");
|
||||||
|
setAlignment(Qt::AlignCenter);
|
||||||
|
} else {
|
||||||
|
setPixmap(QPixmap::fromImage(data->image));
|
||||||
|
}
|
||||||
setFixedSize(itemWidth, itemHeight);
|
setFixedSize(itemWidth, itemHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* @Author: Uyanide pywang0608@foxmail.com
|
||||||
|
* @Date: 2025-08-07 01:12:37
|
||||||
|
* @LastEditTime: 2025-08-07 01:55:56
|
||||||
|
* @Description: Implementation of logger.
|
||||||
|
*/
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QProcessEnvironment>
|
||||||
|
#include <QString>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QThreadPool>
|
||||||
|
|
||||||
|
#ifdef GENERAL_LOGGER_DISABLED
|
||||||
|
#define ENSURE_ENABLED return;
|
||||||
|
#else
|
||||||
|
#define ENSURE_ENABLED
|
||||||
|
static QTextStream s_logStream(stderr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Logger* Logger::instance(FILE* stream) {
|
||||||
|
static Logger* logger{};
|
||||||
|
if (!logger) {
|
||||||
|
if (!stream) {
|
||||||
|
stream = stderr; // Default to stderr if no stream provided
|
||||||
|
}
|
||||||
|
logger = new Logger(stream);
|
||||||
|
}
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::Logger(FILE* stream, QObject* parent)
|
||||||
|
: QObject(parent), m_stream(stream), m_logStream(stream) {
|
||||||
|
connect(this,
|
||||||
|
&Logger::logSig,
|
||||||
|
this,
|
||||||
|
&Logger::_log,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::_log(
|
||||||
|
const QString& msg,
|
||||||
|
const QString& levelString,
|
||||||
|
const QString& levelColorString,
|
||||||
|
const QString& textColorString,
|
||||||
|
const GeneralLogger::LogIndent indent) {
|
||||||
|
ENSURE_ENABLED
|
||||||
|
|
||||||
|
s_logStream << levelColorString << levelString << ' ';
|
||||||
|
for (qint32 i = 0; i < indent; i++) s_logStream << " ";
|
||||||
|
s_logStream << textColorString << msg << (textColorString.isEmpty() ? "\n" : "\033[0m\n");
|
||||||
|
s_logStream.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Logger::isColored() {
|
||||||
|
const auto stream = Logger::instance()->m_stream;
|
||||||
|
if (!isatty(fileno(stream))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||||
|
QString term = env.value("TERM");
|
||||||
|
if (term.isEmpty() || term == "dumb") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeneralLogger::info(
|
||||||
|
const QString& msg,
|
||||||
|
const GeneralLogger::LogIndent indent) {
|
||||||
|
ENSURE_ENABLED
|
||||||
|
constexpr const char* colorInfoMsg[]{"\033[32m", "\033[0m", "\033[0m"};
|
||||||
|
const auto color = Logger::isColored();
|
||||||
|
emit Logger::instance() -> logSig(msg,
|
||||||
|
"[INFO]",
|
||||||
|
color ? "\033[92m" : "",
|
||||||
|
color ? colorInfoMsg[indent] : "",
|
||||||
|
indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeneralLogger::warn(
|
||||||
|
const QString& msg,
|
||||||
|
const GeneralLogger::LogIndent indent) {
|
||||||
|
ENSURE_ENABLED
|
||||||
|
const auto color = Logger::isColored();
|
||||||
|
emit Logger::instance() -> logSig(msg,
|
||||||
|
"[WARN]",
|
||||||
|
color ? "\033[93m" : "",
|
||||||
|
color ? "\033[33m" : "",
|
||||||
|
indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeneralLogger::error(
|
||||||
|
const QString& msg,
|
||||||
|
const GeneralLogger::LogIndent indent) {
|
||||||
|
ENSURE_ENABLED
|
||||||
|
const auto color = Logger::isColored();
|
||||||
|
emit Logger::instance() -> logSig(msg,
|
||||||
|
"[ERROR]",
|
||||||
|
color ? "\033[91m" : "",
|
||||||
|
color ? "\033[31m" : "",
|
||||||
|
indent);
|
||||||
|
}
|
||||||
+34
-43
@@ -1,71 +1,62 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: Uyanide pywang0608@foxmail.com
|
* @Author: Uyanide pywang0608@foxmail.com
|
||||||
* @Date: 2025-08-05 10:43:31
|
* @Date: 2025-08-05 10:43:31
|
||||||
* @LastEditTime: 2025-08-05 17:25:18
|
* @LastEditTime: 2025-08-07 01:55:42
|
||||||
* @Description: A simple logger for general use.
|
* @Description: A simple thread-safe logger for general use.
|
||||||
* g_logStream must be defined somewhere else in the project.
|
|
||||||
*/
|
*/
|
||||||
#ifndef GENERAL_LOGGER_H
|
#ifndef GENERAL_LOGGER_H
|
||||||
#define GENERAL_LOGGER_H
|
#define GENERAL_LOGGER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
namespace GeneralLogger {
|
namespace GeneralLogger {
|
||||||
|
|
||||||
inline constexpr const char* colorInfoMsg[]{"\033[32m", "\033[0m", "\033[0m"};
|
|
||||||
|
|
||||||
enum LogIndent : qint32 {
|
enum LogIndent : qint32 {
|
||||||
GENERAL = 0,
|
GENERAL = 0,
|
||||||
STEP = 1,
|
STEP = 1,
|
||||||
DETAIL = 2,
|
DETAIL = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef GENERAL_LOGGER_DISABLED
|
void info(const QString& msg,
|
||||||
#define ENSURE_ENABLED return;
|
const LogIndent indent = GENERAL);
|
||||||
#else
|
|
||||||
#define ENSURE_ENABLED
|
|
||||||
extern QTextStream g_logStream;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void
|
void warn(const QString& msg,
|
||||||
info(const QString& msg,
|
const LogIndent indent = GENERAL);
|
||||||
const LogIndent indent = GENERAL,
|
|
||||||
const bool color = true) {
|
|
||||||
ENSURE_ENABLED
|
|
||||||
|
|
||||||
g_logStream << (color ? "\033[92m" : "") << "[INFO] ";
|
void error(const QString& msg,
|
||||||
for (qint32 i = 0; i < indent; i++) g_logStream << " ";
|
const LogIndent indent = GENERAL);
|
||||||
g_logStream << (color ? colorInfoMsg[indent] : "") << msg << (color ? "\033[0m\n" : "\n");
|
} // namespace GeneralLogger
|
||||||
g_logStream.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
class Logger : public QObject {
|
||||||
warn(const QString& msg,
|
Q_OBJECT
|
||||||
const LogIndent indent = GENERAL,
|
|
||||||
const bool color = true) {
|
|
||||||
ENSURE_ENABLED
|
|
||||||
|
|
||||||
g_logStream << (color ? "\033[93m" : "") << "[WARN] ";
|
public:
|
||||||
for (uint32_t i = 0; i < indent; i++) g_logStream << " ";
|
static Logger* instance(FILE* stream = nullptr);
|
||||||
g_logStream << (color ? "\033[33m" : "") << msg << (color ? "\033[0m\n" : "\n");
|
|
||||||
g_logStream.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
static bool isColored();
|
||||||
error(const QString& msg,
|
|
||||||
const LogIndent indent = GENERAL,
|
|
||||||
const bool color = true) {
|
|
||||||
ENSURE_ENABLED
|
|
||||||
|
|
||||||
g_logStream << (color ? "\033[91m" : "") << "[ERROR] ";
|
private:
|
||||||
for (uint32_t i = 0; i < indent; i++) g_logStream << " ";
|
explicit Logger(FILE* stream, QObject* parent = nullptr);
|
||||||
g_logStream << (color ? "\033[31m" : "") << msg << (color ? "\033[0m\n" : "\n");
|
|
||||||
g_logStream.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef ENSURE_ENABLED
|
private slots:
|
||||||
|
void _log(const QString& msg,
|
||||||
|
const QString& levelString,
|
||||||
|
const QString& levelColorString,
|
||||||
|
const QString& textColorString,
|
||||||
|
const GeneralLogger::LogIndent indent);
|
||||||
|
|
||||||
}; // namespace GeneralLogger
|
private:
|
||||||
|
FILE* m_stream;
|
||||||
|
QTextStream m_logStream;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void logSig(const QString& msg,
|
||||||
|
const QString& levelString,
|
||||||
|
const QString& levelColorString,
|
||||||
|
const QString& textColorString,
|
||||||
|
const GeneralLogger::LogIndent indent);
|
||||||
|
};
|
||||||
|
|
||||||
#endif // GENERAL_LOGGER_H
|
#endif // GENERAL_LOGGER_H
|
||||||
|
|||||||
+1
-4
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: Uyanide pywang0608@foxmail.com
|
* @Author: Uyanide pywang0608@foxmail.com
|
||||||
* @Date: 2025-08-05 00:37:58
|
* @Date: 2025-08-05 00:37:58
|
||||||
* @LastEditTime: 2025-08-05 19:42:07
|
* @LastEditTime: 2025-08-07 01:49:07
|
||||||
* @Description: Entry point.
|
* @Description: Entry point.
|
||||||
*/
|
*/
|
||||||
#include <qapplication.h>
|
#include <qapplication.h>
|
||||||
@@ -12,11 +12,8 @@
|
|||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "logger.h"
|
|
||||||
#include "main_window.h"
|
#include "main_window.h"
|
||||||
|
|
||||||
QTextStream GeneralLogger::g_logStream(stderr);
|
|
||||||
|
|
||||||
static QString getConfigDir() {
|
static QString getConfigDir() {
|
||||||
auto configDir = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
|
auto configDir = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
|
||||||
if (configDir.isEmpty()) {
|
if (configDir.isEmpty()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user