diff --git a/src/grantleethememanager.cpp b/src/grantleethememanager.cpp index f4b81b6..736f7c5 100644 --- a/src/grantleethememanager.cpp +++ b/src/grantleethememanager.cpp @@ -1,397 +1,392 @@ /* Copyright (c) 2013-2019 Montel Laurent This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "grantleethememanager.h" #include "grantleetheme_p.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace GrantleeTheme; class Q_DECL_HIDDEN ThemeManager::Private { public: Private(const QString &type, const QString &desktopFileName, KActionCollection *ac, const QString &relativePath, ThemeManager *qq) : applicationType(type) , defaultDesktopFileName(desktopFileName) , actionGroup(nullptr) , menu(nullptr) , actionCollection(ac) , q(qq) { watch = new KDirWatch(q); initThemesDirectories(relativePath); if (KAuthorized::authorize(QStringLiteral("ghns"))) { downloadThemesAction = new QAction(i18n("Download New Themes..."), q); downloadThemesAction->setIcon(QIcon::fromTheme(QStringLiteral("get-hot-new-stuff"))); if (actionCollection) { actionCollection->addAction(QStringLiteral("download_header_themes"), downloadThemesAction); } separatorAction = new QAction(q); separatorAction->setSeparator(true); q->connect(downloadThemesAction, &QAction::triggered, q, [this]() { slotDownloadHeaderThemes(); }); } q->connect(watch, &KDirWatch::dirty, q, [this]() { directoryChanged(); }); updateThemesPath(true); // Migrate the old configuration format that only support mail and addressbook // theming to the new generic format KSharedConfig::Ptr config = KSharedConfig::openConfig(); if (config->hasGroup(QStringLiteral("GrantleeTheme"))) { const KConfigGroup group = config->group(QStringLiteral("GrantleeTheme")); const QString mailTheme = group.readEntry(QStringLiteral("grantleeMailThemeName")); const QString addressbookTheme = group.readEntry(QStringLiteral("grantleeAddressBookThemeName")); config->group(QStringLiteral("mail")).writeEntry(QStringLiteral("themeName"), mailTheme); config->group(QStringLiteral("addressbook")).writeEntry(QStringLiteral("themeName"), addressbookTheme); config->deleteGroup(QStringLiteral("GrantleeTheme")); } } ~Private() { removeActions(); themes.clear(); if (downloadThemesDialog) { delete downloadThemesDialog.data(); } } void slotDownloadHeaderThemes() { if (!downloadThemesDialog) { downloadThemesDialog = new KNS3::DownloadDialog(downloadConfigFileName); } downloadThemesDialog.data()->show(); } void directoryChanged() { updateThemesPath(); updateActionList(); Q_EMIT q->updateThemes(); } void updateThemesPath(bool init = false) { if (!init) { if (!themesDirectories.isEmpty()) { for (const QString &directory : qAsConst(themesDirectories)) { watch->removeDir(directory); } } else { return; } } // clear all previous theme information themes.clear(); for (const QString &directory : qAsConst(themesDirectories)) { QDirIterator dirIt(directory, QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot); QStringList alreadyLoadedThemeName; while (dirIt.hasNext()) { dirIt.next(); const QString dirName = dirIt.fileName(); GrantleeTheme::Theme theme = q->loadTheme(dirIt.filePath(), dirName, defaultDesktopFileName); if (theme.isValid()) { QString themeName = theme.name(); if (alreadyLoadedThemeName.contains(themeName)) { int i = 2; const QString originalName(theme.name()); while (alreadyLoadedThemeName.contains(themeName)) { themeName = originalName + QStringLiteral(" (%1)").arg(i); ++i; } theme.d->name = themeName; } alreadyLoadedThemeName << themeName; themes.insert(dirName, theme); //qDebug()<<" theme.name()"<addDir(directory); } Q_EMIT q->themesChanged(); watch->startScan(); } void removeActions() { if (!actionGroup || !menu) { return; } for (KToggleAction *action : qAsConst(themesActionList)) { actionGroup->removeAction(action); menu->removeAction(action); if (actionCollection) { actionCollection->removeAction(action); } } if (separatorAction) { menu->removeAction(separatorAction); menu->removeAction(downloadThemesAction); } themesActionList.clear(); } void updateActionList() { if (!actionGroup || !menu) { return; } QString themeActivated; QAction *selectedAction = actionGroup->checkedAction(); if (selectedAction) { themeActivated = selectedAction->data().toString(); } removeActions(); bool themeActivatedFound = false; QMapIterator i(themes); while (i.hasNext()) { i.next(); GrantleeTheme::Theme theme = i.value(); KToggleAction *act = new KToggleAction(theme.name(), q); act->setToolTip(theme.description()); act->setData(theme.dirName()); if (theme.dirName() == themeActivated) { act->setChecked(true); themeActivatedFound = true; } themesActionList.append(act); actionGroup->addAction(act); menu->addAction(act); q->connect(act, &KToggleAction::triggered, q, [this]() { slotThemeSelected(); }); } if (!themeActivatedFound) { if (!themesActionList.isEmpty() && !themeActivated.isEmpty()) { //Activate first item if we removed theme. KToggleAction *act = themesActionList.at(0); act->setChecked(true); selectTheme(act); } } if (separatorAction) { menu->addAction(separatorAction); menu->addAction(downloadThemesAction); } } void selectTheme(KToggleAction *act) { if (act) { KSharedConfig::Ptr config = KSharedConfig::openConfig(); KConfigGroup group = config->group(applicationType); group.writeEntry(QStringLiteral("themeName"), act->data().toString()); config->sync(); } } void slotThemeSelected() { if (q->sender()) { KToggleAction *act = qobject_cast(q->sender()); selectTheme(act); Q_EMIT q->grantleeThemeSelected(); } } KToggleAction *actionForTheme() { const KSharedConfig::Ptr config = KSharedConfig::openConfig(); const KConfigGroup group = config->group(applicationType); const QString themeName = group.readEntry(QStringLiteral("themeName"), QStringLiteral("default")); if (themeName.isEmpty()) { return nullptr; } for (KToggleAction *act : qAsConst(themesActionList)) { if (act->data().toString() == themeName) { return static_cast(act); } } return nullptr; } void initThemesDirectories(const QString &themesRelativePath) { if (!themesRelativePath.isEmpty()) { themesDirectories = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, themesRelativePath, QStandardPaths::LocateDirectory); - if (themesDirectories.count() < 2) { - //Make sure to add local directory - const QString localDirectory = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + themesRelativePath; - if (!themesDirectories.contains(localDirectory)) { - themesDirectories.append(localDirectory); - } - } + const QString localDirectory = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + themesRelativePath; + themesDirectories.append(localDirectory); } } QString applicationType; QString defaultDesktopFileName; QString downloadConfigFileName; QStringList themesDirectories; QMap themes; QList themesActionList; KDirWatch *watch = nullptr; QActionGroup *actionGroup = nullptr; KActionMenu *menu = nullptr; KActionCollection *actionCollection = nullptr; QAction *separatorAction = nullptr; QAction *downloadThemesAction = nullptr; QPointer downloadThemesDialog; ThemeManager *q; }; ThemeManager::ThemeManager(const QString &applicationType, const QString &defaultDesktopFileName, KActionCollection *actionCollection, const QString &path, QObject *parent) : QObject(parent) , d(new Private(applicationType, defaultDesktopFileName, actionCollection, path, this)) { } ThemeManager::~ThemeManager() { delete d; } QMap ThemeManager::themes() const { return d->themes; } void ThemeManager::setActionGroup(QActionGroup *actionGroup) { if (d->actionGroup != actionGroup) { d->removeActions(); d->actionGroup = actionGroup; d->updateActionList(); } } KToggleAction *ThemeManager::actionForTheme() { return d->actionForTheme(); } void ThemeManager::setThemeMenu(KActionMenu *menu) { if (d->menu != menu) { d->menu = menu; d->updateActionList(); } } QStringList ThemeManager::displayExtraVariables(const QString &themename) const { QMapIterator i(d->themes); while (i.hasNext()) { i.next(); if (i.value().dirName() == themename) { return i.value().displayExtraVariables(); } } return QStringList(); } GrantleeTheme::Theme ThemeManager::theme(const QString &themeName) { return d->themes.value(themeName); } void ThemeManager::setDownloadNewStuffConfigFile(const QString &configFileName) { d->downloadConfigFileName = configFileName; } QString ThemeManager::pathFromThemes(const QString &themesRelativePath, const QString &themeName, const QString &defaultDesktopFileName) { QStringList themesDirectories; if (!themesRelativePath.isEmpty()) { themesDirectories = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, themesRelativePath, QStandardPaths::LocateDirectory); if (themesDirectories.count() < 2) { //Make sure to add local directory const QString localDirectory = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + themesRelativePath; if (!themesDirectories.contains(localDirectory)) { themesDirectories.append(localDirectory); } } for (const QString &directory : qAsConst(themesDirectories)) { QDirIterator dirIt(directory, QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot); while (dirIt.hasNext()) { dirIt.next(); const QString dirName = dirIt.fileName(); GrantleeTheme::Theme theme = loadTheme(dirIt.filePath(), dirName, defaultDesktopFileName); if (theme.isValid()) { if (dirName == themeName) { return theme.absolutePath(); } } } } } return QString(); } GrantleeTheme::Theme ThemeManager::loadTheme(const QString &themePath, const QString &dirName, const QString &defaultDesktopFileName) { const GrantleeTheme::Theme theme(themePath, dirName, defaultDesktopFileName); return theme; } QString ThemeManager::configuredThemeName() const { return configuredThemeName(d->applicationType); } QString ThemeManager::configuredThemeName(const QString &themeType) { const KSharedConfig::Ptr config = KSharedConfig::openConfig(); const KConfigGroup grp = config->group(themeType); return grp.readEntry(QStringLiteral("themeName")); } #include "moc_grantleethememanager.cpp"