/* * Copyright 2018 Michail Vourlakos * * This file is part of Latte-Dock * * Latte-Dock is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * Latte-Dock is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "backgroundcache.h" // local #include "commontools.h" // Qt #include #include #include // Plasma #include // KDE #include #include #define PLASMACONFIG "plasma-org.kde.plasma.desktop-appletsrc" #define DEFAULTWALLPAPER "/usr/share/wallpapers/Next/contents/images/1920x1080.png" namespace Latte{ namespace PlasmaExtended { BackgroundCache::BackgroundCache(QObject *parent) : QObject(parent), m_initialized(false), m_plasmaConfig(KSharedConfig::openConfig(PLASMACONFIG)) { const auto configFile = QStandardPaths::writableLocation( QStandardPaths::GenericConfigLocation) + QLatin1Char('/') + PLASMACONFIG; KDirWatch::self()->addFile(configFile); connect(KDirWatch::self(), &KDirWatch::dirty, this, &BackgroundCache::settingsFileChanged); connect(KDirWatch::self(), &KDirWatch::created, this, &BackgroundCache::settingsFileChanged); if (!m_pool) { m_pool = new ScreenPool(this); } reload(); } BackgroundCache::~BackgroundCache() { if (m_pool) { m_pool->deleteLater(); } } BackgroundCache *BackgroundCache::self() { static BackgroundCache cache; return &cache; } void BackgroundCache::settingsFileChanged(const QString &file) { if (!file.endsWith(PLASMACONFIG)) { return; } if (m_initialized) { m_plasmaConfig->reparseConfiguration(); reload(); } } QString BackgroundCache::backgroundFromConfig(const KConfigGroup &config) const { auto wallpaperPlugin = config.readEntry("wallpaperplugin"); auto wallpaperConfig = config.group("Wallpaper").group(wallpaperPlugin).group("General"); if (wallpaperConfig.hasKey("Image")) { // Trying for the wallpaper auto wallpaper = wallpaperConfig.readEntry("Image", QString()); if (!wallpaper.isEmpty()) { return wallpaper; } } if (wallpaperConfig.hasKey("Color")) { auto backgroundColor = wallpaperConfig.readEntry("Color", QColor(0, 0, 0)); return backgroundColor.name(); } return QString(); } void BackgroundCache::reload() { // Traversing through all containments in search for // containments that define activities in plasma KConfigGroup plasmaConfigContainments = m_plasmaConfig->group("Containments"); for (const auto &containmentId : plasmaConfigContainments.groupList()) { const auto containment = plasmaConfigContainments.group(containmentId); const auto lastScreen = containment.readEntry("lastScreen", 0); const auto activity = containment.readEntry("activityId", QString()); // Ignore the containment if the activity is not defined if (activity.isEmpty()) continue; const auto returnedBackground = backgroundFromConfig(containment); QString background = returnedBackground; if (background.startsWith("file://")) { background = returnedBackground.mid(7); } if (background.isEmpty()) continue; m_backgrounds[activity][m_pool->connector(lastScreen)] = background; } m_initialized = true; qDebug() << m_backgrounds; } QString BackgroundCache::background(QString activity, QString screen) { if (m_backgrounds.contains(activity) && m_backgrounds[activity].contains(screen)) { return m_backgrounds[activity][screen]; } else { return DEFAULTWALLPAPER; } } float BackgroundCache::luminasFor(QString activity, QString screen, Plasma::Types::Location location) { QString assignedBackground = background(activity, screen); if (!assignedBackground.isEmpty()) { return luminasFromFile(assignedBackground, location); } return -1000; } float BackgroundCache::luminasFromFile(QString imageFile, Plasma::Types::Location location) { QImage image(imageFile); if (m_luminasCache.keys().contains(imageFile)) { if (m_luminasCache[imageFile].keys().contains(location)) { return m_luminasCache[imageFile].value(location); } } if (image.format() != QImage::Format_Invalid) { int maskHeight = (0.08 * image.height()); int maskWidth = (0.05 * image.width()); float areaLumin = -1000; int firstRow = 0; int firstColumn = 0; int endRow = 0; int endColumn = 0; if (location == Plasma::Types::TopEdge) { firstRow = 0; endRow = maskHeight; firstColumn = 0; endColumn = image.width() - 1; } else if (location == Plasma::Types::BottomEdge) { firstRow = image.height() - maskHeight - 1; endRow = image.height() - 1; firstColumn = 0; endColumn = image.width() - 1; } else if (location == Plasma::Types::LeftEdge) { firstRow = 0; endRow = image.height() - 1; firstColumn = 0; endColumn = maskWidth; } else if (location == Plasma::Types::RightEdge) { firstRow = 0; endRow = image.height() - 1; firstColumn = image.width() - 1 - maskWidth; endColumn = image.width() - 1; } for (int row = firstRow; row < endRow; ++row) { QRgb *line = (QRgb *)image.scanLine(row); for (int col = firstColumn; col < endColumn ; ++col) { QRgb pixelData = line[col]; float pixelLuminosity = Latte::colorLumina(pixelData); areaLumin = (areaLumin == -1000) ? pixelLuminosity : (areaLumin + pixelLuminosity); } } float areaSize = (endRow - firstRow) * (endColumn - firstColumn); areaLumin = areaLumin / areaSize; if (!m_luminasCache.keys().contains(imageFile)) { m_luminasCache[imageFile] = EdgesHash(); } m_luminasCache[imageFile].insert(location, areaLumin); return areaLumin; } //! didn't find anything return -1000; } } }