From 1ccb26f42bab1305f0d5454d17bc4abbce147146 Mon Sep 17 00:00:00 2001 From: Uyanide Date: Fri, 27 Feb 2026 17:02:19 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20logging?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WallReel/Core/Cache/manager.cpp | 50 ++++++------ WallReel/Core/Config/manager.cpp | 46 ++++++----- WallReel/Core/Image/data.cpp | 116 ++++++++++++++------------- WallReel/Core/Image/data.hpp | 3 + WallReel/Core/Image/model.cpp | 34 ++++---- WallReel/Core/Palette/domcolor.cpp | 9 ++- WallReel/Core/Palette/manager.cpp | 17 ++-- WallReel/Core/Palette/matchcolor.cpp | 5 ++ WallReel/Core/Service/manager.hpp | 12 ++- WallReel/Core/Service/wallpaper.cpp | 30 ++++--- WallReel/Core/appoptions.cpp | 21 +---- WallReel/Core/appoptions.hpp | 6 +- WallReel/Core/logger.cpp | 20 +++-- WallReel/Core/logger.hpp | 24 +++++- WallReel/main.cpp | 11 ++- 15 files changed, 230 insertions(+), 174 deletions(-) diff --git a/WallReel/Core/Cache/manager.cpp b/WallReel/Core/Cache/manager.cpp index 8bdb5bb..74968e2 100644 --- a/WallReel/Core/Cache/manager.cpp +++ b/WallReel/Core/Cache/manager.cpp @@ -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& 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& 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& 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 - .arg(key, insertQuery.lastError().text())); + 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& 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 - .arg(key, cached.absoluteFilePath())); + 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& 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& 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,8 +167,8 @@ QFileInfo Manager::getImage(const QString& key, const std::function& 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 - .arg(key, insertQuery.lastError().text())); + WR_WARN(u"Failed to record image in db [%1]: %2"_s + .arg(key, insertQuery.lastError().text())); } return QFileInfo(filePath); @@ -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 - .arg(m_dbPath, db.lastError().text())); + 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); { diff --git a/WallReel/Core/Config/manager.cpp b/WallReel/Core/Config/manager.cpp index 42583b9..43a1e80 100644 --- a/WallReel/Core/Config/manager.cpp +++ b/WallReel/Core/Config/manager.cpp @@ -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 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 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); } }); diff --git a/WallReel/Core/Image/data.cpp b/WallReel/Core/Image/data.cpp index 0e37b60..75ae7ec 100644 --- a/WallReel/Core/Image/data.cpp +++ b/WallReel/Core/Image/data.cpp @@ -4,6 +4,9 @@ #include #include "Palette/domcolor.hpp" +#include "logger.hpp" + +WALLREEL_DECLARE_SENDER("ImageData") WallReel::Core::Image::Data* WallReel::Core::Image::Data::create( const QString& path, @@ -20,74 +23,73 @@ 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]() { - QImageReader reader(m_file.absoluteFilePath()); - if (!reader.canRead()) { - return QImage(); - } - - const QSize originalSize = reader.size(); - - // Scale the image to fit the target size while maintaining aspect ratio - QSize processSize = originalSize; - if (originalSize.isValid()) { - double widthRatio = (double)m_targetSize.width() / originalSize.width(); - double heightRatio = (double)m_targetSize.height() / originalSize.height(); - double scaleFactor = std::max(widthRatio, heightRatio); - processSize = originalSize * scaleFactor; - - // Use reader's built-in scaling if supported - if (reader.supportsOption(QImageIOHandler::ScaledSize)) { - reader.setScaledSize(processSize); - } - } - - QImage image; - if (!reader.read(&image)) { - return QImage(); - } - - // If reader doesn't support built-in scaling or the image still do not match the target size, do manual scaling - if (image.size() != processSize) { - image = image.scaled(processSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - } - - // Crop to target size if necessary - if (image.size() != m_targetSize) { - int x = (image.width() - m_targetSize.width()) / 2; - int y = (image.height() - m_targetSize.height()) / 2; - image = image.copy(x, y, m_targetSize.width(), m_targetSize.height()); - } - - // Convert to GPU-friendly format - if (image.format() != QImage::Format_ARGB32_Premultiplied) { - 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(); - } - return Palette::getDominantColor(image); - }); + 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(); + } + + const QSize originalSize = reader.size(); + + // Scale the image to fit the target size while maintaining aspect ratio + QSize processSize = originalSize; + if (originalSize.isValid()) { + double widthRatio = (double)m_targetSize.width() / originalSize.width(); + double heightRatio = (double)m_targetSize.height() / originalSize.height(); + double scaleFactor = std::max(widthRatio, heightRatio); + processSize = originalSize * scaleFactor; + + // Use reader's built-in scaling if supported + if (reader.supportsOption(QImageIOHandler::ScaledSize)) { + reader.setScaledSize(processSize); + } + } + + QImage image; + if (!reader.read(&image)) { + WR_WARN("Failed to read image file: " + m_file.absoluteFilePath()); + return QImage(); + } + + // If reader doesn't support built-in scaling or the image still do not match the target size, do manual scaling + if (image.size() != processSize) { + image = image.scaled(processSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + } + + // Crop to target size if necessary + if (image.size() != m_targetSize) { + int x = (image.width() - m_targetSize.width()) / 2; + int y = (image.height() - m_targetSize.height()) / 2; + image = image.copy(x, y, m_targetSize.width(), m_targetSize.height()); + } + + // Convert to GPU-friendly format + if (image.format() != QImage::Format_ARGB32_Premultiplied) { + image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + } + return image; +} + +QColor WallReel::Core::Image::Data::computeDominantColor(const QImage& image) const { + return Palette::getDominantColor(image); +} diff --git a/WallReel/Core/Image/data.hpp b/WallReel/Core/Image/data.hpp index ab09434..b1ab0f6 100644 --- a/WallReel/Core/Image/data.hpp +++ b/WallReel/Core/Image/data.hpp @@ -54,6 +54,9 @@ class Data { QColor m_dominantColor; ///< Dominant color of the image, used for palette matching QHash 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: diff --git a/WallReel/Core/Image/model.cpp b/WallReel/Core/Image/model.cpp index 64b2921..c71ea49 100644 --- a/WallReel/Core/Image/model.cpp +++ b/WallReel/Core/Image/model.cpp @@ -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(); diff --git a/WallReel/Core/Palette/domcolor.cpp b/WallReel/Core/Palette/domcolor.cpp index 444ca60..2540e30 100644 --- a/WallReel/Core/Palette/domcolor.cpp +++ b/WallReel/Core/Palette/domcolor.cpp @@ -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; diff --git a/WallReel/Core/Palette/manager.cpp b/WallReel/Core/Palette/manager.cpp index 40f99a1..72ad671 100644 --- a/WallReel/Core/Palette/manager.cpp +++ b/WallReel/Core/Palette/manager.cpp @@ -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,8 +92,8 @@ 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() + - ": " + found.name); + WR_DEBUG("Using cached color match for image " + imageData->getFileName() + + ": " + found.name); m_displayColor = found.color; m_displayColorName = found.name; hasResult = true; @@ -100,15 +105,15 @@ 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() + - ", using dominant color: " + imageData->getDominantColor().name()); + 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() + ": " + - matched.name); + WR_DEBUG("Computed color match for image " + imageData->getFileName() + ": " + + matched.name); imageData->cacheColor(m_selectedPalette->name, matched.name); m_displayColor = matched.color; m_displayColorName = matched.name; diff --git a/WallReel/Core/Palette/matchcolor.cpp b/WallReel/Core/Palette/matchcolor.cpp index fd3ac9c..f3227e1 100644 --- a/WallReel/Core/Palette/matchcolor.cpp +++ b/WallReel/Core/Palette/matchcolor.cpp @@ -4,10 +4,15 @@ #include #include +#include "logger.hpp" + +WALLREEL_DECLARE_SENDER("PaletteMatchColor") + namespace WallReel::Core::Palette { const ColorItem& bestMatch(const QColor& target, const QList& candidates) { if (candidates.isEmpty() || !target.isValid()) { + WR_WARN("No candidates or invalid target color for palette matching"); static ColorItem emptyItem; return emptyItem; } diff --git a/WallReel/Core/Service/manager.hpp b/WallReel/Core/Service/manager.hpp index 803d186..49d9346 100644 --- a/WallReel/Core/Service/manager.hpp +++ b/WallReel/Core/Service/manager.hpp @@ -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(); } diff --git a/WallReel/Core/Service/wallpaper.cpp b/WallReel/Core/Service/wallpaper.cpp index d915987..1a3de1f 100644 --- a/WallReel/Core/Service/wallpaper.cpp +++ b/WallReel/Core/Service/wallpaper.cpp @@ -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::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::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::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); } diff --git a/WallReel/Core/appoptions.cpp b/WallReel/Core/appoptions.cpp index 251edd3..acd14fd 100644 --- a/WallReel/Core/appoptions.cpp +++ b/WallReel/Core/appoptions.cpp @@ -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)) { diff --git a/WallReel/Core/appoptions.hpp b/WallReel/Core/appoptions.hpp index 87e0d5d..91ceeb1 100644 --- a/WallReel/Core/appoptions.hpp +++ b/WallReel/Core/appoptions.hpp @@ -19,9 +19,6 @@ class AppOptions { // -h --help void printHelp(); - // -C --clear-cache - void clearCache(); - // Print error message and help void printError(); @@ -29,7 +26,8 @@ class AppOptions { QString configPath; QStringList appendDirs; QString errorText; - bool doReturn = false; ///< Indicates whether the application should exit after parsing arguments. + bool clearCache = false; // -C --clear-cache + bool doReturn = false; ///< Indicates whether the application should exit after parsing arguments. AppOptions(); void parseArgs(QApplication& app); diff --git a/WallReel/Core/logger.cpp b/WallReel/Core/logger.cpp index 3adf80b..451ffc8 100644 --- a/WallReel/Core/logger.cpp +++ b/WallReel/Core/logger.cpp @@ -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 diff --git a/WallReel/Core/logger.hpp b/WallReel/Core/logger.hpp index 3fff574..072c29f 100644 --- a/WallReel/Core/logger.hpp +++ b/WallReel/Core/logger.hpp @@ -1,6 +1,8 @@ #ifndef WALLREEL_LOGGER_HPP #define WALLREEL_LOGGER_HPP +#include + #include #include #include @@ -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 diff --git a/WallReel/main.cpp b/WallReel/main.cpp index 33439cd..bd3271c 100644 --- a/WallReel/main.cpp +++ b/WallReel/main.cpp @@ -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,