22 #include <QApplication>
25 #include <QMutableListIterator>
27 #include <QStringBuilder>
31 #include "private/effectwatcher_p.h"
34 #include <kcolorscheme.h>
35 #include <kcomponentdata.h>
36 #include <kconfiggroup.h>
38 #include <kdirwatch.h>
40 #include <kglobalsettings.h>
41 #include <kmanagerselection.h>
42 #include <kimagecache.h>
43 #include <ksharedconfig.h>
44 #include <kstandarddirs.h>
45 #include <kwindowsystem.h>
48 #include "animations/animationscriptengine_p.h"
49 #include "libplasma-theme-global.h"
50 #include "private/packages_p.h"
57 #define DEFAULT_WALLPAPER_THEME "default"
58 #define DEFAULT_WALLPAPER_SUFFIX ".png"
73 Q_DECLARE_OPERATORS_FOR_FLAGS(CacheTypes)
78 ThemePrivate(Theme *theme)
80 colorScheme(QPalette::Active, KColorScheme::Window, KSharedConfigPtr(0)),
81 buttonColorScheme(QPalette::Active, KColorScheme::Button, KSharedConfigPtr(0)),
82 viewColorScheme(QPalette::Active, KColorScheme::View, KSharedConfigPtr(0)),
90 compositingActive(KWindowSystem::self()->compositingActive()),
95 useNativeWidgetStyle(
false)
97 generalFont = QApplication::font();
99 cacheTheme = config.cacheTheme();
101 saveTimer =
new QTimer(q);
102 saveTimer->setSingleShot(
true);
103 saveTimer->setInterval(600);
104 QObject::connect(saveTimer, SIGNAL(timeout()), q, SLOT(scheduledCacheUpdate()));
106 updateNotificationTimer =
new QTimer(q);
107 updateNotificationTimer->setSingleShot(
true);
108 updateNotificationTimer->setInterval(500);
109 QObject::connect(updateNotificationTimer, SIGNAL(timeout()), q, SLOT(notifyOfChanged()));
111 if (QPixmap::defaultDepth() > 8) {
112 QObject::connect(KWindowSystem::self(), SIGNAL(compositingChanged(
bool)), q, SLOT(compositingChanged(
bool)));
115 if (!s_blurEffectWatcher) {
116 s_blurEffectWatcher =
new EffectWatcher(
"_KDE_NET_WM_BLUR_BEHIND_REGION");
119 QObject::connect(s_blurEffectWatcher, SIGNAL(effectChanged(
bool)), q, SLOT(blurBehindChanged(
bool)));
129 KConfigGroup &config()
131 if (!cfg.isValid()) {
132 QString groupName =
"Theme";
135 QString app = KGlobal::mainComponent().componentName();
137 if (!app.isEmpty()) {
138 kDebug() <<
"using theme for app" << app;
139 groupName.append(
"-").append(app);
143 cfg = KConfigGroup(KSharedConfig::openConfig(themeRcFile), groupName);
149 QString findInTheme(
const QString &image,
const QString &theme,
bool cache =
true);
150 void compositingChanged(
bool active);
151 void discardCache(CacheTypes caches);
152 void scheduledCacheUpdate();
153 void scheduleThemeChangeNotification(CacheTypes caches);
154 void notifyOfChanged();
155 void colorsChanged();
156 void blurBehindChanged(
bool blur);
158 void settingsFileChanged(
const QString &);
159 void setThemeName(
const QString &themeName,
bool writeSettings);
160 void onAppExitCleanup();
161 void processWallpaperSettings(KConfigBase *metadata);
162 void processAnimationSettings(
const QString &theme, KConfigBase *metadata);
164 const QString processStyleSheet(
const QString &css);
166 static const char *defaultTheme;
167 static const char *systemColorsTheme;
168 static const char *themeRcFile;
171 static EffectWatcher *s_blurEffectWatcher;
176 QList<QString> fallbackThemes;
177 KSharedConfigPtr colors;
178 KColorScheme colorScheme;
179 KColorScheme buttonColorScheme;
180 KColorScheme viewColorScheme;
183 QString defaultWallpaperTheme;
184 QString defaultWallpaperSuffix;
185 int defaultWallpaperWidth;
186 int defaultWallpaperHeight;
187 KImageCache *pixmapCache;
188 KSharedConfigPtr svgElementsCache;
189 QHash<QString, QSet<QString> > invalidElements;
190 QHash<QString, QPixmap> pixmapsToCache;
191 QHash<QString, QString> keysToCache;
192 QHash<QString, QString> idsToCache;
193 QHash<QString, QString> animationMapping;
194 QHash<styles, QString> cachedStyleSheets;
195 QHash<QString, QString> discoveries;
197 QTimer *updateNotificationTimer;
199 CacheTypes cachesToDiscard;
202 bool compositingActive : 1;
206 bool hasWallpapers : 1;
208 bool useNativeWidgetStyle :1;
212 const char *ThemePrivate::defaultTheme =
"default";
213 const char *ThemePrivate::themeRcFile =
"plasmarc";
216 const char *ThemePrivate::systemColorsTheme =
"internal-system-colors";
218 EffectWatcher *ThemePrivate::s_blurEffectWatcher = 0;
221 bool ThemePrivate::useCache()
223 if (cacheTheme && !pixmapCache) {
224 const bool isRegularTheme = themeName != systemColorsTheme;
225 const QString cacheFile =
"plasma_theme_" + themeName;
227 if (isRegularTheme) {
228 const QString cacheFileBase = cacheFile +
"*.kcache";
230 const QString path = KStandardDirs::locate(
"data",
"desktoptheme/" + themeName +
"/metadata.desktop");
234 QString currentCacheFileName;
235 if (!path.isEmpty()) {
236 const KPluginInfo pluginInfo(path);
237 currentCacheFileName = cacheFile +
"_v" + pluginInfo.version() +
".kcache";
241 foreach (
const QString &file, KGlobal::dirs()->findAllResources(
"cache", cacheFileBase)) {
242 if (currentCacheFileName.isEmpty() ||
243 !file.endsWith(currentCacheFileName)) {
251 pixmapCache =
new KImageCache(cacheFile, config.themeCacheKb() * 1024);
255 if (isRegularTheme) {
260 const QFile f(cacheFile);
261 const QFileInfo fileInfo(f);
262 if (fileInfo.lastModified().toTime_t() > uint(pixmapCache->lastModifiedTime())) {
271 void ThemePrivate::onAppExitCleanup()
273 pixmapsToCache.clear();
279 QString ThemePrivate::findInTheme(
const QString &image,
const QString &theme,
bool cache)
281 if (cache && discoveries.contains(image)) {
282 return discoveries[image];
288 search = QLatin1Literal(
"desktoptheme/") % theme % QLatin1Literal(
"/locolor/") % image;
289 search = KStandardDirs::locate(
"data", search);
290 }
else if (!compositingActive) {
291 search = QLatin1Literal(
"desktoptheme/") % theme % QLatin1Literal(
"/opaque/") % image;
292 search = KStandardDirs::locate(
"data", search);
294 search = QLatin1Literal(
"desktoptheme/") % theme % QLatin1Literal(
"/translucent/") % image;
295 search = KStandardDirs::locate(
"data", search);
299 if (search.isEmpty()) {
300 search = QLatin1Literal(
"desktoptheme/") % theme % QLatin1Char(
'/') % image;
301 search = KStandardDirs::locate(
"data", search);
304 if (cache && !search.isEmpty()) {
305 discoveries.insert(image, search);
311 void ThemePrivate::compositingChanged(
bool active)
314 if (compositingActive != active) {
315 compositingActive = active;
322 void ThemePrivate::discardCache(CacheTypes caches)
325 pixmapsToCache.clear();
328 pixmapCache->clear();
336 cachedStyleSheets.clear();
340 invalidElements.clear();
342 if (svgElementsCache) {
343 QFile f(svgElementsCache->name());
344 svgElementsCache = 0;
348 const QString svgElementsFile = KStandardDirs::locateLocal(
"cache",
"plasma-svgelements-" + themeName);
349 svgElementsCache = KSharedConfig::openConfig(svgElementsFile);
353 void ThemePrivate::scheduledCacheUpdate()
356 QHashIterator<QString, QPixmap> it(pixmapsToCache);
357 while (it.hasNext()) {
359 pixmapCache->insertPixmap(idsToCache[it.key()], it.value());
363 pixmapsToCache.clear();
368 void ThemePrivate::colorsChanged()
370 colorScheme = KColorScheme(QPalette::Active, KColorScheme::Window, colors);
371 buttonColorScheme = KColorScheme(QPalette::Active, KColorScheme::Button, colors);
372 viewColorScheme = KColorScheme(QPalette::Active, KColorScheme::View, colors);
373 scheduleThemeChangeNotification(PixmapCache);
376 void ThemePrivate::blurBehindChanged(
bool blur)
378 if (blurActive != blur) {
380 scheduleThemeChangeNotification(PixmapCache | SvgElementsCache);
384 void ThemePrivate::scheduleThemeChangeNotification(CacheTypes caches)
386 cachesToDiscard |= caches;
387 updateNotificationTimer->start();
390 void ThemePrivate::notifyOfChanged()
393 discardCache(cachesToDiscard);
395 emit q->themeChanged();
398 const QString ThemePrivate::processStyleSheet(
const QString &css)
403 if (stylesheet.isEmpty()) {
404 stylesheet = QString(
"\n\
406 color: %textcolor;\n\
407 font-size: %fontsize;\n\
408 font-family: %fontfamily;\n\
410 a:active { color: %activatedlink; }\n\
411 a:link { color: %link; }\n\
412 a:visited { color: %visitedlink; }\n\
413 a:hover { color: %hoveredlink; text-decoration: none; }\n\
415 stylesheet = processStyleSheet(stylesheet);
420 }
else if (css ==
"SVG") {
421 stylesheet = cachedStyleSheets.value(
SVGSTYLE);
422 if (stylesheet.isEmpty()) {
423 QString skel =
".ColorScheme-%1{color:%2;}";
425 stylesheet += skel.arg(
"Text",
"%textcolor");
426 stylesheet += skel.arg(
"Background",
"%backgroundcolor");
428 stylesheet += skel.arg(
"ButtonText",
"%buttontextcolor");
429 stylesheet += skel.arg(
"ButtonBackground",
"%buttonbackgroundcolor");
430 stylesheet += skel.arg(
"ButtonHover",
"%buttonhovercolor");
431 stylesheet += skel.arg(
"ButtonFocus",
"%buttonfocuscolor");
433 stylesheet += skel.arg(
"ViewText",
"%viewtextcolor");
434 stylesheet += skel.arg(
"ViewBackground",
"%viewbackgroundcolor");
435 stylesheet += skel.arg(
"ViewHover",
"%viewhovercolor");
436 stylesheet += skel.arg(
"ViewFocus",
"%viewfocuscolor");
438 stylesheet = processStyleSheet(stylesheet);
439 cachedStyleSheets.insert(
SVGSTYLE, stylesheet);
447 QHash<QString, QString> elements;
466 elements[
"%fontsize"] = QString(
"%1pt").arg(font.pointSize());
467 elements[
"%fontfamily"] = font.family().split(
'[').first();
468 elements[
"%smallfontsize"] = QString(
"%1pt").arg(KGlobalSettings::smallestReadableFont().pointSize());
470 QHash<QString, QString>::const_iterator it = elements.constBegin();
471 QHash<QString, QString>::const_iterator itEnd = elements.constEnd();
472 for ( ; it != itEnd; ++it) {
473 stylesheet.replace(it.key(), it.value());
483 self.d->isDefault =
true;
486 KDirWatch::self()->addFile(KStandardDirs::locateLocal(
"config", ThemePrivate::themeRcFile));
487 QObject::connect(KDirWatch::self(), SIGNAL(created(QString)), &
self, SLOT(settingsFileChanged(QString)));
488 QObject::connect(KDirWatch::self(), SIGNAL(dirty(QString)), &
self, SLOT(settingsFileChanged(QString)));
494 K_GLOBAL_STATIC(ThemeSingleton, privateThemeSelf)
498 return &privateThemeSelf->self;
503 d(new ThemePrivate(this))
506 if (QCoreApplication::instance()) {
507 connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()),
508 this, SLOT(onAppExitCleanup()));
514 d(new ThemePrivate(this))
517 bool useCache = d->cacheTheme;
518 d->cacheTheme =
false;
520 d->cacheTheme = useCache;
521 if (QCoreApplication::instance()) {
522 connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()),
523 this, SLOT(onAppExitCleanup()));
529 if (d->svgElementsCache) {
530 QHashIterator<QString, QSet<QString> > it(d->invalidElements);
531 while (it.hasNext()) {
533 KConfigGroup imageGroup(d->svgElementsCache, it.key());
534 imageGroup.writeEntry(
"invalidElements", it.value().toList());
538 d->onAppExitCleanup();
553 const QStringList themes = KGlobal::dirs()->findAllResources(
"data",
"desktoptheme/*/metadata.desktop",
554 KStandardDirs::NoDuplicates);
555 return KPluginInfo::fromFiles(themes);
558 void ThemePrivate::settingsFileChanged(
const QString &file)
560 if (file.endsWith(themeRcFile)) {
561 config().config()->reparseConfiguration();
562 q->settingsChanged();
568 KConfigGroup cg = d->config();
569 d->setThemeName(cg.readEntry(
"name", ThemePrivate::defaultTheme),
false);
570 cg = KConfigGroup(cg.config(),
"PlasmaToolTips");
571 d->toolTipDelay = cg.readEntry(
"Delay", 700);
576 d->setThemeName(themeName,
true);
579 void ThemePrivate::processWallpaperSettings(KConfigBase *metadata)
586 if (metadata->hasGroup(
"Wallpaper")) {
589 cg = KConfigGroup(metadata,
"Wallpaper");
602 void ThemePrivate::processAnimationSettings(
const QString &theme, KConfigBase *metadata)
604 KConfigGroup cg(metadata,
"Animations");
605 const QString animDir = QLatin1Literal(
"desktoptheme/") % theme % QLatin1Literal(
"/animations/");
606 foreach (
const QString &path, cg.keyList()) {
607 const QStringList anims = cg.readEntry(path, QStringList());
608 foreach (
const QString &anim, anims) {
609 if (!animationMapping.contains(anim)) {
610 kDebug() <<
"Registering animation. animDir: " << animDir
611 <<
"\tanim: " << anim
612 <<
"\tpath: " << path <<
"\t*******\n\n\n";
615 animationMapping.insert(anim, animDir % path);
617 kDebug() <<
"************Animation already registered!\n\n\n";
624 void ThemePrivate::setThemeName(
const QString &tempThemeName,
bool writeSettings)
627 QString theme = tempThemeName;
628 if (theme.isEmpty() || theme == themeName) {
630 if (themeName.isEmpty()) {
631 theme = ThemePrivate::defaultTheme;
639 bool realTheme = theme != systemColorsTheme;
641 QString themePath = KStandardDirs::locate(
"data", QLatin1Literal(
"desktoptheme/") % theme % QLatin1Char(
'/'));
642 if (themePath.isEmpty() && themeName.isEmpty()) {
643 themePath = KStandardDirs::locate(
"data",
"desktoptheme/default/");
645 if (themePath.isEmpty()) {
649 theme = ThemePrivate::defaultTheme;
654 if (themeName == theme) {
661 const QString colorsFile = realTheme ? KStandardDirs::locate(
"data", QLatin1Literal(
"desktoptheme/") % theme % QLatin1Literal(
"/colors"))
668 const QString metadataPath(KStandardDirs::locate(
"data", QLatin1Literal(
"desktoptheme/") % theme % QLatin1Literal(
"/metadata.desktop")));
669 KConfig metadata(metadataPath);
671 processWallpaperSettings(&metadata);
674 animationMapping.clear();
675 processAnimationSettings(themeName, &metadata);
677 KConfigGroup cg(&metadata,
"Settings");
678 useNativeWidgetStyle = cg.readEntry(
"UseNativeWidgetStyle",
false);
679 QString fallback = cg.readEntry(
"FallbackTheme", QString());
681 fallbackThemes.clear();
682 while (!fallback.isEmpty() && !fallbackThemes.contains(fallback)) {
683 fallbackThemes.append(fallback);
685 QString metadataPath(KStandardDirs::locate(
"data", QLatin1Literal(
"desktoptheme/") % theme % QLatin1Literal(
"/metadata.desktop")));
686 KConfig metadata(metadataPath);
687 KConfigGroup cg(&metadata,
"Settings");
688 fallback = cg.readEntry(
"FallbackTheme", QString());
691 if (!fallbackThemes.contains(
"oxygen")) {
692 fallbackThemes.append(
"oxygen");
695 if (!fallbackThemes.contains(ThemePrivate::defaultTheme)) {
696 fallbackThemes.append(ThemePrivate::defaultTheme);
699 foreach (
const QString &theme, fallbackThemes) {
700 QString metadataPath(KStandardDirs::locate(
"data", QLatin1Literal(
"desktoptheme/") % theme % QLatin1Literal(
"/metadata.desktop")));
701 KConfig metadata(metadataPath);
702 processAnimationSettings(theme, &metadata);
703 processWallpaperSettings(&metadata);
707 if (colorsFile.isEmpty()) {
709 QObject::connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
710 q, SLOT(colorsChanged()), Qt::UniqueConnection);
712 QObject::disconnect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
713 q, SLOT(colorsChanged()));
714 colors = KSharedConfig::openConfig(colorsFile);
717 colorScheme = KColorScheme(QPalette::Active, KColorScheme::Window, colors);
718 buttonColorScheme = KColorScheme(QPalette::Active, KColorScheme::Button, colors);
719 viewColorScheme = KColorScheme(QPalette::Active, KColorScheme::View, colors);
720 hasWallpapers = KStandardDirs::exists(KStandardDirs::locateLocal(
"data", QLatin1Literal(
"desktoptheme/") % theme % QLatin1Literal(
"/wallpapers/")));
722 if (realTheme && isDefault && writeSettings) {
724 KConfigGroup &cg = config();
725 if (ThemePrivate::defaultTheme == themeName) {
726 cg.deleteEntry(
"name");
728 cg.writeEntry(
"name", themeName);
733 scheduleThemeChangeNotification(SvgElementsCache);
744 if (name.contains(
"../") || name.isEmpty()) {
750 const QString svgzName = name % QLatin1Literal(
".svgz");
751 QString path = d->findInTheme(svgzName, d->themeName);
753 if (path.isEmpty()) {
755 const QString svgName = name % QLatin1Literal(
".svg");
756 path = d->findInTheme(svgName, d->themeName);
759 for (
int i = 0; path.isEmpty() && i < d->fallbackThemes.count(); ++i) {
760 if (d->themeName == d->fallbackThemes[i]) {
765 path = d->findInTheme(svgzName, d->fallbackThemes[i]);
767 if (path.isEmpty()) {
769 path = d->findInTheme(svgName, d->fallbackThemes[i]);
785 return d->processStyleSheet(css);
790 const QString path = d->animationMapping.value(name);
791 if (path.isEmpty()) {
796 return KStandardDirs::locate(
"data", path);
802 QString image = d->defaultWallpaperTheme;
804 image.append(
"/contents/images/%1x%2").append(d->defaultWallpaperSuffix);
805 QString defaultImage = image.arg(d->defaultWallpaperWidth).arg(d->defaultWallpaperHeight);
807 if (size.isValid()) {
812 image = image.arg(size.width()).arg(size.height());
814 image = defaultImage;
820 if (d->hasWallpapers) {
822 fullPath = d->findInTheme(QLatin1Literal(
"wallpapers/") % image, d->themeName);
824 if (fullPath.isEmpty()) {
825 fullPath = d->findInTheme(QLatin1Literal(
"wallpapers/") % defaultImage, d->themeName);
829 if (fullPath.isEmpty()) {
832 fullPath = KStandardDirs::locate(
"wallpaper", image);
835 if (fullPath.isEmpty()) {
839 fullPath = KStandardDirs::locate(
"wallpaper", defaultImage);
841 if (fullPath.isEmpty()) {
842 kDebug() <<
"exhausted every effort to find a wallpaper.";
851 if (name.contains(
"../")) {
856 return !(d->findInTheme(name % QLatin1Literal(
".svgz"), d->themeName,
false).isEmpty()) ||
857 !(d->findInTheme(name % QLatin1Literal(
".svg"), d->themeName,
false).isEmpty());
869 return d->colorScheme.foreground(KColorScheme::NormalText).color();
872 return d->colorScheme.decoration(KColorScheme::HoverColor).color();
875 return d->colorScheme.background(KColorScheme::NormalBackground).color();
878 return d->buttonColorScheme.foreground(KColorScheme::NormalText).color();
881 return d->buttonColorScheme.background(KColorScheme::NormalBackground).color();
884 return d->buttonColorScheme.decoration(KColorScheme::HoverColor).color();
887 return d->buttonColorScheme.decoration(KColorScheme::FocusColor).color();
890 return d->viewColorScheme.foreground(KColorScheme::NormalText).color();
893 return d->viewColorScheme.background(KColorScheme::NormalBackground).color();
896 return d->viewColorScheme.decoration(KColorScheme::HoverColor).color();
899 return d->viewColorScheme.decoration(KColorScheme::FocusColor).color();
902 return d->viewColorScheme.foreground(KColorScheme::LinkText).color();
905 return d->viewColorScheme.foreground(KColorScheme::VisitedText).color();
914 d->generalFont =
font;
921 KConfigGroup cg(KGlobal::config(),
"General");
922 return cg.readEntry(
"desktopFont", d->generalFont);
928 return d->generalFont;
932 return KGlobalSettings::smallestReadableFont();
936 return d->generalFont;
942 return QFontMetrics(d->generalFont);
947 return d->compositingActive;
952 if (d->useGlobal == useGlobal) {
956 d->useGlobal = useGlobal;
957 d->cfg = KConfigGroup();
958 d->themeName.clear();
969 return d->useNativeWidgetStyle;
975 const QString
id = d->keysToCache.value(key);
976 if (d->pixmapsToCache.contains(
id)) {
977 pix = d->pixmapsToCache.value(
id);
978 return !pix.isNull();
982 if (d->pixmapCache->findPixmap(key, &temp) && !temp.isNull()) {
994 if (d->useCache() && lastModified > uint(d->pixmapCache->lastModifiedTime())) {
1003 if (d->useCache()) {
1004 d->pixmapCache->insertPixmap(key, pix);
1010 if (d->useCache()) {
1011 d->pixmapsToCache.insert(
id, pix);
1013 if (d->idsToCache.contains(
id)) {
1014 d->keysToCache.remove(d->idsToCache[
id]);
1017 d->keysToCache.insert(key,
id);
1018 d->idsToCache.insert(
id, key);
1019 d->saveTimer->start();
1025 if (!d->svgElementsCache) {
1029 KConfigGroup imageGroup(d->svgElementsCache, image);
1030 rect = imageGroup.readEntry(element % QLatin1Literal(
"Size"), QRectF());
1032 if (rect.isValid()) {
1038 if (element.indexOf(
'_') <= 0) {
1042 bool invalid =
false;
1044 QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
1045 if (it == d->invalidElements.end()) {
1046 QSet<QString> elements = imageGroup.readEntry(
"invalidElements", QStringList()).toSet();
1047 d->invalidElements.insert(image, elements);
1048 invalid = elements.contains(element);
1050 invalid = it.value().contains(element);
1058 if (!d->svgElementsCache) {
1059 return QStringList();
1062 KConfigGroup imageGroup(d->svgElementsCache, image);
1063 QStringList keys = imageGroup.keyList();
1065 QMutableListIterator<QString> i(keys);
1066 while (i.hasNext()) {
1067 QString key = i.next();
1068 if (key.endsWith(
"Size")) {
1070 key.resize(key.size() - 4);
1081 if (!d->svgElementsCache) {
1085 if (rect.isValid()) {
1086 KConfigGroup imageGroup(d->svgElementsCache, image);
1087 imageGroup.writeEntry(element % QLatin1Literal(
"Size"), rect);
1089 QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
1090 if (it == d->invalidElements.end()) {
1091 d->invalidElements[image].insert(element);
1092 }
else if (!it.value().contains(element)) {
1093 if (it.value().count() > 1000) {
1094 it.value().erase(it.value().begin());
1097 it.value().insert(element);
1104 if (d->svgElementsCache) {
1105 KConfigGroup imageGroup(d->svgElementsCache, image);
1106 imageGroup.deleteGroup();
1109 d->invalidElements.remove(image);
1114 QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
1115 if (it != d->invalidElements.end()) {
1116 if (!d->svgElementsCache) {
1117 KConfigGroup imageGroup(d->svgElementsCache, it.key());
1118 imageGroup.writeEntry(
"invalidElements", it.value().toList());
1121 d->invalidElements.erase(it);
1128 if (d->useCache()) {
1137 const QString metadataPath(KStandardDirs::locate(
"data", QLatin1Literal(
"desktoptheme/") % d->themeName % QLatin1Literal(
"/metadata.desktop")));
1138 KConfig metadata(metadataPath);
1139 KConfigGroup brandConfig(&metadata,
"Branding");
1140 return brandConfig.readEntry(
"homepage", KUrl(
"http://www.kde.org"));
1145 return d->toolTipDelay;
1150 #include <theme.moc>