00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "theme.h"
00021
00022 #include <QApplication>
00023 #include <QFile>
00024 #include <QFileInfo>
00025 #include <QTimer>
00026 #include <QPair>
00027 #ifdef Q_WS_X11
00028 #include <QX11Info>
00029 #endif
00030
00031 #include <kcolorscheme.h>
00032 #include <kcomponentdata.h>
00033 #include <kconfiggroup.h>
00034 #include <kdebug.h>
00035 #include <kdirwatch.h>
00036 #include <kglobal.h>
00037 #include <kglobalsettings.h>
00038 #include <kmanagerselection.h>
00039 #include <kpixmapcache.h>
00040 #include <ksharedconfig.h>
00041 #include <kstandarddirs.h>
00042 #include <kwindowsystem.h>
00043
00044 #include "private/packages_p.h"
00045
00046 namespace Plasma
00047 {
00048
00049 #define DEFAULT_WALLPAPER_THEME "Air"
00050 #define DEFAULT_WALLPAPER_SUFFIX ".jpg"
00051 static const int DEFAULT_WALLPAPER_WIDTH = 1920;
00052 static const int DEFAULT_WALLPAPER_HEIGHT = 1200;
00053
00054 class ThemePrivate
00055 {
00056 public:
00057 ThemePrivate(Theme *theme)
00058 : q(theme),
00059 colorScheme(QPalette::Active, KColorScheme::Window, KSharedConfigPtr(0)),
00060 buttonColorScheme(QPalette::Active, KColorScheme::Button, KSharedConfigPtr(0)),
00061 defaultWallpaperTheme(DEFAULT_WALLPAPER_THEME),
00062 defaultWallpaperSuffix(DEFAULT_WALLPAPER_SUFFIX),
00063 defaultWallpaperWidth(DEFAULT_WALLPAPER_WIDTH),
00064 defaultWallpaperHeight(DEFAULT_WALLPAPER_HEIGHT),
00065 pixmapCache(0),
00066 locolor(false),
00067 compositingActive(KWindowSystem::compositingActive()),
00068 isDefault(false),
00069 useGlobal(true),
00070 hasWallpapers(false),
00071 useNativeWidgetStyle(false)
00072 {
00073 generalFont = QApplication::font();
00074 cacheTheme = cacheConfig().readEntry("CacheTheme", true);
00075
00076 #ifdef Q_WS_X11
00077 Display *dpy = QX11Info::display();
00078 int screen = DefaultScreen(dpy);
00079 locolor = DefaultDepth(dpy, screen) < 16;
00080
00081 if (!locolor) {
00082 char net_wm_cm_name[100];
00083 sprintf(net_wm_cm_name, "_NET_WM_CM_S%d", screen);
00084 compositeWatch = new KSelectionWatcher(net_wm_cm_name, -1, q);
00085 QObject::connect(compositeWatch, SIGNAL(newOwner(Window)), q, SLOT(compositingChanged()));
00086 QObject::connect(compositeWatch, SIGNAL(lostOwner()), q, SLOT(compositingChanged()));
00087 }
00088 #endif
00089
00090 saveTimer = new QTimer(q);
00091 saveTimer->setSingleShot(true);
00092 QObject::connect(saveTimer, SIGNAL(timeout()), q, SLOT(scheduledCacheUpdate()));
00093 }
00094
00095 ~ThemePrivate()
00096 {
00097 delete pixmapCache;
00098 }
00099
00100 KConfigGroup cacheConfig()
00101 {
00102 return KConfigGroup(KSharedConfig::openConfig(themeRcFile), "CachePolicies");
00103 }
00104
00105 KConfigGroup &config()
00106 {
00107 if (!cfg.isValid()) {
00108 QString groupName = "Theme";
00109
00110 if (!useGlobal) {
00111 QString app = KGlobal::mainComponent().componentName();
00112
00113 if (!app.isEmpty() && app != "plasma") {
00114 kDebug() << "using theme for app" << app;
00115 groupName.append("-").append(app);
00116 }
00117 }
00118
00119 cfg = KConfigGroup(KSharedConfig::openConfig(themeRcFile), groupName);
00120 }
00121
00122 return cfg;
00123 }
00124
00125 QString findInTheme(const QString &image, const QString &theme) const;
00126 void compositingChanged();
00127 void discardCache(bool recreateElementsCache);
00128 void scheduledCacheUpdate();
00129 void colorsChanged();
00130 bool useCache();
00131 void settingsFileChanged(const QString &);
00132 void setThemeName(const QString &themeName, bool writeSettings);
00133
00134 static const char *defaultTheme;
00135 static const char *themeRcFile;
00136 static PackageStructure::Ptr packageStructure;
00137
00138 Theme *q;
00139 QString themeName;
00140 QList<QString> fallbackThemes;
00141 KSharedConfigPtr colors;
00142 KColorScheme colorScheme;
00143 KColorScheme buttonColorScheme;
00144 KConfigGroup cfg;
00145 QFont generalFont;
00146 QString defaultWallpaperTheme;
00147 QString defaultWallpaperSuffix;
00148 int defaultWallpaperWidth;
00149 int defaultWallpaperHeight;
00150 KPixmapCache *pixmapCache;
00151 KSharedConfigPtr svgElementsCache;
00152 QHash<QString, QSet<QString> > invalidElements;
00153 QHash<QString, QPixmap> pixmapsToCache;
00154 QHash<QString, QString> keysToCache;
00155 QHash<QString, QString> idsToCache;
00156 QTimer *saveTimer;
00157
00158 #ifdef Q_WS_X11
00159 KSelectionWatcher *compositeWatch;
00160 #endif
00161 bool locolor : 1;
00162 bool compositingActive : 1;
00163 bool isDefault : 1;
00164 bool useGlobal : 1;
00165 bool hasWallpapers : 1;
00166 bool cacheTheme : 1;
00167 bool useNativeWidgetStyle :1;
00168 };
00169
00170 PackageStructure::Ptr ThemePrivate::packageStructure(0);
00171 const char *ThemePrivate::defaultTheme = "default";
00172 const char *ThemePrivate::themeRcFile = "plasmarc";
00173
00174 bool ThemePrivate::useCache()
00175 {
00176 if (cacheTheme && !pixmapCache) {
00177 pixmapCache = new KPixmapCache("plasma_theme_" + themeName);
00178 pixmapCache->setCacheLimit(cacheConfig().readEntry("ThemeCacheKb", 80 * 1024));
00179 }
00180
00181 return cacheTheme;
00182 }
00183
00184 QString ThemePrivate::findInTheme(const QString &image, const QString &theme) const
00185 {
00186
00187 QString search;
00188
00189 if (locolor) {
00190 search = "desktoptheme/" + theme + "/locolor/" + image;
00191 search = KStandardDirs::locate("data", search);
00192 } else if (!compositingActive) {
00193 search = "desktoptheme/" + theme + "/opaque/" + image;
00194 search = KStandardDirs::locate("data", search);
00195 }
00196
00197
00198 if (search.isEmpty()) {
00199 search = "desktoptheme/" + theme + '/' + image;
00200 search = KStandardDirs::locate("data", search);
00201 }
00202
00203 return search;
00204 }
00205
00206 void ThemePrivate::compositingChanged()
00207 {
00208 #ifdef Q_WS_X11
00209 bool nowCompositingActive = compositeWatch->owner() != None;
00210
00211 if (compositingActive != nowCompositingActive) {
00212 compositingActive = nowCompositingActive;
00213 discardCache(true);
00214 emit q->themeChanged();
00215 }
00216 #endif
00217 }
00218
00219 void ThemePrivate::discardCache(bool recreateElementsCache)
00220 {
00221 KPixmapCache::deleteCache("plasma_theme_" + themeName);
00222 delete pixmapCache;
00223 pixmapCache = 0;
00224 invalidElements.clear();
00225 pixmapsToCache.clear();
00226 saveTimer->stop();
00227
00228 svgElementsCache = 0;
00229 QString svgElementsFile = KStandardDirs::locateLocal("cache", "plasma-svgelements-" + themeName);
00230 if (!svgElementsFile.isEmpty()) {
00231 QFile f(svgElementsFile);
00232 f.remove();
00233 }
00234
00235 if (recreateElementsCache) {
00236 svgElementsCache = KSharedConfig::openConfig(svgElementsFile);
00237 }
00238 }
00239
00240 void ThemePrivate::scheduledCacheUpdate()
00241 {
00242 QHashIterator<QString, QPixmap> it(pixmapsToCache);
00243 while (it.hasNext()) {
00244 it.next();
00245 pixmapCache->insert(idsToCache[it.key()], it.value());
00246 }
00247
00248 pixmapsToCache.clear();
00249 keysToCache.clear();
00250 idsToCache.clear();
00251 }
00252
00253 void ThemePrivate::colorsChanged()
00254 {
00255 discardCache(true);
00256 colorScheme = KColorScheme(QPalette::Active, KColorScheme::Window, colors);
00257 buttonColorScheme = KColorScheme(QPalette::Active, KColorScheme::Button, colors);
00258 emit q->themeChanged();
00259 }
00260
00261 class ThemeSingleton
00262 {
00263 public:
00264 ThemeSingleton()
00265 {
00266 self.d->isDefault = true;
00267
00268
00269 KDirWatch::self()->addFile(KStandardDirs::locateLocal("config", ThemePrivate::themeRcFile));
00270 QObject::connect(KDirWatch::self(), SIGNAL(created(QString)), &self, SLOT(settingsFileChanged(QString)));
00271 QObject::connect(KDirWatch::self(), SIGNAL(dirty(QString)), &self, SLOT(settingsFileChanged(QString)));
00272 }
00273
00274 Theme self;
00275 };
00276
00277 K_GLOBAL_STATIC(ThemeSingleton, privateThemeSelf)
00278
00279 Theme *Theme::defaultTheme()
00280 {
00281 return &privateThemeSelf->self;
00282 }
00283
00284 Theme::Theme(QObject *parent)
00285 : QObject(parent),
00286 d(new ThemePrivate(this))
00287 {
00288 settingsChanged();
00289 }
00290
00291 Theme::Theme(const QString &themeName, QObject *parent)
00292 : QObject(parent),
00293 d(new ThemePrivate(this))
00294 {
00295
00296 bool useCache = d->cacheTheme;
00297 d->cacheTheme = false;
00298 setThemeName(themeName);
00299 d->cacheTheme = useCache;
00300 }
00301
00302 Theme::~Theme()
00303 {
00304 QHashIterator<QString, QSet<QString> > it(d->invalidElements);
00305 while (it.hasNext()) {
00306 it.next();
00307 KConfigGroup imageGroup(d->svgElementsCache, it.key());
00308 imageGroup.writeEntry("invalidElements", it.value().toList());
00309 }
00310
00311 delete d;
00312 }
00313
00314 PackageStructure::Ptr Theme::packageStructure()
00315 {
00316 if (!ThemePrivate::packageStructure) {
00317 ThemePrivate::packageStructure = new ThemePackage();
00318 }
00319
00320 return ThemePrivate::packageStructure;
00321 }
00322
00323 KPluginInfo::List Theme::listThemeInfo()
00324 {
00325 QStringList themes = KGlobal::dirs()->findAllResources("data", "desktoptheme/*/metadata.desktop",
00326 KStandardDirs::NoDuplicates);
00327 return KPluginInfo::fromFiles(themes);
00328 }
00329
00330 void ThemePrivate::settingsFileChanged(const QString &file)
00331 {
00332 if (file.endsWith(themeRcFile)) {
00333 config().config()->reparseConfiguration();
00334 q->settingsChanged();
00335 }
00336 }
00337
00338 void Theme::settingsChanged()
00339 {
00340 d->setThemeName(d->config().readEntry("name", ThemePrivate::defaultTheme), false);
00341 }
00342
00343 void Theme::setThemeName(const QString &themeName)
00344 {
00345 d->setThemeName(themeName, true);
00346 }
00347
00348 void ThemePrivate::setThemeName(const QString &tempThemeName, bool writeSettings)
00349 {
00350
00351 QString theme = tempThemeName;
00352 if (theme.isEmpty() || theme == themeName) {
00353
00354 if (themeName.isEmpty()) {
00355 theme = ThemePrivate::defaultTheme;
00356 } else {
00357 return;
00358 }
00359 }
00360
00361
00362 QString themePath = KStandardDirs::locate("data", "desktoptheme/" + theme + '/');
00363 if (themePath.isEmpty() && themeName.isEmpty()) {
00364 themePath = KStandardDirs::locate("data", "desktoptheme/default/");
00365
00366 if (themePath.isEmpty()) {
00367 return;
00368 }
00369
00370 theme = ThemePrivate::defaultTheme;
00371 }
00372
00373 if (themeName == theme) {
00374 return;
00375 }
00376
00377
00378 if (!themeName.isEmpty() && pixmapCache) {
00379 discardCache(false);
00380 }
00381
00382 themeName = theme;
00383
00384
00385 QString colorsFile = KStandardDirs::locate("data", "desktoptheme/" + theme + "/colors");
00386
00387
00388
00389 QString metadataPath(KStandardDirs::locate("data", "desktoptheme/" + theme + "/metadata.desktop"));
00390 KConfig metadata(metadataPath);
00391 KConfigGroup cg;
00392 if (metadata.hasGroup("Wallpaper")) {
00393
00394
00395 cg = KConfigGroup(&metadata, "Wallpaper");
00396 } else {
00397
00398
00399 cg = config();
00400 }
00401
00402 defaultWallpaperTheme = cg.readEntry("defaultWallpaperTheme", DEFAULT_WALLPAPER_THEME);
00403 defaultWallpaperSuffix = cg.readEntry("defaultFileSuffix", DEFAULT_WALLPAPER_SUFFIX);
00404 defaultWallpaperWidth = cg.readEntry("defaultWidth", DEFAULT_WALLPAPER_WIDTH);
00405 defaultWallpaperHeight = cg.readEntry("defaultHeight", DEFAULT_WALLPAPER_HEIGHT);
00406
00407 cg = KConfigGroup(&metadata, "Settings");
00408 useNativeWidgetStyle = cg.readEntry("UseNativeWidgetStyle", false);
00409 QString fallback = cg.readEntry("FallbackTheme", QString());
00410
00411 fallbackThemes.clear();
00412 while (!fallback.isEmpty() && !fallbackThemes.contains(fallback)) {
00413 fallbackThemes.append(fallback);
00414
00415 QString metadataPath(KStandardDirs::locate("data", "desktoptheme/" + theme + "/metadata.desktop"));
00416 KConfig metadata(metadataPath);
00417 cg = KConfigGroup(&metadata, "Settings");
00418 fallback = cg.readEntry("FallbackTheme", QString());
00419
00420
00421 }
00422
00423 if (!fallbackThemes.contains("oxygen")) {
00424 fallbackThemes.append("oxygen");
00425 }
00426
00427 if (!fallbackThemes.contains(ThemePrivate::defaultTheme)) {
00428 fallbackThemes.append(ThemePrivate::defaultTheme);
00429 }
00430
00431 QObject::disconnect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
00432 q, SLOT(colorsChanged()));
00433
00434 if (colorsFile.isEmpty()) {
00435 colors = 0;
00436 QObject::connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
00437 q, SLOT(colorsChanged()));
00438 } else {
00439 colors = KSharedConfig::openConfig(colorsFile);
00440 }
00441
00442 colorScheme = KColorScheme(QPalette::Active, KColorScheme::Window, colors);
00443 buttonColorScheme = KColorScheme(QPalette::Active, KColorScheme::Button, colors);
00444 hasWallpapers = KStandardDirs::exists(KStandardDirs::locateLocal("data", "desktoptheme/" + theme + "/wallpapers/"));
00445
00446 if (isDefault && writeSettings) {
00447
00448 KConfigGroup &cg = config();
00449 if (ThemePrivate::defaultTheme == themeName) {
00450 cg.deleteEntry("name");
00451 } else {
00452 cg.writeEntry("name", themeName);
00453 }
00454 cg.sync();
00455 }
00456
00457
00458 QFile f(metadataPath);
00459 QFileInfo info(f);
00460
00461 if (useCache() && info.lastModified().toTime_t() > pixmapCache->timestamp()) {
00462 discardCache(false);
00463 }
00464
00465 invalidElements.clear();
00466 QString svgElementsFile = KStandardDirs::locateLocal("cache", "plasma-svgelements-" + themeName);
00467 svgElementsCache = KSharedConfig::openConfig(svgElementsFile);
00468
00469 emit q->themeChanged();
00470 }
00471
00472 QString Theme::themeName() const
00473 {
00474 return d->themeName;
00475 }
00476
00477 QString Theme::imagePath(const QString &name) const
00478 {
00479
00480 if (name.contains("../") || name.isEmpty()) {
00481
00482 kDebug() << "Theme says: bad image path " << name;
00483 return QString();
00484 }
00485
00486 QString path = d->findInTheme(name + ".svgz", d->themeName);
00487
00488 if (path.isEmpty()) {
00489
00490 path = d->findInTheme(name + ".svg", d->themeName);
00491
00492
00493 for (int i = 0; path.isEmpty() && i < d->fallbackThemes.count(); ++i) {
00494 if (d->themeName == d->fallbackThemes[i]) {
00495 continue;
00496 }
00497
00498
00499 path = d->findInTheme(name + ".svgz", d->fallbackThemes[i]);
00500
00501 if (path.isEmpty()) {
00502
00503 path = d->findInTheme(name + ".svg", d->fallbackThemes[i]);
00504 }
00505 }
00506 }
00507
00508 if (path.isEmpty()) {
00509 kDebug() << "Theme says: bad image path " << name;
00510 }
00511
00512 return path;
00513 }
00514
00515 QString Theme::wallpaperPath(const QSize &size) const
00516 {
00517 QString fullPath;
00518 QString image = d->defaultWallpaperTheme;
00519
00520 image.append("/contents/images/%1x%2").append(d->defaultWallpaperSuffix);
00521 QString defaultImage = image.arg(d->defaultWallpaperWidth).arg(d->defaultWallpaperHeight);
00522
00523 if (size.isValid()) {
00524
00525
00526
00527
00528 image = image.arg(size.width()).arg(size.height());
00529 } else {
00530 image = defaultImage;
00531 }
00532
00533
00534
00535
00536 if (d->hasWallpapers) {
00537
00538 fullPath = d->findInTheme("wallpapers/" + image, d->themeName);
00539
00540 if (fullPath.isEmpty()) {
00541 fullPath = d->findInTheme("wallpapers/" + defaultImage, d->themeName);
00542 }
00543 }
00544
00545 if (fullPath.isEmpty()) {
00546
00547
00548 fullPath = KStandardDirs::locate("wallpaper", image);
00549 }
00550
00551 if (fullPath.isEmpty()) {
00552
00553
00554
00555 fullPath = KStandardDirs::locate("wallpaper", defaultImage);
00556
00557 if (fullPath.isEmpty()) {
00558 kDebug() << "exhausted every effort to find a wallpaper.";
00559 }
00560 }
00561
00562 return fullPath;
00563 }
00564
00565 bool Theme::currentThemeHasImage(const QString &name) const
00566 {
00567 if (name.contains("../")) {
00568
00569 return false;
00570 }
00571
00572 return !(d->findInTheme(name + ".svgz", d->themeName).isEmpty()) ||
00573 !(d->findInTheme(name + ".svg", d->themeName).isEmpty());
00574 }
00575
00576 KSharedConfigPtr Theme::colorScheme() const
00577 {
00578 return d->colors;
00579 }
00580
00581 QColor Theme::color(ColorRole role) const
00582 {
00583 switch (role) {
00584 case TextColor:
00585 return d->colorScheme.foreground(KColorScheme::NormalText).color();
00586 break;
00587
00588 case HighlightColor:
00589 return d->colorScheme.decoration(KColorScheme::HoverColor).color();
00590 break;
00591
00592 case BackgroundColor:
00593 return d->colorScheme.background().color();
00594 break;
00595
00596 case ButtonTextColor:
00597 return d->buttonColorScheme.foreground(KColorScheme::NormalText).color();
00598 break;
00599
00600 case ButtonBackgroundColor:
00601 return d->buttonColorScheme.background(KColorScheme::ActiveBackground).color();
00602 break;
00603 }
00604
00605 return QColor();
00606 }
00607
00608 void Theme::setFont(const QFont &font, FontRole role)
00609 {
00610 Q_UNUSED(role)
00611 d->generalFont = font;
00612 }
00613
00614 QFont Theme::font(FontRole role) const
00615 {
00616 Q_UNUSED(role)
00617 switch (role) {
00618 case DesktopFont:
00619 {
00620 KConfigGroup cg(KGlobal::config(), "General");
00621 return cg.readEntry("desktopFont", QFont("Sans Serif", 10));
00622 }
00623 break;
00624 case DefaultFont:
00625 default:
00626 return d->generalFont;
00627 break;
00628 }
00629
00630 return d->generalFont;
00631 }
00632
00633 QFontMetrics Theme::fontMetrics() const
00634 {
00635
00636 return QFontMetrics(d->generalFont);
00637 }
00638
00639 bool Theme::windowTranslucencyEnabled() const
00640 {
00641 return d->compositingActive;
00642 }
00643
00644 void Theme::setUseGlobalSettings(bool useGlobal)
00645 {
00646 if (d->useGlobal == useGlobal) {
00647 return;
00648 }
00649
00650 d->useGlobal = useGlobal;
00651 d->cfg = KConfigGroup();
00652 d->themeName.clear();
00653 settingsChanged();
00654 }
00655
00656 bool Theme::useGlobalSettings() const
00657 {
00658 return d->useGlobal;
00659 }
00660
00661 bool Theme::useNativeWidgetStyle() const
00662 {
00663 return d->useNativeWidgetStyle;
00664 }
00665
00666 bool Theme::findInCache(const QString &key, QPixmap &pix)
00667 {
00668 if (d->useCache()) {
00669 const QString id = d->keysToCache.value(key);
00670 if (d->pixmapsToCache.contains(id)) {
00671 pix = d->pixmapsToCache.value(id);
00672 return true;
00673 }
00674
00675 return d->pixmapCache->find(key, pix);
00676 }
00677
00678 return false;
00679 }
00680
00681
00682 bool Theme::findInCache(const QString &key, QPixmap &pix, unsigned int lastModified)
00683 {
00684 if (d->useCache() && lastModified > d->pixmapCache->timestamp()) {
00685 return false;
00686 }
00687
00688 return findInCache(key, pix);
00689 }
00690
00691 void Theme::insertIntoCache(const QString& key, const QPixmap& pix)
00692 {
00693 if (d->useCache()) {
00694 d->pixmapCache->insert(key, pix);
00695 }
00696 }
00697
00698 void Theme::insertIntoCache(const QString& key, const QPixmap& pix, const QString& id)
00699 {
00700 if (d->useCache()) {
00701 d->pixmapsToCache.insert(id, pix);
00702
00703 if (d->idsToCache.contains(id)) {
00704 d->keysToCache.remove(d->idsToCache[id]);
00705 }
00706
00707 d->keysToCache.insert(key, id);
00708 d->idsToCache.insert(id, key);
00709 d->saveTimer->start(600);
00710 }
00711 }
00712
00713 bool Theme::findInRectsCache(const QString &image, const QString &element, QRectF &rect) const
00714 {
00715 if (!d->pixmapCache) {
00716 return false;
00717 }
00718
00719 KConfigGroup imageGroup(d->svgElementsCache, image);
00720 rect = imageGroup.readEntry(element + "Size", QRectF());
00721
00722 if (rect.isValid()) {
00723 return true;
00724 }
00725
00726
00727
00728 if (element.indexOf('_') <= 0) {
00729 return false;
00730 }
00731
00732 bool invalid = false;
00733
00734 QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
00735 if (it == d->invalidElements.end()) {
00736 QSet<QString> elements = imageGroup.readEntry("invalidElements", QStringList()).toSet();
00737 d->invalidElements.insert(image, elements);
00738 invalid = elements.contains(element);
00739 } else {
00740 invalid = it.value().contains(element);
00741 }
00742
00743 return invalid;
00744 }
00745
00746 void Theme::insertIntoRectsCache(const QString& image, const QString &element, const QRectF &rect)
00747 {
00748 if (!d->pixmapCache) {
00749 return;
00750 }
00751
00752 if (rect.isValid()) {
00753 KConfigGroup imageGroup(d->svgElementsCache, image);
00754 imageGroup.writeEntry(element + "Size", rect);
00755 } else {
00756 QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
00757 if (it == d->invalidElements.end()) {
00758 d->invalidElements[image].insert(element);
00759 } else if (!it.value().contains(element)) {
00760 if (it.value().count() > 1000) {
00761 it.value().erase(it.value().begin());
00762 }
00763
00764 it.value().insert(element);
00765 }
00766 }
00767 }
00768
00769 void Theme::invalidateRectsCache(const QString& image)
00770 {
00771 KConfigGroup imageGroup(d->svgElementsCache, image);
00772 imageGroup.deleteGroup();
00773
00774 releaseRectsCache(image);
00775 }
00776
00777 void Theme::releaseRectsCache(const QString &image)
00778 {
00779 QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
00780 if (it != d->invalidElements.end()) {
00781 KConfigGroup imageGroup(d->svgElementsCache, it.key());
00782 imageGroup.writeEntry("invalidElements", it.value().toList());
00783 d->invalidElements.erase(it);
00784 }
00785 }
00786
00787 void Theme::setCacheLimit(int kbytes)
00788 {
00789 if (d->useCache()) {
00790 d->pixmapCache->setCacheLimit(kbytes);
00791 }
00792 }
00793
00794 }
00795
00796 #include <theme.moc>