• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

Plasma

  • sources
  • kde-4.12
  • kdelibs
  • plasma
theme.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2006-2007 Aaron Seigo <aseigo@kde.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Library General Public License as
6  * published by the Free Software Foundation; either version 2, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this program; if not, write to the
16  * Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19 
20 #include "theme.h"
21 
22 #include <QApplication>
23 #include <QFile>
24 #include <QFileInfo>
25 #include <QMutableListIterator>
26 #include <QPair>
27 #include <QStringBuilder>
28 #include <QTimer>
29 #ifdef Q_WS_X11
30 #include <QX11Info>
31 #include "private/effectwatcher_p.h"
32 #endif
33 
34 #include <kcolorscheme.h>
35 #include <kcomponentdata.h>
36 #include <kconfiggroup.h>
37 #include <kdebug.h>
38 #include <kdirwatch.h>
39 #include <kglobal.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>
46 
47 
48 #include "animations/animationscriptengine_p.h"
49 #include "libplasma-theme-global.h"
50 #include "private/packages_p.h"
51 #include "windoweffects.h"
52 
53 namespace Plasma
54 {
55 
56 //NOTE: Default wallpaper can be set from the theme configuration
57 #define DEFAULT_WALLPAPER_THEME "default"
58 #define DEFAULT_WALLPAPER_SUFFIX ".png"
59 static const int DEFAULT_WALLPAPER_WIDTH = 1920;
60 static const int DEFAULT_WALLPAPER_HEIGHT = 1200;
61 
62 enum styles {
63  DEFAULTSTYLE,
64  SVGSTYLE
65 };
66 
67 enum CacheType {
68  NoCache = 0,
69  PixmapCache = 1,
70  SvgElementsCache = 2
71 };
72 Q_DECLARE_FLAGS(CacheTypes, CacheType)
73 Q_DECLARE_OPERATORS_FOR_FLAGS(CacheTypes)
74 
75 class ThemePrivate
76 {
77 public:
78  ThemePrivate(Theme *theme)
79  : q(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)),
83  defaultWallpaperTheme(DEFAULT_WALLPAPER_THEME),
84  defaultWallpaperSuffix(DEFAULT_WALLPAPER_SUFFIX),
85  defaultWallpaperWidth(DEFAULT_WALLPAPER_WIDTH),
86  defaultWallpaperHeight(DEFAULT_WALLPAPER_HEIGHT),
87  pixmapCache(0),
88  cachesToDiscard(NoCache),
89  locolor(false),
90  compositingActive(KWindowSystem::self()->compositingActive()),
91  blurActive(false),
92  isDefault(false),
93  useGlobal(true),
94  hasWallpapers(false),
95  useNativeWidgetStyle(false)
96  {
97  generalFont = QApplication::font();
98  ThemeConfig config;
99  cacheTheme = config.cacheTheme();
100 
101  saveTimer = new QTimer(q);
102  saveTimer->setSingleShot(true);
103  saveTimer->setInterval(600);
104  QObject::connect(saveTimer, SIGNAL(timeout()), q, SLOT(scheduledCacheUpdate()));
105 
106  updateNotificationTimer = new QTimer(q);
107  updateNotificationTimer->setSingleShot(true);
108  updateNotificationTimer->setInterval(500);
109  QObject::connect(updateNotificationTimer, SIGNAL(timeout()), q, SLOT(notifyOfChanged()));
110 
111  if (QPixmap::defaultDepth() > 8) {
112  QObject::connect(KWindowSystem::self(), SIGNAL(compositingChanged(bool)), q, SLOT(compositingChanged(bool)));
113 #ifdef Q_WS_X11
114  //watch for blur effect property changes as well
115  if (!s_blurEffectWatcher) {
116  s_blurEffectWatcher = new EffectWatcher("_KDE_NET_WM_BLUR_BEHIND_REGION");
117  }
118 
119  QObject::connect(s_blurEffectWatcher, SIGNAL(effectChanged(bool)), q, SLOT(blurBehindChanged(bool)));
120 #endif
121  }
122  }
123 
124  ~ThemePrivate()
125  {
126  delete pixmapCache;
127  }
128 
129  KConfigGroup &config()
130  {
131  if (!cfg.isValid()) {
132  QString groupName = "Theme";
133 
134  if (!useGlobal) {
135  QString app = KGlobal::mainComponent().componentName();
136 
137  if (!app.isEmpty()) {
138  kDebug() << "using theme for app" << app;
139  groupName.append("-").append(app);
140  }
141  }
142 
143  cfg = KConfigGroup(KSharedConfig::openConfig(themeRcFile), groupName);
144  }
145 
146  return cfg;
147  }
148 
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);
157  bool useCache();
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);
163 
164  const QString processStyleSheet(const QString &css);
165 
166  static const char *defaultTheme;
167  static const char *systemColorsTheme;
168  static const char *themeRcFile;
169  static PackageStructure::Ptr packageStructure;
170 #ifdef Q_WS_X11
171  static EffectWatcher *s_blurEffectWatcher;
172 #endif
173 
174  Theme *q;
175  QString themeName;
176  QList<QString> fallbackThemes;
177  KSharedConfigPtr colors;
178  KColorScheme colorScheme;
179  KColorScheme buttonColorScheme;
180  KColorScheme viewColorScheme;
181  KConfigGroup cfg;
182  QFont generalFont;
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;
196  QTimer *saveTimer;
197  QTimer *updateNotificationTimer;
198  int toolTipDelay;
199  CacheTypes cachesToDiscard;
200  QString themeVersion;
201  QString themeMetadataPath;
202 
203  bool locolor : 1;
204  bool compositingActive : 1;
205  bool blurActive : 1;
206  bool isDefault : 1;
207  bool useGlobal : 1;
208  bool hasWallpapers : 1;
209  bool cacheTheme : 1;
210  bool useNativeWidgetStyle :1;
211 };
212 
213 PackageStructure::Ptr ThemePrivate::packageStructure(0);
214 const char *ThemePrivate::defaultTheme = "default";
215 
216 const char *ThemePrivate::themeRcFile = "plasmarc";
217 // the system colors theme is used to cache unthemed svgs with colorization needs
218 // these svgs do not follow the theme's colors, but rather the system colors
219 const char *ThemePrivate::systemColorsTheme = "internal-system-colors";
220 #ifdef Q_WS_X11
221 EffectWatcher *ThemePrivate::s_blurEffectWatcher = 0;
222 #endif
223 
224 bool ThemePrivate::useCache()
225 {
226  bool cachesTooOld = false;
227 
228  if (cacheTheme && !pixmapCache) {
229  const bool isRegularTheme = themeName != systemColorsTheme;
230  QString cacheFile = "plasma_theme_" + themeName;
231 
232  // clear any cached values from the previous theme cache
233  themeVersion.clear();
234 
235  if (!themeMetadataPath.isEmpty()) {
236  KDirWatch::self()->removeFile(themeMetadataPath);
237  }
238  themeMetadataPath = KStandardDirs::locate("data", "desktoptheme/" + themeName + "/metadata.desktop");
239 
240  if (isRegularTheme) {
241  const QString cacheFileBase = cacheFile + "*.kcache";
242 
243  // if the path is empty, then we haven't found the theme and so
244  // we will leave currentCacheFileName empty, resulting in the deletion of
245  // *all* matching cache files
246  QString currentCacheFileName;
247  if (!themeMetadataPath.isEmpty()) {
248  // now we record the theme version, if we can
249  const KPluginInfo pluginInfo(themeMetadataPath);
250  themeVersion = pluginInfo.version();
251  if (!themeVersion.isEmpty()) {
252  cacheFile += "_v" + themeVersion;
253  currentCacheFileName = cacheFile + ".kcache";
254  }
255 
256  // watch the metadata file for changes at runtime
257  KDirWatch::self()->addFile(themeMetadataPath);
258  QObject::connect(KDirWatch::self(), SIGNAL(created(QString)),
259  q, SLOT(settingsFileChanged(QString)),
260  Qt::UniqueConnection);
261  QObject::connect(KDirWatch::self(), SIGNAL(dirty(QString)),
262  q, SLOT(settingsFileChanged(QString)),
263  Qt::UniqueConnection);
264  }
265 
266  // now we check for (and remove) old caches
267  foreach (const QString &file, KGlobal::dirs()->findAllResources("cache", cacheFileBase)) {
268  if (currentCacheFileName.isEmpty() ||
269  !file.endsWith(currentCacheFileName)) {
270  QFile::remove(file);
271  }
272  }
273  }
274 
275  // now we do a sanity check: if the metadata.desktop file is newer than the cache, drop
276  // the cache
277  if (isRegularTheme && !themeMetadataPath.isEmpty()) {
278  // now we check to see if the theme metadata file itself is newer than the pixmap cache
279  // this is done before creating the pixmapCache object since that can change the mtime
280  // on the cache file
281 
282  // FIXME: when using the system colors, if they change while the application is not running
283  // the cache should be dropped; we need a way to detect system color change when the
284  // application is not running.
285  // check for expired cache
286  const QString cacheFilePath = KStandardDirs::locateLocal("cache", cacheFile);
287  if (!cacheFilePath.isEmpty()) {
288  const QFileInfo cacheFileInfo(cacheFilePath);
289  const QFileInfo metadataFileInfo(themeMetadataPath);
290  cachesTooOld = cacheFileInfo.lastModified().toTime_t() > metadataFileInfo.lastModified().toTime_t();
291  }
292  }
293 
294  ThemeConfig config;
295  pixmapCache = new KImageCache(cacheFile, config.themeCacheKb() * 1024);
296 
297  if (cachesTooOld) {
298  discardCache(PixmapCache | SvgElementsCache);
299  }
300  }
301 
302  if (cacheTheme && !svgElementsCache) {
303  const QString svgElementsFileNameBase = "plasma-svgelements-" + themeName;
304  QString svgElementsFileName = svgElementsFileNameBase;
305  if (!themeVersion.isEmpty()) {
306  svgElementsFileName += "_v" + themeVersion;
307  }
308 
309  // now we check for (and remove) old caches
310  foreach (const QString &file, KGlobal::dirs()->findAllResources("cache", svgElementsFileNameBase + "*")) {
311  if (cachesTooOld || !file.endsWith(svgElementsFileName)) {
312  QFile::remove(file);
313  }
314  }
315 
316  const QString svgElementsFile = KStandardDirs::locateLocal("cache", svgElementsFileName);
317  svgElementsCache = KSharedConfig::openConfig(svgElementsFile);
318  }
319 
320  return cacheTheme;
321 }
322 
323 void ThemePrivate::onAppExitCleanup()
324 {
325  pixmapsToCache.clear();
326  delete pixmapCache;
327  pixmapCache = 0;
328  cacheTheme = false;
329 }
330 
331 QString ThemePrivate::findInTheme(const QString &image, const QString &theme, bool cache)
332 {
333  if (cache && discoveries.contains(image)) {
334  return discoveries[image];
335  }
336 
337  QString search;
338 
339  if (locolor) {
340  search = QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/locolor/") % image;
341  search = KStandardDirs::locate("data", search);
342  } else if (!compositingActive) {
343  search = QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/opaque/") % image;
344  search = KStandardDirs::locate("data", search);
345  } else if (WindowEffects::isEffectAvailable(WindowEffects::BlurBehind)) {
346  search = QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/translucent/") % image;
347  search = KStandardDirs::locate("data", search);
348  }
349 
350  //not found or compositing enabled
351  if (search.isEmpty()) {
352  search = QLatin1Literal("desktoptheme/") % theme % QLatin1Char('/') % image;
353  search = KStandardDirs::locate("data", search);
354  }
355 
356  if (cache && !search.isEmpty()) {
357  discoveries.insert(image, search);
358  }
359 
360  return search;
361 }
362 
363 void ThemePrivate::compositingChanged(bool active)
364 {
365 #ifdef Q_WS_X11
366  if (compositingActive != active) {
367  compositingActive = active;
368  //kDebug() << QTime::currentTime();
369  scheduleThemeChangeNotification(PixmapCache | SvgElementsCache);
370  }
371 #endif
372 }
373 
374 void ThemePrivate::discardCache(CacheTypes caches)
375 {
376  if (caches & PixmapCache) {
377  pixmapsToCache.clear();
378  saveTimer->stop();
379  if (pixmapCache) {
380  pixmapCache->clear();
381  }
382  } else {
383  // This deletes the object but keeps the on-disk cache for later use
384  delete pixmapCache;
385  pixmapCache = 0;
386  }
387 
388  cachedStyleSheets.clear();
389 
390  if (caches & SvgElementsCache) {
391  discoveries.clear();
392  invalidElements.clear();
393  svgElementsCache = 0;
394  }
395 }
396 
397 void ThemePrivate::scheduledCacheUpdate()
398 {
399  if (useCache()) {
400  QHashIterator<QString, QPixmap> it(pixmapsToCache);
401  while (it.hasNext()) {
402  it.next();
403  pixmapCache->insertPixmap(idsToCache[it.key()], it.value());
404  }
405  }
406 
407  pixmapsToCache.clear();
408  keysToCache.clear();
409  idsToCache.clear();
410 }
411 
412 void ThemePrivate::colorsChanged()
413 {
414  colorScheme = KColorScheme(QPalette::Active, KColorScheme::Window, colors);
415  buttonColorScheme = KColorScheme(QPalette::Active, KColorScheme::Button, colors);
416  viewColorScheme = KColorScheme(QPalette::Active, KColorScheme::View, colors);
417  scheduleThemeChangeNotification(PixmapCache);
418 }
419 
420 void ThemePrivate::blurBehindChanged(bool blur)
421 {
422  if (blurActive != blur) {
423  blurActive = blur;
424  scheduleThemeChangeNotification(PixmapCache | SvgElementsCache);
425  }
426 }
427 
428 void ThemePrivate::scheduleThemeChangeNotification(CacheTypes caches)
429 {
430  cachesToDiscard |= caches;
431  updateNotificationTimer->start();
432 }
433 
434 void ThemePrivate::notifyOfChanged()
435 {
436  //kDebug() << cachesToDiscard;
437  discardCache(cachesToDiscard);
438  cachesToDiscard = NoCache;
439  emit q->themeChanged();
440 }
441 
442 const QString ThemePrivate::processStyleSheet(const QString &css)
443 {
444  QString stylesheet;
445  if (css.isEmpty()) {
446  stylesheet = cachedStyleSheets.value(DEFAULTSTYLE);
447  if (stylesheet.isEmpty()) {
448  stylesheet = QString("\n\
449  body {\n\
450  color: %textcolor;\n\
451  font-size: %fontsize;\n\
452  font-family: %fontfamily;\n\
453  }\n\
454  a:active { color: %activatedlink; }\n\
455  a:link { color: %link; }\n\
456  a:visited { color: %visitedlink; }\n\
457  a:hover { color: %hoveredlink; text-decoration: none; }\n\
458  ");
459  stylesheet = processStyleSheet(stylesheet);
460  cachedStyleSheets.insert(DEFAULTSTYLE, stylesheet);
461  }
462 
463  return stylesheet;
464  } else if (css == "SVG") {
465  stylesheet = cachedStyleSheets.value(SVGSTYLE);
466  if (stylesheet.isEmpty()) {
467  QString skel = ".ColorScheme-%1{color:%2;}";
468 
469  stylesheet += skel.arg("Text","%textcolor");
470  stylesheet += skel.arg("Background","%backgroundcolor");
471 
472  stylesheet += skel.arg("ButtonText","%buttontextcolor");
473  stylesheet += skel.arg("ButtonBackground","%buttonbackgroundcolor");
474  stylesheet += skel.arg("ButtonHover","%buttonhovercolor");
475  stylesheet += skel.arg("ButtonFocus","%buttonfocuscolor");
476 
477  stylesheet += skel.arg("ViewText","%viewtextcolor");
478  stylesheet += skel.arg("ViewBackground","%viewbackgroundcolor");
479  stylesheet += skel.arg("ViewHover","%viewhovercolor");
480  stylesheet += skel.arg("ViewFocus","%viewfocuscolor");
481 
482  stylesheet = processStyleSheet(stylesheet);
483  cachedStyleSheets.insert(SVGSTYLE, stylesheet);
484  }
485 
486  return stylesheet;
487  } else {
488  stylesheet = css;
489  }
490 
491  QHash<QString, QString> elements;
492  // If you add elements here, make sure their names are sufficiently unique to not cause
493  // clashes between element keys
494  elements["%textcolor"] = q->color(Theme::TextColor).name();
495  elements["%backgroundcolor"] = q->color(Theme::BackgroundColor).name();
496  elements["%visitedlink"] = q->color(Theme::VisitedLinkColor).name();
497  elements["%activatedlink"] = q->color(Theme::HighlightColor).name();
498  elements["%hoveredlink"] = q->color(Theme::HighlightColor).name();
499  elements["%link"] = q->color(Theme::LinkColor).name();
500  elements["%buttontextcolor"] = q->color(Theme::ButtonTextColor).name();
501  elements["%buttonbackgroundcolor"] = q->color(Theme::ButtonBackgroundColor).name();
502  elements["%buttonhovercolor"] = q->color(Theme::ButtonHoverColor).name();
503  elements["%buttonfocuscolor"] = q->color(Theme::ButtonFocusColor).name();
504  elements["%viewtextcolor"] = q->color(Theme::ViewTextColor).name();
505  elements["%viewbackgroundcolor"] = q->color(Theme::ViewBackgroundColor).name();
506  elements["%viewhovercolor"] = q->color(Theme::ViewHoverColor).name();
507  elements["%viewfocuscolor"] = q->color(Theme::ViewFocusColor).name();
508 
509  QFont font = q->font(Theme::DefaultFont);
510  elements["%fontsize"] = QString("%1pt").arg(font.pointSize());
511  elements["%fontfamily"] = font.family().split('[').first();
512  elements["%smallfontsize"] = QString("%1pt").arg(KGlobalSettings::smallestReadableFont().pointSize());
513 
514  QHash<QString, QString>::const_iterator it = elements.constBegin();
515  QHash<QString, QString>::const_iterator itEnd = elements.constEnd();
516  for ( ; it != itEnd; ++it) {
517  stylesheet.replace(it.key(), it.value());
518  }
519  return stylesheet;
520 }
521 
522 class ThemeSingleton
523 {
524 public:
525  ThemeSingleton()
526  {
527  self.d->isDefault = true;
528 
529  //FIXME: if/when kconfig gets change notification, this will be unnecessary
530  KDirWatch::self()->addFile(KStandardDirs::locateLocal("config", ThemePrivate::themeRcFile));
531  QObject::connect(KDirWatch::self(), SIGNAL(created(QString)),
532  &self, SLOT(settingsFileChanged(QString)),
533  Qt::UniqueConnection);
534  QObject::connect(KDirWatch::self(), SIGNAL(dirty(QString)),
535  &self, SLOT(settingsFileChanged(QString)),
536  Qt::UniqueConnection);
537  }
538 
539  Theme self;
540 };
541 
542 K_GLOBAL_STATIC(ThemeSingleton, privateThemeSelf)
543 
544 Theme *Theme::defaultTheme()
545 {
546  return &privateThemeSelf->self;
547 }
548 
549 Theme::Theme(QObject *parent)
550  : QObject(parent),
551  d(new ThemePrivate(this))
552 {
553  settingsChanged();
554  if (QCoreApplication::instance()) {
555  connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()),
556  this, SLOT(onAppExitCleanup()));
557  }
558 }
559 
560 Theme::Theme(const QString &themeName, QObject *parent)
561  : QObject(parent),
562  d(new ThemePrivate(this))
563 {
564  // turn off caching so we don't accidently trigger unnecessary disk activity at this point
565  bool useCache = d->cacheTheme;
566  d->cacheTheme = false;
567  setThemeName(themeName);
568  d->cacheTheme = useCache;
569  if (QCoreApplication::instance()) {
570  connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()),
571  this, SLOT(onAppExitCleanup()));
572  }
573 }
574 
575 Theme::~Theme()
576 {
577  if (d->svgElementsCache) {
578  QHashIterator<QString, QSet<QString> > it(d->invalidElements);
579  while (it.hasNext()) {
580  it.next();
581  KConfigGroup imageGroup(d->svgElementsCache, it.key());
582  imageGroup.writeEntry("invalidElements", it.value().toList()); //FIXME: add QSet support to KConfig
583  }
584  }
585 
586  d->onAppExitCleanup();
587  delete d;
588 }
589 
590 PackageStructure::Ptr Theme::packageStructure()
591 {
592  if (!ThemePrivate::packageStructure) {
593  ThemePrivate::packageStructure = new ThemePackage();
594  }
595 
596  return ThemePrivate::packageStructure;
597 }
598 
599 KPluginInfo::List Theme::listThemeInfo()
600 {
601  const QStringList themes = KGlobal::dirs()->findAllResources("data", "desktoptheme/*/metadata.desktop",
602  KStandardDirs::NoDuplicates);
603  return KPluginInfo::fromFiles(themes);
604 }
605 
606 void ThemePrivate::settingsFileChanged(const QString &file)
607 {
608  if (file == themeMetadataPath) {
609  const KPluginInfo pluginInfo(themeMetadataPath);
610  if (themeVersion != pluginInfo.version()) {
611  scheduleThemeChangeNotification(SvgElementsCache);
612  }
613  } else if (file.endsWith(themeRcFile)) {
614  config().config()->reparseConfiguration();
615  q->settingsChanged();
616  }
617 }
618 
619 void Theme::settingsChanged()
620 {
621  KConfigGroup cg = d->config();
622  d->setThemeName(cg.readEntry("name", ThemePrivate::defaultTheme), false);
623  cg = KConfigGroup(cg.config(), "PlasmaToolTips");
624  d->toolTipDelay = cg.readEntry("Delay", 700);
625 }
626 
627 void Theme::setThemeName(const QString &themeName)
628 {
629  d->setThemeName(themeName, true);
630 }
631 
632 void ThemePrivate::processWallpaperSettings(KConfigBase *metadata)
633 {
634  if (!defaultWallpaperTheme.isEmpty() && defaultWallpaperTheme != DEFAULT_WALLPAPER_THEME) {
635  return;
636  }
637 
638  KConfigGroup cg;
639  if (metadata->hasGroup("Wallpaper")) {
640  // we have a theme color config, so let's also check to see if
641  // there is a wallpaper defined in there.
642  cg = KConfigGroup(metadata, "Wallpaper");
643  } else {
644  // since we didn't find an entry in the theme, let's look in the main
645  // theme config
646  cg = config();
647  }
648 
649  defaultWallpaperTheme = cg.readEntry("defaultWallpaperTheme", DEFAULT_WALLPAPER_THEME);
650  defaultWallpaperSuffix = cg.readEntry("defaultFileSuffix", DEFAULT_WALLPAPER_SUFFIX);
651  defaultWallpaperWidth = cg.readEntry("defaultWidth", DEFAULT_WALLPAPER_WIDTH);
652  defaultWallpaperHeight = cg.readEntry("defaultHeight", DEFAULT_WALLPAPER_HEIGHT);
653 }
654 
655 void ThemePrivate::processAnimationSettings(const QString &theme, KConfigBase *metadata)
656 {
657  KConfigGroup cg(metadata, "Animations");
658  const QString animDir = QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/animations/");
659  foreach (const QString &path, cg.keyList()) {
660  const QStringList anims = cg.readEntry(path, QStringList());
661  foreach (const QString &anim, anims) {
662  if (!animationMapping.contains(anim)) {
663  kDebug() << "Registering animation. animDir: " << animDir
664  << "\tanim: " << anim
665  << "\tpath: " << path << "\t*******\n\n\n";
666  //key: desktoptheme/default/animations/+ all.js
667  //value: ZoomAnimation
668  animationMapping.insert(anim, animDir % path);
669  } else {
670  kDebug() << "************Animation already registered!\n\n\n";
671  }
672  }
673  }
674 
675 }
676 
677 void ThemePrivate::setThemeName(const QString &tempThemeName, bool writeSettings)
678 {
679  //kDebug() << tempThemeName;
680  QString theme = tempThemeName;
681  if (theme.isEmpty() || theme == themeName) {
682  // let's try and get the default theme at least
683  if (themeName.isEmpty()) {
684  theme = ThemePrivate::defaultTheme;
685  } else {
686  return;
687  }
688  }
689 
690  // we have one special theme: essentially a dummy theme used to cache things with
691  // the system colors.
692  bool realTheme = theme != systemColorsTheme;
693  if (realTheme) {
694  QString themePath = KStandardDirs::locate("data", QLatin1Literal("desktoptheme/") % theme % QLatin1Char('/'));
695  if (themePath.isEmpty() && themeName.isEmpty()) {
696  themePath = KStandardDirs::locate("data", "desktoptheme/default/");
697 
698  if (themePath.isEmpty()) {
699  return;
700  }
701 
702  theme = ThemePrivate::defaultTheme;
703  }
704  }
705 
706  // check again as ThemePrivate::defaultTheme might be empty
707  if (themeName == theme) {
708  return;
709  }
710 
711  themeName = theme;
712 
713  // load the color scheme config
714  const QString colorsFile = realTheme ? KStandardDirs::locate("data", QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/colors"))
715  : QString();
716 
717  //kDebug() << "we're going for..." << colorsFile << "*******************";
718 
719  // load the wallpaper settings, if any
720  if (realTheme) {
721  const QString metadataPath(KStandardDirs::locate("data", QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/metadata.desktop")));
722  KConfig metadata(metadataPath);
723 
724  processWallpaperSettings(&metadata);
725 
726  AnimationScriptEngine::clearAnimations();
727  animationMapping.clear();
728  processAnimationSettings(themeName, &metadata);
729 
730  KConfigGroup cg(&metadata, "Settings");
731  useNativeWidgetStyle = cg.readEntry("UseNativeWidgetStyle", false);
732  QString fallback = cg.readEntry("FallbackTheme", QString());
733 
734  fallbackThemes.clear();
735  while (!fallback.isEmpty() && !fallbackThemes.contains(fallback)) {
736  fallbackThemes.append(fallback);
737 
738  QString metadataPath(KStandardDirs::locate("data", QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/metadata.desktop")));
739  KConfig metadata(metadataPath);
740  KConfigGroup cg(&metadata, "Settings");
741  fallback = cg.readEntry("FallbackTheme", QString());
742  }
743 
744  if (!fallbackThemes.contains("oxygen")) {
745  fallbackThemes.append("oxygen");
746  }
747 
748  if (!fallbackThemes.contains(ThemePrivate::defaultTheme)) {
749  fallbackThemes.append(ThemePrivate::defaultTheme);
750  }
751 
752  foreach (const QString &theme, fallbackThemes) {
753  QString metadataPath(KStandardDirs::locate("data", QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/metadata.desktop")));
754  KConfig metadata(metadataPath);
755  processAnimationSettings(theme, &metadata);
756  processWallpaperSettings(&metadata);
757  }
758  }
759 
760  if (colorsFile.isEmpty()) {
761  colors = 0;
762  QObject::connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
763  q, SLOT(colorsChanged()), Qt::UniqueConnection);
764  } else {
765  QObject::disconnect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
766  q, SLOT(colorsChanged()));
767  colors = KSharedConfig::openConfig(colorsFile);
768  }
769 
770  colorScheme = KColorScheme(QPalette::Active, KColorScheme::Window, colors);
771  buttonColorScheme = KColorScheme(QPalette::Active, KColorScheme::Button, colors);
772  viewColorScheme = KColorScheme(QPalette::Active, KColorScheme::View, colors);
773  hasWallpapers = KStandardDirs::exists(KStandardDirs::locateLocal("data", QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/wallpapers/")));
774 
775  if (realTheme && isDefault && writeSettings) {
776  // we're the default theme, let's save our state
777  KConfigGroup &cg = config();
778  if (ThemePrivate::defaultTheme == themeName) {
779  cg.deleteEntry("name");
780  } else {
781  cg.writeEntry("name", themeName);
782  }
783  cg.sync();
784  }
785 
786  scheduleThemeChangeNotification(SvgElementsCache);
787 }
788 
789 QString Theme::themeName() const
790 {
791  return d->themeName;
792 }
793 
794 QString Theme::imagePath(const QString &name) const
795 {
796  // look for a compressed svg file in the theme
797  if (name.contains("../") || name.isEmpty()) {
798  // we don't support relative paths
799  //kDebug() << "Theme says: bad image path " << name;
800  return QString();
801  }
802 
803  const QString svgzName = name % QLatin1Literal(".svgz");
804  QString path = d->findInTheme(svgzName, d->themeName);
805 
806  if (path.isEmpty()) {
807  // try for an uncompressed svg file
808  const QString svgName = name % QLatin1Literal(".svg");
809  path = d->findInTheme(svgName, d->themeName);
810 
811  // search in fallback themes if necessary
812  for (int i = 0; path.isEmpty() && i < d->fallbackThemes.count(); ++i) {
813  if (d->themeName == d->fallbackThemes[i]) {
814  continue;
815  }
816 
817  // try a compressed svg file in the fallback theme
818  path = d->findInTheme(svgzName, d->fallbackThemes[i]);
819 
820  if (path.isEmpty()) {
821  // try an uncompressed svg file in the fallback theme
822  path = d->findInTheme(svgName, d->fallbackThemes[i]);
823  }
824  }
825  }
826 
827  /*
828  if (path.isEmpty()) {
829  kDebug() << "Theme says: bad image path " << name;
830  }
831  */
832 
833  return path;
834 }
835 
836 QString Theme::styleSheet(const QString &css) const
837 {
838  return d->processStyleSheet(css);
839 }
840 
841 QString Theme::animationPath(const QString &name) const
842 {
843  const QString path = d->animationMapping.value(name);
844  if (path.isEmpty()) {
845  //kError() << "****** FAILED TO FIND IN MAPPING!";
846  return path;
847  }
848 
849  return KStandardDirs::locate("data", path);
850 }
851 
852 QString Theme::wallpaperPath(const QSize &size) const
853 {
854  QString fullPath;
855  QString image = d->defaultWallpaperTheme;
856 
857  image.append("/contents/images/%1x%2").append(d->defaultWallpaperSuffix);
858  QString defaultImage = image.arg(d->defaultWallpaperWidth).arg(d->defaultWallpaperHeight);
859 
860  if (size.isValid()) {
861  // try to customize the paper to the size requested
862  //TODO: this should do better than just fallback to the default size.
863  // a "best fit" matching would be far better, so we don't end
864  // up returning a 1920x1200 wallpaper for a 640x480 request ;)
865  image = image.arg(size.width()).arg(size.height());
866  } else {
867  image = defaultImage;
868  }
869 
870  //TODO: the theme's wallpaper overrides regularly installed wallpapers.
871  // should it be possible for user installed (e.g. locateLocal) wallpapers
872  // to override the theme?
873  if (d->hasWallpapers) {
874  // check in the theme first
875  fullPath = d->findInTheme(QLatin1Literal("wallpapers/") % image, d->themeName);
876 
877  if (fullPath.isEmpty()) {
878  fullPath = d->findInTheme(QLatin1Literal("wallpapers/") % defaultImage, d->themeName);
879  }
880  }
881 
882  if (fullPath.isEmpty()) {
883  // we failed to find it in the theme, so look in the standard directories
884  //kDebug() << "looking for" << image;
885  fullPath = KStandardDirs::locate("wallpaper", image);
886  }
887 
888  if (fullPath.isEmpty()) {
889  // we still failed to find it in the theme, so look for the default in
890  // the standard directories
891  //kDebug() << "looking for" << defaultImage;
892  fullPath = KStandardDirs::locate("wallpaper", defaultImage);
893 
894  if (fullPath.isEmpty()) {
895  kDebug() << "exhausted every effort to find a wallpaper.";
896  }
897  }
898 
899  return fullPath;
900 }
901 
902 bool Theme::currentThemeHasImage(const QString &name) const
903 {
904  if (name.contains("../")) {
905  // we don't support relative paths
906  return false;
907  }
908 
909  return !(d->findInTheme(name % QLatin1Literal(".svgz"), d->themeName, false).isEmpty()) ||
910  !(d->findInTheme(name % QLatin1Literal(".svg"), d->themeName, false).isEmpty());
911 }
912 
913 KSharedConfigPtr Theme::colorScheme() const
914 {
915  return d->colors;
916 }
917 
918 QColor Theme::color(ColorRole role) const
919 {
920  switch (role) {
921  case TextColor:
922  return d->colorScheme.foreground(KColorScheme::NormalText).color();
923 
924  case HighlightColor:
925  return d->colorScheme.decoration(KColorScheme::HoverColor).color();
926 
927  case BackgroundColor:
928  return d->colorScheme.background(KColorScheme::NormalBackground).color();
929 
930  case ButtonTextColor:
931  return d->buttonColorScheme.foreground(KColorScheme::NormalText).color();
932 
933  case ButtonBackgroundColor:
934  return d->buttonColorScheme.background(KColorScheme::NormalBackground).color();
935 
936  case ButtonHoverColor:
937  return d->buttonColorScheme.decoration(KColorScheme::HoverColor).color();
938 
939  case ButtonFocusColor:
940  return d->buttonColorScheme.decoration(KColorScheme::FocusColor).color();
941 
942  case ViewTextColor:
943  return d->viewColorScheme.foreground(KColorScheme::NormalText).color();
944 
945  case ViewBackgroundColor:
946  return d->viewColorScheme.background(KColorScheme::NormalBackground).color();
947 
948  case ViewHoverColor:
949  return d->viewColorScheme.decoration(KColorScheme::HoverColor).color();
950 
951  case ViewFocusColor:
952  return d->viewColorScheme.decoration(KColorScheme::FocusColor).color();
953 
954  case LinkColor:
955  return d->viewColorScheme.foreground(KColorScheme::LinkText).color();
956 
957  case VisitedLinkColor:
958  return d->viewColorScheme.foreground(KColorScheme::VisitedText).color();
959  }
960 
961  return QColor();
962 }
963 
964 void Theme::setFont(const QFont &font, FontRole role)
965 {
966  Q_UNUSED(role)
967  d->generalFont = font;
968 }
969 
970 QFont Theme::font(FontRole role) const
971 {
972  switch (role) {
973  case DesktopFont: {
974  KConfigGroup cg(KGlobal::config(), "General");
975  return cg.readEntry("desktopFont", d->generalFont);
976  }
977  break;
978 
979  case DefaultFont:
980  default:
981  return d->generalFont;
982  break;
983 
984  case SmallestFont:
985  return KGlobalSettings::smallestReadableFont();
986  break;
987  }
988 
989  return d->generalFont;
990 }
991 
992 QFontMetrics Theme::fontMetrics() const
993 {
994  //TODO: allow this to be overridden with a plasma specific font?
995  return QFontMetrics(d->generalFont);
996 }
997 
998 bool Theme::windowTranslucencyEnabled() const
999 {
1000  return d->compositingActive;
1001 }
1002 
1003 void Theme::setUseGlobalSettings(bool useGlobal)
1004 {
1005  if (d->useGlobal == useGlobal) {
1006  return;
1007  }
1008 
1009  d->useGlobal = useGlobal;
1010  d->cfg = KConfigGroup();
1011  d->themeName.clear();
1012  settingsChanged();
1013 }
1014 
1015 bool Theme::useGlobalSettings() const
1016 {
1017  return d->useGlobal;
1018 }
1019 
1020 bool Theme::useNativeWidgetStyle() const
1021 {
1022  return d->useNativeWidgetStyle;
1023 }
1024 
1025 bool Theme::findInCache(const QString &key, QPixmap &pix)
1026 {
1027  if (d->useCache()) {
1028  const QString id = d->keysToCache.value(key);
1029  if (d->pixmapsToCache.contains(id)) {
1030  pix = d->pixmapsToCache.value(id);
1031  return !pix.isNull();
1032  }
1033 
1034  QPixmap temp;
1035  if (d->pixmapCache->findPixmap(key, &temp) && !temp.isNull()) {
1036  pix = temp;
1037  return true;
1038  }
1039  }
1040 
1041  return false;
1042 }
1043 
1044 // BIC FIXME: Should be merged with the other findInCache method above when we break BC
1045 bool Theme::findInCache(const QString &key, QPixmap &pix, unsigned int lastModified)
1046 {
1047  if (d->useCache() && lastModified > uint(d->pixmapCache->lastModifiedTime())) {
1048  return false;
1049  }
1050 
1051  return findInCache(key, pix);
1052 }
1053 
1054 void Theme::insertIntoCache(const QString& key, const QPixmap& pix)
1055 {
1056  if (d->useCache()) {
1057  d->pixmapCache->insertPixmap(key, pix);
1058  }
1059 }
1060 
1061 void Theme::insertIntoCache(const QString& key, const QPixmap& pix, const QString& id)
1062 {
1063  if (d->useCache()) {
1064  d->pixmapsToCache.insert(id, pix);
1065 
1066  if (d->idsToCache.contains(id)) {
1067  d->keysToCache.remove(d->idsToCache[id]);
1068  }
1069 
1070  d->keysToCache.insert(key, id);
1071  d->idsToCache.insert(id, key);
1072  d->saveTimer->start();
1073  }
1074 }
1075 
1076 bool Theme::findInRectsCache(const QString &image, const QString &element, QRectF &rect) const
1077 {
1078  if (!d->useCache()) {
1079  return false;
1080  }
1081 
1082  KConfigGroup imageGroup(d->svgElementsCache, image);
1083  rect = imageGroup.readEntry(element % QLatin1Literal("Size"), QRectF());
1084 
1085  if (rect.isValid()) {
1086  return true;
1087  }
1088 
1089  //Name starting by _ means the element is empty and we're asked for the size of
1090  //the whole image, so the whole image is never invalid
1091  if (element.indexOf('_') <= 0) {
1092  return false;
1093  }
1094 
1095  bool invalid = false;
1096 
1097  QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
1098  if (it == d->invalidElements.end()) {
1099  QSet<QString> elements = imageGroup.readEntry("invalidElements", QStringList()).toSet();
1100  d->invalidElements.insert(image, elements);
1101  invalid = elements.contains(element);
1102  } else {
1103  invalid = it.value().contains(element);
1104  }
1105 
1106  return invalid;
1107 }
1108 
1109 QStringList Theme::listCachedRectKeys(const QString &image) const
1110 {
1111  if (!d->useCache()) {
1112  return QStringList();
1113  }
1114 
1115  KConfigGroup imageGroup(d->svgElementsCache, image);
1116  QStringList keys = imageGroup.keyList();
1117 
1118  QMutableListIterator<QString> i(keys);
1119  while (i.hasNext()) {
1120  QString key = i.next();
1121  if (key.endsWith("Size")) {
1122  // The actual cache id used from outside doesn't end on "Size".
1123  key.resize(key.size() - 4);
1124  i.setValue(key);
1125  } else {
1126  i.remove();
1127  }
1128  }
1129  return keys;
1130 }
1131 
1132 void Theme::insertIntoRectsCache(const QString& image, const QString &element, const QRectF &rect)
1133 {
1134  if (!d->useCache()) {
1135  return;
1136  }
1137 
1138  if (rect.isValid()) {
1139  KConfigGroup imageGroup(d->svgElementsCache, image);
1140  imageGroup.writeEntry(element % QLatin1Literal("Size"), rect);
1141  } else {
1142  QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
1143  if (it == d->invalidElements.end()) {
1144  d->invalidElements[image].insert(element);
1145  } else if (!it.value().contains(element)) {
1146  if (it.value().count() > 1000) {
1147  it.value().erase(it.value().begin());
1148  }
1149 
1150  it.value().insert(element);
1151  }
1152  }
1153 }
1154 
1155 void Theme::invalidateRectsCache(const QString& image)
1156 {
1157  if (d->useCache()) {
1158  KConfigGroup imageGroup(d->svgElementsCache, image);
1159  imageGroup.deleteGroup();
1160  }
1161 
1162  d->invalidElements.remove(image);
1163 }
1164 
1165 void Theme::releaseRectsCache(const QString &image)
1166 {
1167  QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
1168  if (it != d->invalidElements.end()) {
1169  if (d->useCache()) {
1170  KConfigGroup imageGroup(d->svgElementsCache, it.key());
1171  imageGroup.writeEntry("invalidElements", it.value().toList());
1172  }
1173 
1174  d->invalidElements.erase(it);
1175  }
1176 }
1177 
1178 void Theme::setCacheLimit(int kbytes)
1179 {
1180  Q_UNUSED(kbytes)
1181  if (d->useCache()) {
1182  ;
1183  // Too late for you bub.
1184  // d->pixmapCache->setCacheLimit(kbytes);
1185  }
1186 }
1187 
1188 KUrl Theme::homepage() const
1189 {
1190  const QString metadataPath(KStandardDirs::locate("data", QLatin1Literal("desktoptheme/") % d->themeName % QLatin1Literal("/metadata.desktop")));
1191  KConfig metadata(metadataPath);
1192  KConfigGroup brandConfig(&metadata, "Branding");
1193  return brandConfig.readEntry("homepage", KUrl("http://www.kde.org"));
1194 }
1195 
1196 int Theme::toolTipDelay() const
1197 {
1198  return d->toolTipDelay;
1199 }
1200 
1201 }
1202 
1203 #include <theme.moc>
Plasma::Theme::imagePath
Q_INVOKABLE QString imagePath(const QString &name) const
Retrieve the path for an SVG image in the current theme.
Definition: theme.cpp:794
Plasma::Theme::insertIntoRectsCache
void insertIntoRectsCache(const QString &image, const QString &element, const QRectF &rect)
Inserts a rectangle of a sub element of an image into a disk cache.
Definition: theme.cpp:1132
Plasma::PixmapCache
Definition: theme.cpp:69
Plasma::Theme::FontRole
FontRole
Definition: theme.h:79
windoweffects.h
Plasma::Theme::HighlightColor
the text higlight color to be used by items resting on the background
Definition: theme.h:64
Plasma::Theme::findInCache
bool findInCache(const QString &key, QPixmap &pix)
Tries to load pixmap with the specified key from cache.
Definition: theme.cpp:1025
Plasma::Theme::setThemeName
void setThemeName(const QString &themeName)
Sets the current theme being used.
Definition: theme.cpp:627
Plasma::Theme::useNativeWidgetStyle
bool useNativeWidgetStyle() const
Definition: theme.cpp:1020
Plasma::Theme::DefaultFont
The standard text font.
Definition: theme.h:80
Plasma::Theme::settingsChanged
void settingsChanged()
Notifies the Theme object that the theme settings have changed and should be read from the config fil...
Definition: theme.cpp:619
Plasma::Theme::animationPath
Q_INVOKABLE QString animationPath(const QString &name) const
Retrieves the path for the script file that contains a given Javascript animation.
Definition: theme.cpp:841
Plasma::Theme::colorScheme
Q_INVOKABLE KSharedConfigPtr colorScheme() const
Returns the color scheme configurationthat goes along this theme.
Definition: theme.cpp:913
Plasma::Theme::font
Q_INVOKABLE QFont font(FontRole role) const
Returns the font to be used by themed items.
Definition: theme.cpp:970
Plasma::Theme::TextColor
the text color to be used by items resting on the background
Definition: theme.h:63
libplasma-theme-global.h
theme.h
Plasma::Theme::ViewTextColor
color for focus effect on buttons
Definition: theme.h:73
Plasma::Theme::setCacheLimit
void setCacheLimit(int kbytes)
Sets the maximum size of the cache (in kilobytes).
Definition: theme.cpp:1178
QObject
Plasma::Theme::packageStructure
static PackageStructure::Ptr packageStructure()
Definition: theme.cpp:590
Plasma::SvgElementsCache
Definition: theme.cpp:70
Plasma::CacheType
CacheType
Definition: theme.cpp:67
Plasma::Theme::Theme
Theme(QObject *parent=0)
Default constructor.
Definition: theme.cpp:549
Plasma::Theme::listThemeInfo
static KPluginInfo::List listThemeInfo()
Definition: theme.cpp:599
Plasma::Theme::setFont
Q_INVOKABLE void setFont(const QFont &font, FontRole role=DefaultFont)
Sets the default font to be used with themed items.
Definition: theme.cpp:964
ThemeConfig::cacheTheme
bool cacheTheme() const
Get Whether or not to create an on-disk cache for the theme.
Definition: libplasma-theme-global.h:21
Plasma::Theme::VisitedLinkColor
color for clickable links
Definition: theme.h:70
Plasma::AnimationScriptEngine::clearAnimations
void clearAnimations()
Definition: animationscriptengine.cpp:75
Plasma::styles
styles
Definition: theme.cpp:62
Plasma::DEFAULT_WALLPAPER_WIDTH
static const int DEFAULT_WALLPAPER_WIDTH
Definition: theme.cpp:59
Plasma::PackageStructure::Ptr
KSharedPtr< PackageStructure > Ptr
Definition: packagestructure.h:77
Plasma::Theme::ViewHoverColor
background color for views
Definition: theme.h:75
Plasma::Theme::currentThemeHasImage
Q_INVOKABLE bool currentThemeHasImage(const QString &name) const
Checks if this theme has an image named in a certain way.
Definition: theme.cpp:902
Plasma::NoCache
Definition: theme.cpp:68
Plasma::Theme::releaseRectsCache
void releaseRectsCache(const QString &image)
Frees up memory used by cached information for a given image without removing the permenant record of...
Definition: theme.cpp:1165
ThemeConfig::themeCacheKb
int themeCacheKb() const
Get The maximum size of the on-disk Theme cache in kilobytes.
Definition: libplasma-theme-global.h:30
Plasma::DEFAULT_WALLPAPER_HEIGHT
static const int DEFAULT_WALLPAPER_HEIGHT
Definition: theme.cpp:60
Plasma::Theme::windowTranslucencyEnabled
Q_INVOKABLE bool windowTranslucencyEnabled() const
Definition: theme.cpp:998
Plasma::WindowEffects::isEffectAvailable
bool isEffectAvailable(Effect effect)
Definition: windoweffects.cpp:44
Plasma::Theme::ViewBackgroundColor
text color for views
Definition: theme.h:74
Plasma::Theme::ButtonTextColor
Definition: theme.h:67
Plasma::Theme::styleSheet
Q_INVOKABLE QString styleSheet(const QString &css=QString()) const
Provides a Plasma::Theme-themed stylesheet for hybrid (web / native Plasma) widgets.
Definition: theme.cpp:836
Plasma::Theme::SmallestFont
The smallest readable font.
Definition: theme.h:82
Plasma::Theme::setUseGlobalSettings
void setUseGlobalSettings(bool useGlobal)
Tells the theme whether to follow the global settings or use application specific settings...
Definition: theme.cpp:1003
Plasma::Theme::wallpaperPath
Q_INVOKABLE QString wallpaperPath(const QSize &size=QSize()) const
Retrieves the default wallpaper associated with this theme.
Definition: theme.cpp:852
Plasma::Theme::ButtonFocusColor
color for hover effect on buttons
Definition: theme.h:72
DEFAULT_WALLPAPER_SUFFIX
#define DEFAULT_WALLPAPER_SUFFIX
Definition: theme.cpp:58
Plasma::Theme::DesktopFont
The standard text font.
Definition: theme.h:81
Plasma::Theme
Interface to the Plasma theme.
Definition: theme.h:56
Plasma::Theme::fontMetrics
Q_INVOKABLE QFontMetrics fontMetrics() const
Definition: theme.cpp:992
Plasma::DEFAULTSTYLE
Definition: theme.cpp:63
Plasma::Theme::ColorRole
ColorRole
Definition: theme.h:62
Plasma::Theme::invalidateRectsCache
void invalidateRectsCache(const QString &image)
Discards all the information about a given image from the rectangle disk cache.
Definition: theme.cpp:1155
Plasma::Theme::ButtonBackgroundColor
text color for buttons
Definition: theme.h:68
Plasma::Theme::toolTipDelay
int toolTipDelay() const
Definition: theme.cpp:1196
Plasma::Theme::listCachedRectKeys
QStringList listCachedRectKeys(const QString &image) const
Returns a list of all keys of cached rects for the given image.
Definition: theme.cpp:1109
Plasma::Theme::findInRectsCache
bool findInRectsCache(const QString &image, const QString &element, QRectF &rect) const
Tries to load the rect of a sub element from a disk cache.
Definition: theme.cpp:1076
Plasma::SVGSTYLE
Definition: theme.cpp:64
Plasma::Theme::insertIntoCache
void insertIntoCache(const QString &key, const QPixmap &pix)
Insert specified pixmap into the cache.
Definition: theme.cpp:1054
Plasma::Theme::color
Q_INVOKABLE QColor color(ColorRole role) const
Returns the text color to be used by items resting on the background.
Definition: theme.cpp:918
DEFAULT_WALLPAPER_THEME
#define DEFAULT_WALLPAPER_THEME
Definition: theme.cpp:57
Plasma::Theme::BackgroundColor
the default background color
Definition: theme.h:66
Plasma::Theme::LinkColor
background color for buttons
Definition: theme.h:69
Plasma::WindowEffects::BlurBehind
Definition: windoweffects.h:45
Plasma::Theme::ViewFocusColor
color for hover effect on view
Definition: theme.h:76
Plasma::Theme::ButtonHoverColor
color visited clickable links
Definition: theme.h:71
Plasma::packageStructure
PackageStructure::Ptr packageStructure(const QString &language, ComponentType type)
Loads an appropriate PackageStructure for the given language and type.
Definition: scriptengine.cpp:274
ThemeConfig
Definition: libplasma-theme-global.h:10
Plasma::Theme::useGlobalSettings
bool useGlobalSettings() const
Definition: theme.cpp:1015
Plasma::Theme::~Theme
~Theme()
Definition: theme.cpp:575
Plasma::Theme::homepage
KUrl homepage() const
Definition: theme.cpp:1188
Plasma::Theme::themeName
QString themeName() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:48:34 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Plasma

Skip menu "Plasma"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal