File indexing completed on 2025-04-27 03:58:32
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2004-08-02 0007 * Description : colors theme manager 0008 * 0009 * SPDX-FileCopyrightText: 2006-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "thememanager_p.h" 0016 0017 namespace Digikam 0018 { 0019 0020 class Q_DECL_HIDDEN ThemeManagerCreator 0021 { 0022 public: 0023 0024 ThemeManager object; 0025 }; 0026 0027 Q_GLOBAL_STATIC(ThemeManagerCreator, creator) 0028 0029 // ----------------------------------------------------- 0030 0031 ThemeManager::ThemeManager() 0032 : d(new Private) 0033 { 0034 } 0035 0036 ThemeManager::~ThemeManager() 0037 { 0038 delete d; 0039 } 0040 0041 ThemeManager* ThemeManager::instance() 0042 { 0043 return &creator->object; 0044 } 0045 0046 QString ThemeManager::defaultThemeName() const 0047 { 0048 return d->defaultThemeName; 0049 } 0050 0051 QString ThemeManager::currentThemeName() const 0052 { 0053 if (!d->themeMenuAction || !d->themeMenuActionGroup) 0054 { 0055 return defaultThemeName(); 0056 } 0057 0058 QAction* const action = d->themeMenuActionGroup->checkedAction(); 0059 0060 return (!action ? defaultThemeName() 0061 : action->text().remove(QLatin1Char('&'))); 0062 } 0063 0064 void ThemeManager::setCurrentTheme(const QString& name) 0065 { 0066 if (!d->themeMenuAction || !d->themeMenuActionGroup) 0067 { 0068 return; 0069 } 0070 0071 QList<QAction*> list = d->themeMenuActionGroup->actions(); 0072 0073 Q_FOREACH (QAction* const action, list) 0074 { 0075 if (action->text().remove(QLatin1Char('&')) == name) 0076 { 0077 action->setChecked(true); 0078 slotChangePalette(); 0079 } 0080 } 0081 } 0082 0083 void ThemeManager::slotChangePalette() 0084 { 0085 updateCurrentDesktopDefaultThemePreview(); 0086 0087 QString theme(currentThemeName()); 0088 0089 if (theme.isEmpty() || 0090 (theme == defaultThemeName()) || 0091 (qApp->style()->objectName().compare(QLatin1String("windowsvista"), Qt::CaseInsensitive) == 0)) 0092 { 0093 theme = currentDesktopdefaultTheme(); 0094 } 0095 0096 QString filePath = d->themeMap.value(theme); 0097 KSharedConfigPtr config = KSharedConfig::openConfig(filePath); 0098 0099 // hint for the style to synchronize the color scheme with the window manager/compositor 0100 0101 qApp->setProperty("KDE_COLOR_SCHEME_PATH", filePath); 0102 qApp->setPalette(SchemeManager::createApplicationPalette(config)); 0103 qApp->style()->polish(qApp); 0104 0105 qCDebug(DIGIKAM_WIDGETS_LOG) << theme << " :: " << filePath; 0106 0107 Q_EMIT signalThemeChanged(); 0108 } 0109 0110 void ThemeManager::setThemeMenuAction(QMenu* const action) 0111 { 0112 d->themeMenuAction = action; 0113 populateThemeMenu(); 0114 } 0115 0116 void ThemeManager::registerThemeActions(DXmlGuiWindow* const win) 0117 { 0118 if (!win) 0119 { 0120 return; 0121 } 0122 0123 if (!d->themeMenuAction) 0124 { 0125 qCDebug(DIGIKAM_WIDGETS_LOG) << "Cannot register theme actions to " << win->windowTitle(); 0126 return; 0127 } 0128 0129 win->actionCollection()->addAction(QLatin1String("theme_menu"), d->themeMenuAction->menuAction()); 0130 } 0131 0132 void ThemeManager::populateThemeMenu() 0133 { 0134 if (!d->themeMenuAction) 0135 { 0136 return; 0137 } 0138 0139 QString theme(currentThemeName()); 0140 0141 d->themeMap.clear(); 0142 d->themeMenuAction->clear(); 0143 delete d->themeMenuActionGroup; 0144 0145 d->themeMenuActionGroup = new QActionGroup(d->themeMenuAction); 0146 0147 QAction* const action = new QAction(defaultThemeName(), d->themeMenuActionGroup); 0148 action->setCheckable(true); 0149 action->setChecked(true); 0150 d->themeMenuAction->addAction(action); 0151 0152 if (qApp->style()->objectName().compare(QLatin1String("windowsvista"), Qt::CaseInsensitive) != 0) 0153 { 0154 QMap<QString, QAction*> actionMap; 0155 QStringList dirs; 0156 0157 // digiKam colors scheme 0158 0159 dirs << QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, 0160 QLatin1String("digikam/colorschemes"), 0161 QStandardPaths::LocateDirectory); 0162 0163 qCDebug(DIGIKAM_WIDGETS_LOG) << "Paths to color scheme : " << dirs; 0164 0165 Q_FOREACH (const QString& dir, dirs) 0166 { 0167 QDirIterator it(dir, QStringList() << QLatin1String("*.colors")); 0168 0169 while (it.hasNext()) 0170 { 0171 const QString filePath = it.next(); 0172 KSharedConfigPtr config = KSharedConfig::openConfig(filePath); 0173 QIcon icon = d->createSchemePreviewIcon(config); 0174 KConfigGroup group(config, QLatin1String("General")); 0175 const QString name = group.readEntry("Name", 0176 it.fileInfo().baseName()); 0177 QAction* const ac = new QAction(name, d->themeMenuActionGroup); 0178 d->themeMap.insert(name, filePath); 0179 ac->setIcon(icon); 0180 ac->setCheckable(true); 0181 actionMap.insert(name, ac); 0182 } 0183 } 0184 0185 Q_FOREACH (QAction* const menuAction, actionMap.values()) 0186 { 0187 d->themeMenuAction->addAction(menuAction); 0188 } 0189 } 0190 0191 connect(d->themeMenuActionGroup, SIGNAL(triggered(QAction*)), 0192 this, SLOT(slotChangePalette())); 0193 0194 updateCurrentDesktopDefaultThemePreview(); 0195 setCurrentTheme(theme); 0196 } 0197 0198 void ThemeManager::updateCurrentDesktopDefaultThemePreview() 0199 { 0200 QList<QAction*> list = d->themeMenuActionGroup->actions(); 0201 0202 Q_FOREACH (QAction* const action, list) 0203 { 0204 if (action->text().remove(QLatin1Char('&')) == defaultThemeName()) 0205 { 0206 KSharedConfigPtr config = KSharedConfig::openConfig(d->themeMap.value(currentDesktopdefaultTheme())); 0207 QIcon icon = d->createSchemePreviewIcon(config); 0208 action->setIcon(icon); 0209 } 0210 } 0211 } 0212 0213 QString ThemeManager::currentDesktopdefaultTheme() const 0214 { 0215 KSharedConfigPtr config = KSharedConfig::openConfig(QLatin1String("kdeglobals")); 0216 KConfigGroup group(config, QLatin1String("General")); 0217 0218 return group.readEntry("ColorScheme"); 0219 } 0220 0221 void ThemeManager::updateThemeMenu() 0222 { 0223 populateThemeMenu(); 0224 slotChangePalette(); 0225 } 0226 0227 } // namespace Digikam 0228 0229 #include "moc_thememanager.cpp"