♻️ refactor: logging

This commit is contained in:
2026-02-27 17:02:19 +01:00
parent c8acbf1319
commit 1ccb26f42b
15 changed files with 230 additions and 174 deletions
+22 -20
View File
@@ -10,6 +10,8 @@
#include "logger.hpp"
WALLREEL_DECLARE_SENDER("CacheManager")
using namespace Qt::StringLiterals;
namespace WallReel::Core::Cache {
@@ -22,7 +24,7 @@ QString Manager::cacheKey(const QFileInfo& fileInfo, const QSize& imageSize) {
Manager::Manager(const QDir& cacheDir)
: m_cacheDir(cacheDir), m_dbPath(cacheDir.filePath(u"cache.db"_s)), m_connectionPrefix(u"WallReelCache:"_s + QString::fromLatin1(QCryptographicHash::hash(m_dbPath.toUtf8(), QCryptographicHash::Md5).toHex())) {
Logger::debug(u"Initializing cache db: %1"_s.arg(m_dbPath));
WR_DEBUG(u"Initializing cache db: %1"_s.arg(m_dbPath));
// Open a connection on the constructing thread so the schema is
// guaranteed to exist before any worker thread first calls _db().
_db();
@@ -34,7 +36,7 @@ Manager::~Manager() {
QMutexLocker lock(&m_connectionsMutex);
names = std::move(m_connectionNames);
}
Logger::debug(u"Closing %1 cache db connection(s)"_s.arg(names.size()));
WR_DEBUG(u"Closing %1 cache db connection(s)"_s.arg(names.size()));
for (const QString& connName : std::as_const(names)) {
{
// Scope: release the QSqlDatabase copy before removeDatabase()
@@ -61,12 +63,12 @@ void Manager::clearCache(Type type) {
}
}
QSqlQuery(db).exec(QStringLiteral("DELETE FROM image_cache"));
Logger::info(u"Cleared %1 image cache file(s)"_s.arg(removed));
WR_INFO(u"Cleared %1 image cache file(s)"_s.arg(removed));
}
if ((type & Type::Color) != Type::None) {
QSqlQuery(db).exec(QStringLiteral("DELETE FROM color_cache"));
Logger::info(u"Cleared color cache"_s);
WR_INFO(u"Cleared color cache"_s);
}
}
@@ -79,7 +81,7 @@ QColor Manager::getColor(const QString& key, const std::function<QColor()>& comp
query.bindValue(u":key"_s, key);
if (query.exec() && query.next()) {
Logger::debug(u"Color cache hit [%1]"_s.arg(key));
WR_DEBUG(u"Color cache hit [%1]"_s.arg(key));
return QColor(
query.value(0).toInt(),
query.value(1).toInt(),
@@ -88,11 +90,11 @@ QColor Manager::getColor(const QString& key, const std::function<QColor()>& comp
}
}
Logger::debug(u"Color cache miss [%1], computing"_s.arg(key));
WR_DEBUG(u"Color cache miss [%1], computing"_s.arg(key));
const QColor color = computeFunc();
if (!color.isValid()) {
Logger::warn(u"ComputeFunc returned invalid color for key [%1]"_s.arg(key));
WR_WARN(u"ComputeFunc returned invalid color for key [%1]"_s.arg(key));
return color;
}
@@ -107,10 +109,10 @@ QColor Manager::getColor(const QString& key, const std::function<QColor()>& comp
insertQuery.bindValue(u":b"_s, color.blue());
insertQuery.bindValue(u":a"_s, color.alpha());
if (!insertQuery.exec())
Logger::warn(u"Failed to cache color [%1]: %2"_s
WR_WARN(u"Failed to cache color [%1]: %2"_s
.arg(key, insertQuery.lastError().text()));
else
Logger::debug(u"Color cached [%1]"_s.arg(key));
WR_DEBUG(u"Color cached [%1]"_s.arg(key));
}
return color;
@@ -127,13 +129,13 @@ QFileInfo Manager::getImage(const QString& key, const std::function<QImage()>& c
if (query.exec() && query.next()) {
const QFileInfo cached(m_cacheDir.filePath(query.value(0).toString()));
if (cached.exists()) {
Logger::debug(u"Image cache hit [%1] -> %2"_s
WR_DEBUG(u"Image cache hit [%1] -> %2"_s
.arg(key, cached.absoluteFilePath()));
return cached;
}
// File was deleted externally — evict the stale DB record.
Logger::warn(u"Image cache stale, file missing [%1], evicting"_s.arg(key));
WR_WARN(u"Image cache stale, file missing [%1], evicting"_s.arg(key));
QSqlQuery evict(db);
evict.prepare(QStringLiteral("DELETE FROM image_cache WHERE key = :key"));
evict.bindValue(u":key"_s, key);
@@ -141,10 +143,10 @@ QFileInfo Manager::getImage(const QString& key, const std::function<QImage()>& c
}
}
Logger::debug(u"Image cache miss [%1], computing"_s.arg(key));
WR_DEBUG(u"Image cache miss [%1], computing"_s.arg(key));
const QImage image = computeFunc();
if (image.isNull()) {
Logger::warn(u"ComputeFunc returned null image for key [%1]"_s.arg(key));
WR_WARN(u"ComputeFunc returned null image for key [%1]"_s.arg(key));
return QFileInfo{};
}
@@ -152,10 +154,10 @@ QFileInfo Manager::getImage(const QString& key, const std::function<QImage()>& c
const QString filePath = m_cacheDir.filePath(fileName);
if (!image.save(filePath, "PNG")) {
Logger::warn(u"Failed to save image to %1"_s.arg(filePath));
WR_WARN(u"Failed to save image to %1"_s.arg(filePath));
return QFileInfo{};
}
Logger::debug(u"Image saved to %1"_s.arg(filePath));
WR_DEBUG(u"Image saved to %1"_s.arg(filePath));
if (db.isOpen()) {
QSqlQuery insertQuery(db);
@@ -165,7 +167,7 @@ QFileInfo Manager::getImage(const QString& key, const std::function<QImage()>& c
insertQuery.bindValue(u":key"_s, key);
insertQuery.bindValue(u":file_name"_s, fileName);
if (!insertQuery.exec())
Logger::warn(u"Failed to record image in db [%1]: %2"_s
WR_WARN(u"Failed to record image in db [%1]: %2"_s
.arg(key, insertQuery.lastError().text()));
}
@@ -185,9 +187,9 @@ QSqlDatabase Manager::_db() const {
if (db.isOpen())
return db;
// Reopen if closed externally.
Logger::debug(u"Reopening cache db connection [%1]"_s.arg(*it));
WR_DEBUG(u"Reopening cache db connection [%1]"_s.arg(*it));
if (!db.open()) {
Logger::warn(u"Cannot reopen cache database: %1"_s.arg(db.lastError().text()));
WR_WARN(u"Cannot reopen cache database: %1"_s.arg(db.lastError().text()));
return QSqlDatabase{};
}
QSqlQuery q(db);
@@ -204,13 +206,13 @@ QSqlDatabase Manager::_db() const {
db.setDatabaseName(m_dbPath);
if (!db.open()) {
Logger::warn(u"Cannot open cache database %1: %2"_s
WR_WARN(u"Cannot open cache database %1: %2"_s
.arg(m_dbPath, db.lastError().text()));
db = QSqlDatabase{};
QSqlDatabase::removeDatabase(connName);
return QSqlDatabase{};
}
Logger::debug(u"Opened cache db connection [%1]"_s.arg(connName));
WR_DEBUG(u"Opened cache db connection [%1]"_s.arg(connName));
tlsConns.insert(m_connectionPrefix, connName);
{
+24 -22
View File
@@ -13,6 +13,8 @@
#include "Utils/misc.hpp"
#include "logger.hpp"
WALLREEL_DECLARE_SENDER("ConfigManager")
WallReel::Core::Config::Manager::Manager(
const QDir& configDir,
const QStringList& searchDirs,
@@ -21,20 +23,20 @@ WallReel::Core::Config::Manager::Manager(
: QObject(parent), m_configDir(configDir) {
// Load configPath if not empty, otherwise load from default location (configDir + s_DefaultConfigFileName)
if (configPath.isEmpty()) {
Logger::info(QString("Configuration directory: %1").arg(m_configDir.absolutePath()));
WR_INFO(QString("Configuration directory: %1").arg(m_configDir.absolutePath()));
_loadConfig(m_configDir.absolutePath() + QDir::separator() + s_DefaultConfigFileName);
} else {
_loadConfig(configPath);
}
// Append additional search directories to the config
if (!searchDirs.isEmpty()) {
Logger::info(QString("Additional search directories: %1").arg(searchDirs.join(", ")));
WR_INFO(QString("Additional search directories: %1").arg(searchDirs.join(", ")));
for (const auto& dir : searchDirs) {
m_wallpaperConfig.dirs.append({dir, false});
}
}
Logger::debug("Loading wallpapers ...");
WR_DEBUG("Loading wallpapers ...");
_loadWallpapers();
}
@@ -42,10 +44,10 @@ WallReel::Core::Config::Manager::~Manager() {
}
void WallReel::Core::Config::Manager::_loadConfig(const QString& configPath) {
Logger::info(QString("Loading configuration from: %1").arg(configPath));
WR_INFO(QString("Loading configuration from: %1").arg(configPath));
QFile configFile(configPath);
if (!configFile.open(QIODevice::ReadOnly)) {
Logger::critical(QString("Failed to open config file: %1").arg(configPath));
WR_CRITICAL(QString("Failed to open config file: %1").arg(configPath));
return;
}
QByteArray configData = configFile.readAll();
@@ -53,7 +55,7 @@ void WallReel::Core::Config::Manager::_loadConfig(const QString& configPath) {
QJsonDocument jsonDoc = QJsonDocument::fromJson(configData);
if (jsonDoc.isNull() || !jsonDoc.isObject()) {
Logger::critical(QString("Invalid JSON format in config file"));
WR_CRITICAL(QString("Invalid JSON format in config file"));
return;
}
@@ -103,7 +105,7 @@ void WallReel::Core::Config::Manager::_loadWallpaperConfig(const QJsonObject& ro
if (item.isString()) {
auto regex = QRegularExpression(item.toString());
if (!regex.isValid()) {
Logger::warn(QString("Invalid regular expression in config: %1").arg(item.toString()));
WR_WARN(QString("Invalid regular expression in config: %1").arg(item.toString()));
} else {
m_wallpaperConfig.excludes.append(regex);
}
@@ -146,7 +148,7 @@ void WallReel::Core::Config::Manager::_loadThemeConfig(const QJsonObject& root)
if (color.isValid()) {
colorConfig.value = color;
} else {
Logger::warn(QString("Invalid color string in config: %1").arg(colorObj["value"].toString()));
WR_WARN(QString("Invalid color string in config: %1").arg(colorObj["value"].toString()));
}
}
} else if (colorItem.isString()) {
@@ -154,7 +156,7 @@ void WallReel::Core::Config::Manager::_loadThemeConfig(const QJsonObject& root)
if (color.isValid()) {
colorConfig.value = color;
} else {
Logger::warn(QString("Invalid color string in config: %1").arg(colorItem.toString()));
WR_WARN(QString("Invalid color string in config: %1").arg(colorItem.toString()));
}
}
if (colorConfig.value.isValid()) {
@@ -305,7 +307,7 @@ void WallReel::Core::Config::Manager::_loadSortConfig(const QJsonObject& root) {
} else if (type == "size") {
m_sortConfig.type = SortType::Size;
} else {
Logger::warn(QString("Unknown sort type: %1").arg(type));
WR_WARN(QString("Unknown sort type: %1").arg(type));
}
}
}
@@ -324,12 +326,12 @@ void WallReel::Core::Config::Manager::_loadWallpapers() {
QSet<QString> paths;
Logger::debug(QString("Loading wallpapers from %1 specified paths...").arg(m_wallpaperConfig.paths.size()));
WR_DEBUG(QString("Loading wallpapers from %1 specified paths...").arg(m_wallpaperConfig.paths.size()));
for (const QString& path : std::as_const(m_wallpaperConfig.paths)) {
paths.insert(path);
}
Logger::debug(QString("Loading wallpapers from %1 specified directories...").arg(m_wallpaperConfig.dirs.size()));
WR_DEBUG(QString("Loading wallpapers from %1 specified directories...").arg(m_wallpaperConfig.dirs.size()));
for (const auto& dirConfig : std::as_const(m_wallpaperConfig.dirs)) {
if (Utils::checkDir(dirConfig.path)) {
std::function<void(const QDir&)> scanDir;
@@ -342,7 +344,7 @@ void WallReel::Core::Config::Manager::_loadWallpapers() {
if (dirConfig.recursive) {
QStringList subDirs = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
Logger::debug(QString("Scanning directory '%1' for subdirectories... Found %2").arg(d.absolutePath()).arg(subDirs.size()));
WR_DEBUG(QString("Scanning directory '%1' for subdirectories... Found %2").arg(d.absolutePath()).arg(subDirs.size()));
for (const QString& subDir : std::as_const(subDirs)) {
scanDir(QDir(d.filePath(subDir)));
}
@@ -350,19 +352,19 @@ void WallReel::Core::Config::Manager::_loadWallpapers() {
};
scanDir(QDir(dirConfig.path));
} else {
Logger::warn(QString("Directory '%1' does not exist").arg(dirConfig.path));
WR_WARN(QString("Directory '%1' does not exist").arg(dirConfig.path));
}
}
// Exclude paths that match any of the exclude regexes
Logger::debug(QString("Excluding %1 specified paths...").arg(m_wallpaperConfig.excludes.size()));
WR_DEBUG(QString("Excluding %1 specified paths...").arg(m_wallpaperConfig.excludes.size()));
QStringList toRemove;
for (const auto& exclude : std::as_const(m_wallpaperConfig.excludes)) {
for (const QString& path : std::as_const(paths)) {
if (exclude.match(path).hasMatch()) {
toRemove.append(path);
Logger::debug(QString("Excluded path '%1' matched by regex '%2'").arg(path).arg(exclude.pattern()));
WR_DEBUG(QString("Excluded path '%1' matched by regex '%2'").arg(path).arg(exclude.pattern()));
}
}
}
@@ -375,16 +377,16 @@ void WallReel::Core::Config::Manager::_loadWallpapers() {
if (Utils::checkImageFile(path)) {
m_wallpapers.append(path);
} else {
Logger::warn(QString("File '%1' is not recognized as a valid image file").arg(path));
WR_WARN(QString("File '%1' is not recognized as a valid image file").arg(path));
}
}
Logger::info(QString("Found %1 images").arg(paths.size()));
WR_INFO(QString("Found %1 images").arg(paths.size()));
}
void WallReel::Core::Config::Manager::captureState() {
if (m_pendingCaptures > 0) {
Logger::warn("State capture already in progress, ignoring new capture request");
WR_WARN("State capture already in progress, ignoring new capture request");
return;
}
@@ -430,7 +432,7 @@ void WallReel::Core::Config::Manager::captureState() {
process->disconnect();
QString result = success ? output : defaultVal;
Logger::debug(QString("Capture result for key '%1': %2 (success: %3)").arg(key).arg(result).arg(success));
WR_DEBUG(QString("Capture result for key '%1': %2 (success: %3)").arg(key).arg(result).arg(success));
if (result.isEmpty()) result = defaultVal;
_onCaptureResult(key, result);
@@ -440,7 +442,7 @@ void WallReel::Core::Config::Manager::captureState() {
if (timer) {
// Timeout handler
connect(timer, &QTimer::timeout, this, [process, onFinished, key]() {
Logger::warn(QString("Timeout capturing state for key '%1'").arg(key));
WR_WARN(QString("Timeout capturing state for key '%1'").arg(key));
if (process->state() != QProcess::NotRunning) {
process->kill();
} else {
@@ -462,7 +464,7 @@ void WallReel::Core::Config::Manager::captureState() {
// Error handler
connect(process, &QProcess::errorOccurred, this, [process, onFinished, key](QProcess::ProcessError error) {
if (error == QProcess::FailedToStart) {
Logger::warn(QString("Failed to start state command for key '%1'").arg(key));
WR_WARN(QString("Failed to start state command for key '%1'").arg(key));
onFinished(QString(), false);
}
});
+26 -24
View File
@@ -4,6 +4,9 @@
#include <QImageReader>
#include "Palette/domcolor.hpp"
#include "logger.hpp"
WALLREEL_DECLARE_SENDER("ImageData")
WallReel::Core::Image::Data* WallReel::Core::Image::Data::create(
const QString& path,
@@ -20,9 +23,29 @@ WallReel::Core::Image::Data* WallReel::Core::Image::Data::create(
WallReel::Core::Image::Data::Data(const QString& path, const QSize& targetSize, Cache::Manager& cacheMgr)
: m_cacheMgr(cacheMgr), m_file(path), m_targetSize(targetSize) {
m_id = cacheMgr.cacheKey(m_file, m_targetSize);
m_cachedFile = cacheMgr.getImage(m_id, [this]() {
m_cachedFile = cacheMgr.getImage(m_id, [this]() { return computeImage(); });
m_dominantColor = cacheMgr.getColor(m_id, [this]() { return computeDominantColor(loadImage()); });
}
QImage WallReel::Core::Image::Data::loadImage() const {
QImageReader reader(m_cachedFile.absoluteFilePath());
if (!reader.canRead()) {
WR_WARN("Cannot read cached image: " + m_cachedFile.absoluteFilePath());
return QImage();
}
QImage image;
if (!reader.read(&image)) {
WR_WARN("Failed to read cached image: " + m_cachedFile.absoluteFilePath());
return QImage();
}
return image;
}
QImage WallReel::Core::Image::Data::computeImage() const {
QImageReader reader(m_file.absoluteFilePath());
if (!reader.canRead()) {
WR_WARN("Cannot read image file: " + m_file.absoluteFilePath());
return QImage();
}
@@ -44,6 +67,7 @@ WallReel::Core::Image::Data::Data(const QString& path, const QSize& targetSize,
QImage image;
if (!reader.read(&image)) {
WR_WARN("Failed to read image file: " + m_file.absoluteFilePath());
return QImage();
}
@@ -64,30 +88,8 @@ WallReel::Core::Image::Data::Data(const QString& path, const QSize& targetSize,
image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
}
return image;
});
m_dominantColor = cacheMgr.getColor(m_id, [this]() {
QImageReader reader(m_cachedFile.absoluteFilePath());
if (!reader.canRead()) {
return QColor();
}
QImage image;
if (!reader.read(&image)) {
return QColor();
}
QColor WallReel::Core::Image::Data::computeDominantColor(const QImage& image) const {
return Palette::getDominantColor(image);
});
}
QImage WallReel::Core::Image::Data::loadImage() const {
QImageReader reader(m_cachedFile.absoluteFilePath());
if (!reader.canRead()) {
return QImage();
}
QImage image;
if (!reader.read(&image)) {
return QImage();
}
return image;
}
+3
View File
@@ -54,6 +54,9 @@ class Data {
QColor m_dominantColor; ///< Dominant color of the image, used for palette matching
QHash<QString, QString> m_colorCache; ///< Cache for palette color matching results, key is palette name, value is matched color name
QImage computeImage() const;
QColor computeDominantColor(const QImage& image) const;
Data(const QString& path, const QSize& size, Cache::Manager& cacheMgr);
public:
+18 -16
View File
@@ -6,6 +6,8 @@
#include "data.hpp"
#include "logger.hpp"
WALLREEL_DECLARE_SENDER("ImageModel")
WallReel::Core::Image::Model::Model(
const Config::SortConfigItems& sortConfig,
Cache::Manager& cacheMgr,
@@ -54,16 +56,16 @@ int WallReel::Core::Image::Model::rowCount(const QModelIndex& parent) const {
QVariant WallReel::Core::Image::Model::data(const QModelIndex& index, int role) const {
if (!index.isValid() || index.row() >= m_filteredIndices.count()) {
Logger::debug("Invalid index requested: " + QString::number(index.row()));
WR_DEBUG("Invalid index requested: " + QString::number(index.row()));
return QVariant();
}
int actualIndex = _convertProxyIndex(index.row());
if (actualIndex < 0 || actualIndex >= m_data.count()) {
Logger::debug("Actual index out of bounds: " + QString::number(actualIndex));
WR_DEBUG("Actual index out of bounds: " + QString::number(actualIndex));
return QVariant();
}
// Logger::debug("Data requested for index: " + QString::number(index.row()) + ", actual index: " + QString::number(actualIndex) + ", role: " + QString::number(role));
// WR_DEBUG("Data requested for index: " + QString::number(index.row()) + ", actual index: " + QString::number(actualIndex) + ", role: " + QString::number(role));
const auto& item = m_data[actualIndex];
switch (role) {
case IdRole:
@@ -120,7 +122,7 @@ void WallReel::Core::Image::Model::setCurrentSortReverse(bool reverse) {
}
void WallReel::Core::Image::Model::setSearchText(const QString& text) {
// Logger::debug("Search text changed: " + text);
// WR_DEBUG("Search text changed: " + text);
if (m_searchText != text) {
m_searchText = text;
_applySearchFilter();
@@ -130,12 +132,12 @@ void WallReel::Core::Image::Model::setSearchText(const QString& text) {
WallReel::Core::Image::Data* WallReel::Core::Image::Model::imageAt(int index) {
if (index < 0 || index >= m_filteredIndices.count()) {
Logger::debug("Invalid index requested: " + QString::number(index));
WR_DEBUG("Invalid index requested: " + QString::number(index));
return nullptr;
}
int actualIndex = _convertProxyIndex(index);
if (actualIndex < 0 || actualIndex >= m_data.count()) {
Logger::debug("Actual index out of bounds: " + QString::number(actualIndex));
WR_DEBUG("Actual index out of bounds: " + QString::number(actualIndex));
return nullptr;
}
return m_data[actualIndex];
@@ -147,13 +149,13 @@ WallReel::Core::Image::Data* WallReel::Core::Image::Model::focusedImage() {
QVariant WallReel::Core::Image::Model::dataAt(int index, const QString& roleName) const {
if (index < 0 || index >= m_filteredIndices.count()) {
Logger::debug("Invalid index requested: " + QString::number(index));
WR_DEBUG("Invalid index requested: " + QString::number(index));
return QVariant();
}
int actualIndex = _convertProxyIndex(index);
if (actualIndex < 0 || actualIndex >= m_data.count()) {
Logger::debug("Actual index out of bounds: " + QString::number(actualIndex));
WR_DEBUG("Actual index out of bounds: " + QString::number(actualIndex));
return QVariant();
}
const auto& item = m_data[actualIndex];
@@ -172,7 +174,7 @@ QVariant WallReel::Core::Image::Model::dataAt(int index, const QString& roleName
void WallReel::Core::Image::Model::loadAndProcess(const QStringList& paths) {
if (m_isLoading) {
Logger::warn("Already loading images. Ignoring new load request.");
WR_WARN("Already loading images. Ignoring new load request.");
return;
}
m_isLoading = true;
@@ -198,12 +200,12 @@ void WallReel::Core::Image::Model::loadAndProcess(const QStringList& paths) {
void WallReel::Core::Image::Model::focusOnIndex(int index) {
if (index < 0 || index >= m_filteredIndices.count()) {
Logger::debug("Invalid index to focus on: " + QString::number(index));
WR_DEBUG("Invalid index to focus on: " + QString::number(index));
return;
}
int actualIndex = _convertProxyIndex(index);
if (actualIndex < 0 || actualIndex >= m_data.count()) {
Logger::debug("Actual index out of bounds for focus: " + QString::number(actualIndex));
WR_DEBUG("Actual index out of bounds for focus: " + QString::number(actualIndex));
return;
}
if (m_focusedIndex != index) {
@@ -215,16 +217,16 @@ void WallReel::Core::Image::Model::focusOnIndex(int index) {
void WallReel::Core::Image::Model::stop() {
if (m_isLoading) {
Logger::info("Stopping image loading...");
WR_INFO("Stopping image loading...");
m_watcher.cancel();
} else {
Logger::warn("No loading operation to stop.");
WR_WARN("No loading operation to stop.");
}
}
int WallReel::Core::Image::Model::_convertProxyIndex(int proxyIndex) const {
if (proxyIndex < 0 || proxyIndex >= m_filteredIndices.size()) {
Logger::debug("Invalid proxy index requested: " + QString::number(proxyIndex));
WR_DEBUG("Invalid proxy index requested: " + QString::number(proxyIndex));
return -1;
}
return m_filteredIndices[proxyIndex];
@@ -331,7 +333,7 @@ void WallReel::Core::Image::Model::_onProcessingFinished() {
if (data && data->isValid()) {
m_data.append(data);
} else {
Logger::warn("Failed to load image: " + (data ? data->getFullPath() : "null"));
WR_WARN("Failed to load image: " + (data ? data->getFullPath() : "null"));
delete data;
data = nullptr;
}
@@ -345,7 +347,7 @@ void WallReel::Core::Image::Model::_onProcessingFinished() {
endResetModel();
Logger::info("Finished loading images. Total valid images: " + QString::number(m_data.count()));
WR_INFO("Finished loading images. Total valid images: " + QString::number(m_data.count()));
m_isLoading = false;
m_progressUpdateTimer.stop();
+8 -1
View File
@@ -1,5 +1,9 @@
#include "domcolor.hpp"
#include "logger.hpp"
WALLREEL_DECLARE_SENDER("DomColor")
static constexpr int scaleMaxWidth = 128;
static constexpr int scaleMaxHeight = 128;
// See /misc/ColorArgTest/index.html for visualizing the effect of different powers
@@ -24,7 +28,10 @@ static double getWeight(const QColor& color) {
}
static QColor getWeightedDominantColor(const QImage& image) {
if (image.isNull()) return QColor();
if (image.isNull()) {
WR_WARN("Image is null");
return QColor();
}
// QImage scaledImg = image.scaled(128, 128, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
QImage* scaledImg = nullptr;
+8 -3
View File
@@ -5,6 +5,8 @@
#include "logger.hpp"
#include "predefined.hpp"
WALLREEL_DECLARE_SENDER("PaletteManager")
WallReel::Core::Palette::Manager::Manager(
const Config::ThemeConfigItems& config,
Image::Model& imageModel,
@@ -38,6 +40,8 @@ WallReel::Core::Palette::Manager::Manager(
newP.colors.reserve(p.colors.size());
for (const auto& c : p.colors) {
if (!c.value.isValid()) {
WR_WARN(QString("Invalid color value '%1' for color '%2' in palette '%3', skipping this color")
.arg(c.value.name(), c.name, p.name));
continue;
}
newP.colors.append({c.name, c.value});
@@ -72,6 +76,7 @@ void WallReel::Core::Palette::Manager::updateColor() {
});
auto imageData = m_imageModel.focusedImage();
if (!imageData || !imageData->isValid()) {
WR_WARN("No valid focused image data. Cannot update palette color.");
return;
}
// No palette selected, use dominant color
@@ -87,7 +92,7 @@ void WallReel::Core::Palette::Manager::updateColor() {
if (cached.has_value()) {
auto found = m_selectedPalette.value().getColorItem(cached.value());
if (found.isValid()) {
Logger::debug("Using cached color match for image " + imageData->getFileName() +
WR_DEBUG("Using cached color match for image " + imageData->getFileName() +
": " + found.name);
m_displayColor = found.color;
m_displayColorName = found.name;
@@ -100,14 +105,14 @@ void WallReel::Core::Palette::Manager::updateColor() {
m_selectedPalette.value().colors);
// Use dominant color if no valid match found (possibly empty palette)
if (!matched.isValid()) {
Logger::debug("No valid color match found for image " + imageData->getFileName() +
WR_DEBUG("No valid color match found for image " + imageData->getFileName() +
", using dominant color: " + imageData->getDominantColor().name());
m_displayColor = imageData->getDominantColor();
m_displayColorName = "";
hasResult = true;
return;
}
Logger::debug("Computed color match for image " + imageData->getFileName() + ": " +
WR_DEBUG("Computed color match for image " + imageData->getFileName() + ": " +
matched.name);
imageData->cacheColor(m_selectedPalette->name, matched.name);
m_displayColor = matched.color;
+5
View File
@@ -4,10 +4,15 @@
#include <cmath>
#include <limits>
#include "logger.hpp"
WALLREEL_DECLARE_SENDER("PaletteMatchColor")
namespace WallReel::Core::Palette {
const ColorItem& bestMatch(const QColor& target, const QList<ColorItem>& candidates) {
if (candidates.isEmpty() || !target.isValid()) {
WR_WARN("No candidates or invalid target color for palette matching");
static ColorItem emptyItem;
return emptyItem;
}
+10 -2
View File
@@ -39,8 +39,9 @@ class Manager : public QObject {
}
Q_INVOKABLE void selectWallpaper(int index) {
Logger::debug("ServiceManager", QString("Select wallpaper at index %1").arg(index));
if (m_isProcessing) {
Logger::debug("Already processing an action, ignoring select request");
Logger::debug("ServiceManager", "Already processing an select action, ignoring new request");
return;
}
m_isProcessing = true;
@@ -49,6 +50,7 @@ class Manager : public QObject {
if (data) {
m_wallpaperService->select(*data);
} else {
Logger::warn("ServiceManager", QString("No image data at index %1. Skipping select action.").arg(index));
m_isProcessing = false;
emit isProcessingChanged();
emit selectCompleted();
@@ -56,8 +58,9 @@ class Manager : public QObject {
}
Q_INVOKABLE void restore() {
Logger::debug("ServiceManager", "Restore states");
if (m_isProcessing) {
Logger::debug("Already processing an action, ignoring restore request");
Logger::debug("ServiceManager", "Already processing an restore action, ignoring new request");
return;
}
m_isProcessing = true;
@@ -66,6 +69,7 @@ class Manager : public QObject {
}
Q_INVOKABLE void cancel() {
Logger::debug("ServiceManager", "Cancel action");
m_wallpaperService->stopAll();
if (m_actionConfig.restoreOnCancel) {
connect(m_wallpaperService, &WallpaperService::restoreCompleted, this, [this]() {
@@ -82,10 +86,12 @@ class Manager : public QObject {
public slots:
void previewWallpaper() {
Logger::debug("ServiceManager", "Preview wallpaper");
const auto* data = m_imageModel.focusedImage();
if (data) {
m_wallpaperService->preview(*data);
} else {
Logger::warn("ServiceManager", "No focused image data. Skipping preview action.");
emit previewCompleted();
}
}
@@ -93,11 +99,13 @@ class Manager : public QObject {
private slots:
void _onSelectCompleted() {
Logger::debug("ServiceManager", "Select completed");
_onProcessCompleted();
emit selectCompleted();
}
void _onRestoreCompleted() {
Logger::debug("ServiceManager", "Restore completed");
_onProcessCompleted();
emit restoreCompleted();
}
+19 -11
View File
@@ -6,6 +6,8 @@
#include "Utils/texttemplate.hpp"
#include "logger.hpp"
WALLREEL_DECLARE_SENDER("WallpaperService")
WallReel::Core::Service::WallpaperService::WallpaperService(
const Config::ActionConfigItems& actionConfig,
const Palette::Manager& paletteManager,
@@ -23,8 +25,7 @@ WallReel::Core::Service::WallpaperService::WallpaperService(
QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this,
[this](int exitCode, QProcess::ExitStatus exitStatus) {
Q_UNUSED(exitCode);
Q_UNUSED(exitStatus);
WR_DEBUG(QString("Preview process finished with exit code %1 and exit status %2").arg(exitCode).arg(exitStatus));
emit previewCompleted();
});
@@ -33,8 +34,7 @@ WallReel::Core::Service::WallpaperService::WallpaperService(
QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this,
[this](int exitCode, QProcess::ExitStatus exitStatus) {
Q_UNUSED(exitCode);
Q_UNUSED(exitStatus);
WR_DEBUG(QString("Select process finished with exit code %1 and exit status %2").arg(exitCode).arg(exitStatus));
emit selectCompleted();
});
@@ -43,13 +43,13 @@ WallReel::Core::Service::WallpaperService::WallpaperService(
QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this,
[this](int exitCode, QProcess::ExitStatus exitStatus) {
Q_UNUSED(exitCode);
Q_UNUSED(exitStatus);
WR_DEBUG(QString("Restore process finished with exit code %1 and exit status %2").arg(exitCode).arg(exitStatus));
emit restoreCompleted();
});
}
void WallReel::Core::Service::WallpaperService::stopAll() {
WR_DEBUG("Stopping all wallpaper service processes");
if (m_previewProcess->state() != QProcess::NotRunning) {
m_previewProcess->kill();
m_previewProcess->waitForFinished();
@@ -72,17 +72,19 @@ void WallReel::Core::Service::WallpaperService::preview(const Image::Data& image
void WallReel::Core::Service::WallpaperService::select(const Image::Data& imageData) {
if (m_selectProcess->state() != QProcess::NotRunning) {
Logger::warn("Previous select command is still running. Ignoring new command.");
WR_WARN("Previous select command is still running. Ignoring new command.");
return;
}
WR_DEBUG(QString("Select wallpaper: %1").arg(imageData.getFullPath()));
_doSelect(imageData);
}
void WallReel::Core::Service::WallpaperService::restore() {
if (m_restoreProcess->state() != QProcess::NotRunning) {
Logger::warn("Previous restore command is still running. Ignoring new command.");
WR_WARN("Previous restore command is still running. Ignoring new command.");
return;
}
WR_DEBUG("Restore state");
_doRestore();
}
@@ -116,6 +118,7 @@ void WallReel::Core::Service::WallpaperService::_doPreview(const Image::Data& im
QString path = imageData.getFullPath();
if (path.isEmpty()) {
WR_WARN("No valid image path for preview. Skipping preview action.");
emit previewCompleted();
return;
}
@@ -127,10 +130,11 @@ void WallReel::Core::Service::WallpaperService::_doPreview(const Image::Data& im
const auto variables = _generateVariables(imageData);
auto command = Utils::renderTemplate(m_actionConfig.onPreview, variables);
if (command.isEmpty()) {
WR_DEBUG("No preview command configured. Skipping preview action.");
emit previewCompleted();
return;
}
Logger::debug(QString("Executing preview command: %1").arg(command));
WR_DEBUG(QString("Executing preview command: %1").arg(command));
if (m_previewProcess->state() != QProcess::NotRunning) {
m_previewProcess->kill();
@@ -143,6 +147,7 @@ void WallReel::Core::Service::WallpaperService::_doSelect(const Image::Data& ima
QString path = imageData.getFullPath();
if (path.isEmpty()) {
WR_WARN("No valid image path for select. Skipping select action.");
emit selectCompleted();
return;
}
@@ -154,24 +159,27 @@ void WallReel::Core::Service::WallpaperService::_doSelect(const Image::Data& ima
const auto variables = _generateVariables(imageData);
auto command = Utils::renderTemplate(m_actionConfig.onSelected, variables);
if (command.isEmpty()) {
WR_DEBUG("No select command configured. Skipping select action.");
emit selectCompleted();
return;
}
Logger::debug(QString("Executing select command: %1").arg(command));
WR_DEBUG(QString("Executing select command: %1").arg(command));
m_selectProcess->start("sh", QStringList() << "-c" << command);
}
void WallReel::Core::Service::WallpaperService::_doRestore() {
if (m_actionConfig.onRestore.isEmpty()) {
WR_DEBUG("No restore command configured. Skipping restore action.");
emit restoreCompleted();
return;
}
const QString command = Utils::renderTemplate(m_actionConfig.onRestore, m_actionConfig.saveState);
if (command.isEmpty()) {
WR_DEBUG("Restore command is empty after rendering. Skipping restore action.");
emit restoreCompleted();
return;
}
Logger::debug(QString("Executing restore command: %1").arg(command));
WR_DEBUG(QString("Executing restore command: %1").arg(command));
m_restoreProcess->start("sh", QStringList() << "-c" << command);
}
+4 -17
View File
@@ -8,6 +8,8 @@
#include "logger.hpp"
#include "version.h"
WALLREEL_DECLARE_SENDER("AppOptions")
namespace WallReel::Core {
// -v --version
@@ -32,21 +34,6 @@ void AppOptions::printHelp() {
doReturn = true;
}
// -C --clear-cache
void AppOptions::clearCache() {
QDir cacheDir = Utils::getCacheDir();
if (cacheDir.exists()) {
if (cacheDir.removeRecursively()) {
Logger::info("Cache cleared successfully.");
} else {
Logger::warn("Failed to clear cache.");
}
} else {
Logger::info("Cache directory does not exist, nothing to clear.");
}
doReturn = true;
}
// Print error message and help
void AppOptions::printError() {
if (!errorText.isEmpty()) {
@@ -100,7 +87,7 @@ void AppOptions::parseArgs(QApplication& app) {
}
if (parser.isSet(clearCacheOption)) {
clearCache();
clearCache = true;
return;
}
@@ -110,7 +97,7 @@ void AppOptions::parseArgs(QApplication& app) {
Logger::quiet();
} else {
// Default to INFO level
Logger::setLogLevel(QtDebugMsg);
Logger::setLogLevel(QtInfoMsg);
}
for (const QString& dir : parser.values(appendDirOption)) {
+1 -3
View File
@@ -19,9 +19,6 @@ class AppOptions {
// -h --help
void printHelp();
// -C --clear-cache
void clearCache();
// Print error message and help
void printError();
@@ -29,6 +26,7 @@ class AppOptions {
QString configPath;
QStringList appendDirs;
QString errorText;
bool clearCache = false; // -C --clear-cache
bool doReturn = false; ///< Indicates whether the application should exit after parsing arguments.
AppOptions();
+12 -8
View File
@@ -105,20 +105,24 @@ void WallReel::Core::Logger::quiet() {
QLoggingCategory::setFilterRules(QString("%1.debug=false\n%1.info=false\n%1.warning=false\n%1.critical=false\n%1.fatal=false").arg(APP_NAME));
}
void WallReel::Core::Logger::debug(const QString& msg) {
qCDebug(logMain).noquote() << msg;
void WallReel::Core::Logger::debug(const QString& sender, const QString& msg) {
qCDebug(logMain) << QString("[%1] %2").arg(sender, msg);
}
void WallReel::Core::Logger::info(const QString& msg) {
qCInfo(logMain).noquote() << msg;
void WallReel::Core::Logger::info(const QString& sender, const QString& msg) {
qCInfo(logMain) << QString("[%1] %2").arg(sender, msg);
}
void WallReel::Core::Logger::warn(const QString& msg) {
qCWarning(logMain).noquote() << msg;
void WallReel::Core::Logger::warn(const QString& sender, const QString& msg) {
qCWarning(logMain) << QString("[%1] %2").arg(sender, msg);
}
void WallReel::Core::Logger::critical(const QString& msg) {
qCCritical(logMain).noquote() << msg;
void WallReel::Core::Logger::critical(const QString& sender, const QString& msg) {
qCCritical(logMain) << QString("[%1] %2").arg(sender, msg);
}
void WallReel::Core::Logger::fatal(const QString& sender, const QString& msg) {
qCFatal(logMain) << QString("[%1] %2").arg(sender, msg);
}
// No fatal because qCFatal does not exist before Qt 6.5
+20 -4
View File
@@ -1,6 +1,8 @@
#ifndef WALLREEL_LOGGER_HPP
#define WALLREEL_LOGGER_HPP
#include <qcontainerfwd.h>
#include <QLoggingCategory>
#include <QString>
#include <cstdio>
@@ -8,15 +10,18 @@
Q_DECLARE_LOGGING_CATEGORY(logMain)
namespace WallReel::Core {
class Logger {
public:
static void debug(const QString& msg);
static void debug(const QString& sender, const QString& msg);
static void info(const QString& msg);
static void info(const QString& sender, const QString& msg);
static void warn(const QString& msg);
static void warn(const QString& sender, const QString& msg);
static void critical(const QString& msg);
static void critical(const QString& sender, const QString& msg);
static void fatal(const QString& sender, const QString& msg);
/**
* @brief Initialize the logger and set the output stream.
@@ -41,4 +46,15 @@ class Logger {
} // namespace WallReel::Core
#define WALLREEL_DECLARE_SENDER(name) \
namespace { \
constexpr const char* _wallreel_sender = name; \
}
#define WR_DEBUG(msg) WallReel::Core::Logger::debug(_wallreel_sender, msg)
#define WR_INFO(msg) WallReel::Core::Logger::info(_wallreel_sender, msg)
#define WR_WARN(msg) WallReel::Core::Logger::warn(_wallreel_sender, msg)
#define WR_CRITICAL(msg) WallReel::Core::Logger::critical(_wallreel_sender, msg)
#define WR_FATAL(msg) WallReel::Core::Logger::fatal(_wallreel_sender, msg)
#endif // WALLREEL_LOGGER_HPP
+9 -2
View File
@@ -17,6 +17,8 @@
using namespace WallReel::Core;
WALLREEL_DECLARE_SENDER("Main")
int main(int argc, char* argv[]) {
AppOptions s_options;
@@ -33,6 +35,13 @@ int main(int argc, char* argv[]) {
QQmlApplicationEngine engine;
auto cacheMgr = new Cache::Manager(Utils::getCacheDir());
if (s_options.clearCache) {
cacheMgr->clearCache();
return 0;
}
auto config = new Config::Manager(
Utils::getConfigDir(),
s_options.appendDirs,
@@ -45,8 +54,6 @@ int main(int argc, char* argv[]) {
"Config",
config);
auto cacheMgr = new Cache::Manager(Utils::getCacheDir());
auto imageModel = new Image::Model(
config->getSortConfig(),
*cacheMgr,