7#include "grantleethememanager.h"
8#include "grantleetheme_p.h"
10#include <KActionCollection>
13#include <KConfigGroup>
15#include <KLocalizedString>
16#include <KNSWidgets/Action>
17#include <KSharedConfig>
18#include <KToggleAction>
23#include <QActionGroup>
25#include <QDirIterator>
26#include <QStandardPaths>
28namespace GrantleeTheme
30class ThemeManagerPrivate
33 ThemeManagerPrivate(
const QString &type,
34 const QString &desktopFileName,
35 KActionCollection *ac,
36 const QString &relativePath,
37 const QString &configFileName,
39 : applicationType(
type)
40 , defaultDesktopFileName(desktopFileName)
41 , actionCollection(ac)
44 watch =
new KDirWatch(q);
45 initThemesDirectories(relativePath);
47 downloadThemesAction =
new KNSWidgets::Action(
i18n(
"Download new Templates…"), configFileName, q);
48 if (actionCollection) {
49 actionCollection->addAction(QStringLiteral(
"download_header_themes"), downloadThemesAction);
51 separatorAction =
new QAction(q);
52 separatorAction->setSeparator(
true);
58 updateThemesPath(
true);
63 if (config->hasGroup(QStringLiteral(
"GrantleeTheme"))) {
64 const KConfigGroup group = config->group(QStringLiteral(
"GrantleeTheme"));
65 const QString mailTheme = group.readEntry(QStringLiteral(
"grantleeMailThemeName"));
66 const QString addressbookTheme = group.readEntry(QStringLiteral(
"grantleeAddressBookThemeName"));
68 config->group(QStringLiteral(
"mail")).writeEntry(QStringLiteral(
"themeName"), mailTheme);
69 config->group(QStringLiteral(
"addressbook")).writeEntry(QStringLiteral(
"themeName"), addressbookTheme);
71 config->deleteGroup(QStringLiteral(
"GrantleeTheme"));
75 ~ThemeManagerPrivate()
81 void directoryChanged()
85 Q_EMIT q->updateThemes();
88 void updateThemesPath(
bool init =
false)
91 if (!themesDirectories.isEmpty()) {
92 for (
const QString &directory : std::as_const(themesDirectories)) {
93 watch->removeDir(directory);
103 for (
const QString &directory : std::as_const(themesDirectories)) {
105 QStringList alreadyLoadedThemeName;
106 while (dirIt.hasNext()) {
108 const QString dirName = dirIt.fileName();
109 GrantleeTheme::Theme theme = q->loadTheme(dirIt.filePath(), dirName, defaultDesktopFileName);
110 if (theme.isValid()) {
111 QString themeName = theme.name();
112 if (alreadyLoadedThemeName.
contains(themeName)) {
114 const QString originalName(theme.name());
115 while (alreadyLoadedThemeName.
contains(themeName)) {
116 themeName = originalName + QStringLiteral(
" (%1)").
arg(i);
119 theme.d->name = themeName;
121 alreadyLoadedThemeName << themeName;
122 auto it = themes.find(dirName);
123 if (it != themes.end()) {
124 (*it).addThemePath(dirIt.filePath());
126 themes.insert(dirName, theme);
130 watch->addDir(directory);
133 Q_EMIT q->themesChanged();
139 if (!actionGroup || !menu) {
142 for (KToggleAction *action : std::as_const(themesActionList)) {
143 actionGroup->removeAction(action);
144 menu->removeAction(action);
145 if (actionCollection) {
146 actionCollection->removeAction(action);
149 if (separatorAction) {
150 menu->removeAction(separatorAction);
151 if (downloadThemesAction) {
152 menu->removeAction(downloadThemesAction);
155 themesActionList.clear();
158 void updateActionList()
160 if (!actionGroup || !menu) {
163 QString themeActivated;
165 QAction *selectedAction = actionGroup->checkedAction();
166 if (selectedAction) {
172 bool themeActivatedFound =
false;
173 QMapIterator<QString, GrantleeTheme::Theme> i(themes);
174 while (i.hasNext()) {
176 GrantleeTheme::Theme theme = i.value();
177 auto act =
new KToggleAction(theme.name(), q);
178 act->setToolTip(theme.description());
179 act->setData(theme.dirName());
180 if (theme.dirName() == themeActivated) {
181 act->setChecked(
true);
182 themeActivatedFound =
true;
184 themesActionList.append(act);
185 actionGroup->addAction(act);
186 menu->addAction(act);
191 if (!themeActivatedFound) {
192 if (!themesActionList.isEmpty() && !themeActivated.
isEmpty()) {
194 KToggleAction *act = themesActionList.at(0);
199 if (separatorAction) {
200 menu->addAction(separatorAction);
201 if (downloadThemesAction) {
202 menu->addAction(downloadThemesAction);
207 void selectTheme(KToggleAction *act)
211 KConfigGroup group = config->group(applicationType);
212 group.writeEntry(QStringLiteral(
"themeName"), act->
data().
toString());
217 void slotThemeSelected()
220 auto act = qobject_cast<KToggleAction *>(q->sender());
222 Q_EMIT q->grantleeThemeSelected();
226 KToggleAction *actionForTheme()
229 const KConfigGroup group = config->group(applicationType);
230 const QString themeName = group.readEntry(QStringLiteral(
"themeName"), QStringLiteral(
"default"));
235 for (KToggleAction *act : std::as_const(themesActionList)) {
237 return static_cast<KToggleAction *
>(act);
243 void initThemesDirectories(
const QString &themesRelativePath)
245 if (!themesRelativePath.
isEmpty()) {
248 themesDirectories.
append(localDirectory);
252 QString applicationType;
253 QString defaultDesktopFileName;
254 QStringList themesDirectories;
255 QMap<QString, GrantleeTheme::Theme> themes;
256 QList<KToggleAction *> themesActionList;
257 KDirWatch *watch =
nullptr;
258 QActionGroup *actionGroup =
nullptr;
259 KActionMenu *menu =
nullptr;
260 KActionCollection *
const actionCollection;
261 QAction *separatorAction =
nullptr;
262 KNSWidgets::Action *downloadThemesAction =
nullptr;
263 ThemeManager *
const q;
267using namespace GrantleeTheme;
269ThemeManager::ThemeManager(
const QString &applicationType,
270 const QString &defaultDesktopFileName,
276 , d(new ThemeManagerPrivate(applicationType, defaultDesktopFileName, actionCollection,
path, configFileName, this))
280ThemeManager::~ThemeManager() =
default;
287void ThemeManager::setActionGroup(QActionGroup *actionGroup)
289 if (d->actionGroup != actionGroup) {
291 d->actionGroup = actionGroup;
292 d->updateActionList();
296KToggleAction *ThemeManager::actionForTheme()
298 return d->actionForTheme();
301void ThemeManager::setThemeMenu(KActionMenu *menu)
303 if (d->menu != menu) {
305 d->updateActionList();
309QStringList ThemeManager::displayExtraVariables(
const QString &themename)
const
311 QMapIterator<QString, GrantleeTheme::Theme> i(d->themes);
312 while (i.hasNext()) {
314 if (i.value().dirName() == themename) {
315 return i.value().displayExtraVariables();
321GrantleeTheme::Theme ThemeManager::theme(
const QString &themeName)
323 return d->themes.value(themeName);
326QString ThemeManager::pathFromThemes(
const QString &themesRelativePath,
const QString &themeName,
const QString &defaultDesktopFileName)
328 QStringList themesDirectories;
329 if (!themesRelativePath.
isEmpty()) {
331 if (themesDirectories.
count() < 2) {
334 if (!themesDirectories.
contains(localDirectory)) {
335 themesDirectories.
append(localDirectory);
338 for (
const QString &directory : std::as_const(themesDirectories)) {
340 while (dirIt.hasNext()) {
342 const QString dirName = dirIt.fileName();
343 GrantleeTheme::Theme theme = loadTheme(dirIt.filePath(), dirName, defaultDesktopFileName);
344 if (theme.isValid()) {
345 if (dirName == themeName) {
346 return theme.absolutePath();
355GrantleeTheme::Theme ThemeManager::loadTheme(
const QString &themePath,
const QString &dirName,
const QString &defaultDesktopFileName)
357 const GrantleeTheme::Theme theme(themePath, dirName, defaultDesktopFileName);
361QString ThemeManager::configuredThemeName()
const
363 return configuredThemeName(d->applicationType);
366QString ThemeManager::configuredThemeName(
const QString &themeType)
369 const KConfigGroup grp = config->group(themeType);
370 return grp.
readEntry(QStringLiteral(
"themeName"));
373#include "moc_grantleethememanager.cpp"
static Q_INVOKABLE bool authorize(const QString &action)
QString readEntry(const char *key, const char *aDefault=nullptr) const
void dirty(const QString &path)
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
QString i18n(const char *text, const TYPE &arg...)
QString path(const QString &relativePath)
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
QVariant data() const const
void triggered(bool checked)
void append(QList< T > &&value)
qsizetype count() const const
QStringList locateAll(StandardLocation type, const QString &fileName, LocateOptions options)
QString writableLocation(StandardLocation type)
QString & append(QChar ch)
QString arg(Args &&... args) const const
bool isEmpty() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
QString toString() const const