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

Plasma

  • 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 
201  bool locolor : 1;
202  bool compositingActive : 1;
203  bool blurActive : 1;
204  bool isDefault : 1;
205  bool useGlobal : 1;
206  bool hasWallpapers : 1;
207  bool cacheTheme : 1;
208  bool useNativeWidgetStyle :1;
209 };
210 
211 PackageStructure::Ptr ThemePrivate::packageStructure(0);
212 const char *ThemePrivate::defaultTheme = "default";
213 const char *ThemePrivate::themeRcFile = "plasmarc";
214 // the system colors theme is used to cache unthemed svgs with colorization needs
215 // these svgs do not follow the theme's colors, but rather the system colors
216 const char *ThemePrivate::systemColorsTheme = "internal-system-colors";
217 #ifdef Q_WS_X11
218 EffectWatcher *ThemePrivate::s_blurEffectWatcher = 0;
219 #endif
220 
221 bool ThemePrivate::useCache()
222 {
223  if (cacheTheme && !pixmapCache) {
224  ThemeConfig config;
225  pixmapCache = new KImageCache("plasma_theme_" + themeName, config.themeCacheKb() * 1024);
226  if (themeName != systemColorsTheme) {
227  //check for expired cache
228  // FIXME: when using the system colors, if they change while the application is not running
229  // the cache should be dropped; we need a way to detect system color change when the
230  // application is not running.
231  QFile f(KStandardDirs::locate("data", "desktoptheme/" + themeName + "/metadata.desktop"));
232  QFileInfo info(f);
233  if (info.lastModified().toTime_t() > uint(pixmapCache->lastModifiedTime())) {
234  pixmapCache->clear();
235  }
236  }
237  }
238 
239  return cacheTheme;
240 }
241 
242 void ThemePrivate::onAppExitCleanup()
243 {
244  pixmapsToCache.clear();
245  delete pixmapCache;
246  pixmapCache = 0;
247  cacheTheme = false;
248 }
249 
250 QString ThemePrivate::findInTheme(const QString &image, const QString &theme, bool cache)
251 {
252  if (cache && discoveries.contains(image)) {
253  return discoveries[image];
254  }
255 
256  QString search;
257 
258  if (locolor) {
259  search = QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/locolor/") % image;
260  search = KStandardDirs::locate("data", search);
261  } else if (!compositingActive) {
262  search = QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/opaque/") % image;
263  search = KStandardDirs::locate("data", search);
264  } else if (WindowEffects::isEffectAvailable(WindowEffects::BlurBehind)) {
265  search = QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/translucent/") % image;
266  search = KStandardDirs::locate("data", search);
267  }
268 
269  //not found or compositing enabled
270  if (search.isEmpty()) {
271  search = QLatin1Literal("desktoptheme/") % theme % QLatin1Char('/') % image;
272  search = KStandardDirs::locate("data", search);
273  }
274 
275  if (cache && !search.isEmpty()) {
276  discoveries.insert(image, search);
277  }
278 
279  return search;
280 }
281 
282 void ThemePrivate::compositingChanged(bool active)
283 {
284 #ifdef Q_WS_X11
285  if (compositingActive != active) {
286  compositingActive = active;
287  //kDebug() << QTime::currentTime();
288  scheduleThemeChangeNotification(PixmapCache | SvgElementsCache);
289  }
290 #endif
291 }
292 
293 void ThemePrivate::discardCache(CacheTypes caches)
294 {
295  if (caches & PixmapCache) {
296  pixmapsToCache.clear();
297  saveTimer->stop();
298  if (pixmapCache) {
299  pixmapCache->clear();
300  }
301  } else {
302  // This deletes the object but keeps the on-disk cache for later use
303  delete pixmapCache;
304  pixmapCache = 0;
305  }
306 
307  cachedStyleSheets.clear();
308 
309  if (caches & SvgElementsCache) {
310  discoveries.clear();
311  invalidElements.clear();
312 
313  if (svgElementsCache) {
314  QFile f(svgElementsCache->name());
315  svgElementsCache = 0;
316  f.remove();
317  }
318 
319  const QString svgElementsFile = KStandardDirs::locateLocal("cache", "plasma-svgelements-" + themeName);
320  svgElementsCache = KSharedConfig::openConfig(svgElementsFile);
321  }
322 }
323 
324 void ThemePrivate::scheduledCacheUpdate()
325 {
326  if (useCache()) {
327  QHashIterator<QString, QPixmap> it(pixmapsToCache);
328  while (it.hasNext()) {
329  it.next();
330  pixmapCache->insertPixmap(idsToCache[it.key()], it.value());
331  }
332  }
333 
334  pixmapsToCache.clear();
335  keysToCache.clear();
336  idsToCache.clear();
337 }
338 
339 void ThemePrivate::colorsChanged()
340 {
341  colorScheme = KColorScheme(QPalette::Active, KColorScheme::Window, colors);
342  buttonColorScheme = KColorScheme(QPalette::Active, KColorScheme::Button, colors);
343  viewColorScheme = KColorScheme(QPalette::Active, KColorScheme::View, colors);
344  scheduleThemeChangeNotification(PixmapCache);
345 }
346 
347 void ThemePrivate::blurBehindChanged(bool blur)
348 {
349  if (blurActive != blur) {
350  blurActive = blur;
351  scheduleThemeChangeNotification(PixmapCache | SvgElementsCache);
352  }
353 }
354 
355 void ThemePrivate::scheduleThemeChangeNotification(CacheTypes caches)
356 {
357  cachesToDiscard |= caches;
358  updateNotificationTimer->start();
359 }
360 
361 void ThemePrivate::notifyOfChanged()
362 {
363  //kDebug() << cachesToDiscard;
364  discardCache(cachesToDiscard);
365  cachesToDiscard = NoCache;
366  emit q->themeChanged();
367 }
368 
369 const QString ThemePrivate::processStyleSheet(const QString &css)
370 {
371  QString stylesheet;
372  if (css.isEmpty()) {
373  stylesheet = cachedStyleSheets.value(DEFAULTSTYLE);
374  if (stylesheet.isEmpty()) {
375  stylesheet = QString("\n\
376  body {\n\
377  color: %textcolor;\n\
378  font-size: %fontsize;\n\
379  font-family: %fontfamily;\n\
380  }\n\
381  a:active { color: %activatedlink; }\n\
382  a:link { color: %link; }\n\
383  a:visited { color: %visitedlink; }\n\
384  a:hover { color: %hoveredlink; text-decoration: none; }\n\
385  ");
386  stylesheet = processStyleSheet(stylesheet);
387  cachedStyleSheets.insert(DEFAULTSTYLE, stylesheet);
388  }
389 
390  return stylesheet;
391  } else if (css == "SVG") {
392  stylesheet = cachedStyleSheets.value(SVGSTYLE);
393  if (stylesheet.isEmpty()) {
394  QString skel = ".ColorScheme-%1{color:%2;}";
395 
396  stylesheet += skel.arg("Text","%textcolor");
397  stylesheet += skel.arg("Background","%backgroundcolor");
398 
399  stylesheet += skel.arg("ButtonText","%buttontextcolor");
400  stylesheet += skel.arg("ButtonBackground","%buttonbackgroundcolor");
401  stylesheet += skel.arg("ButtonHover","%buttonhovercolor");
402  stylesheet += skel.arg("ButtonFocus","%buttonfocuscolor");
403 
404  stylesheet += skel.arg("ViewText","%viewtextcolor");
405  stylesheet += skel.arg("ViewBackground","%viewbackgroundcolor");
406  stylesheet += skel.arg("ViewHover","%viewhovercolor");
407  stylesheet += skel.arg("ViewFocus","%viewfocuscolor");
408 
409  stylesheet = processStyleSheet(stylesheet);
410  cachedStyleSheets.insert(SVGSTYLE, stylesheet);
411  }
412 
413  return stylesheet;
414  } else {
415  stylesheet = css;
416  }
417 
418  QHash<QString, QString> elements;
419  // If you add elements here, make sure their names are sufficiently unique to not cause
420  // clashes between element keys
421  elements["%textcolor"] = q->color(Theme::TextColor).name();
422  elements["%backgroundcolor"] = q->color(Theme::BackgroundColor).name();
423  elements["%visitedlink"] = q->color(Theme::VisitedLinkColor).name();
424  elements["%activatedlink"] = q->color(Theme::HighlightColor).name();
425  elements["%hoveredlink"] = q->color(Theme::HighlightColor).name();
426  elements["%link"] = q->color(Theme::LinkColor).name();
427  elements["%buttontextcolor"] = q->color(Theme::ButtonTextColor).name();
428  elements["%buttonbackgroundcolor"] = q->color(Theme::ButtonBackgroundColor).name();
429  elements["%buttonhovercolor"] = q->color(Theme::ButtonHoverColor).name();
430  elements["%buttonfocuscolor"] = q->color(Theme::ButtonFocusColor).name();
431  elements["%viewtextcolor"] = q->color(Theme::ViewTextColor).name();
432  elements["%viewbackgroundcolor"] = q->color(Theme::ViewBackgroundColor).name();
433  elements["%viewhovercolor"] = q->color(Theme::ViewHoverColor).name();
434  elements["%viewfocuscolor"] = q->color(Theme::ViewFocusColor).name();
435 
436  QFont font = q->font(Theme::DefaultFont);
437  elements["%fontsize"] = QString("%1pt").arg(font.pointSize());
438  elements["%fontfamily"] = font.family().split('[').first();
439  elements["%smallfontsize"] = QString("%1pt").arg(KGlobalSettings::smallestReadableFont().pointSize());
440 
441  QHash<QString, QString>::const_iterator it = elements.constBegin();
442  QHash<QString, QString>::const_iterator itEnd = elements.constEnd();
443  for ( ; it != itEnd; ++it) {
444  stylesheet.replace(it.key(), it.value());
445  }
446  return stylesheet;
447 }
448 
449 class ThemeSingleton
450 {
451 public:
452  ThemeSingleton()
453  {
454  self.d->isDefault = true;
455 
456  //FIXME: if/when kconfig gets change notification, this will be unnecessary
457  KDirWatch::self()->addFile(KStandardDirs::locateLocal("config", ThemePrivate::themeRcFile));
458  QObject::connect(KDirWatch::self(), SIGNAL(created(QString)), &self, SLOT(settingsFileChanged(QString)));
459  QObject::connect(KDirWatch::self(), SIGNAL(dirty(QString)), &self, SLOT(settingsFileChanged(QString)));
460  }
461 
462  Theme self;
463 };
464 
465 K_GLOBAL_STATIC(ThemeSingleton, privateThemeSelf)
466 
467 Theme *Theme::defaultTheme()
468 {
469  return &privateThemeSelf->self;
470 }
471 
472 Theme::Theme(QObject *parent)
473  : QObject(parent),
474  d(new ThemePrivate(this))
475 {
476  settingsChanged();
477  if (QCoreApplication::instance()) {
478  connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()),
479  this, SLOT(onAppExitCleanup()));
480  }
481 }
482 
483 Theme::Theme(const QString &themeName, QObject *parent)
484  : QObject(parent),
485  d(new ThemePrivate(this))
486 {
487  // turn off caching so we don't accidently trigger unnecessary disk activity at this point
488  bool useCache = d->cacheTheme;
489  d->cacheTheme = false;
490  setThemeName(themeName);
491  d->cacheTheme = useCache;
492  if (QCoreApplication::instance()) {
493  connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()),
494  this, SLOT(onAppExitCleanup()));
495  }
496 }
497 
498 Theme::~Theme()
499 {
500  if (d->svgElementsCache) {
501  QHashIterator<QString, QSet<QString> > it(d->invalidElements);
502  while (it.hasNext()) {
503  it.next();
504  KConfigGroup imageGroup(d->svgElementsCache, it.key());
505  imageGroup.writeEntry("invalidElements", it.value().toList()); //FIXME: add QSet support to KConfig
506  }
507  }
508 
509  d->onAppExitCleanup();
510  delete d;
511 }
512 
513 PackageStructure::Ptr Theme::packageStructure()
514 {
515  if (!ThemePrivate::packageStructure) {
516  ThemePrivate::packageStructure = new ThemePackage();
517  }
518 
519  return ThemePrivate::packageStructure;
520 }
521 
522 KPluginInfo::List Theme::listThemeInfo()
523 {
524  const QStringList themes = KGlobal::dirs()->findAllResources("data", "desktoptheme/*/metadata.desktop",
525  KStandardDirs::NoDuplicates);
526  return KPluginInfo::fromFiles(themes);
527 }
528 
529 void ThemePrivate::settingsFileChanged(const QString &file)
530 {
531  if (file.endsWith(themeRcFile)) {
532  config().config()->reparseConfiguration();
533  q->settingsChanged();
534  }
535 }
536 
537 void Theme::settingsChanged()
538 {
539  KConfigGroup cg = d->config();
540  d->setThemeName(cg.readEntry("name", ThemePrivate::defaultTheme), false);
541  cg = KConfigGroup(cg.config(), "PlasmaToolTips");
542  d->toolTipDelay = cg.readEntry("Delay", 700);
543 }
544 
545 void Theme::setThemeName(const QString &themeName)
546 {
547  d->setThemeName(themeName, true);
548 }
549 
550 void ThemePrivate::processWallpaperSettings(KConfigBase *metadata)
551 {
552  if (!defaultWallpaperTheme.isEmpty() && defaultWallpaperTheme != DEFAULT_WALLPAPER_THEME) {
553  return;
554  }
555 
556  KConfigGroup cg;
557  if (metadata->hasGroup("Wallpaper")) {
558  // we have a theme color config, so let's also check to see if
559  // there is a wallpaper defined in there.
560  cg = KConfigGroup(metadata, "Wallpaper");
561  } else {
562  // since we didn't find an entry in the theme, let's look in the main
563  // theme config
564  cg = config();
565  }
566 
567  defaultWallpaperTheme = cg.readEntry("defaultWallpaperTheme", DEFAULT_WALLPAPER_THEME);
568  defaultWallpaperSuffix = cg.readEntry("defaultFileSuffix", DEFAULT_WALLPAPER_SUFFIX);
569  defaultWallpaperWidth = cg.readEntry("defaultWidth", DEFAULT_WALLPAPER_WIDTH);
570  defaultWallpaperHeight = cg.readEntry("defaultHeight", DEFAULT_WALLPAPER_HEIGHT);
571 }
572 
573 void ThemePrivate::processAnimationSettings(const QString &theme, KConfigBase *metadata)
574 {
575  KConfigGroup cg(metadata, "Animations");
576  const QString animDir = QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/animations/");
577  foreach (const QString &path, cg.keyList()) {
578  const QStringList anims = cg.readEntry(path, QStringList());
579  foreach (const QString &anim, anims) {
580  if (!animationMapping.contains(anim)) {
581  kDebug() << "Registering animation. animDir: " << animDir
582  << "\tanim: " << anim
583  << "\tpath: " << path << "\t*******\n\n\n";
584  //key: desktoptheme/default/animations/+ all.js
585  //value: ZoomAnimation
586  animationMapping.insert(anim, animDir % path);
587  } else {
588  kDebug() << "************Animation already registered!\n\n\n";
589  }
590  }
591  }
592 
593 }
594 
595 void ThemePrivate::setThemeName(const QString &tempThemeName, bool writeSettings)
596 {
597  //kDebug() << tempThemeName;
598  QString theme = tempThemeName;
599  if (theme.isEmpty() || theme == themeName) {
600  // let's try and get the default theme at least
601  if (themeName.isEmpty()) {
602  theme = ThemePrivate::defaultTheme;
603  } else {
604  return;
605  }
606  }
607 
608  // we have one special theme: essentially a dummy theme used to cache things with
609  // the system colors.
610  bool realTheme = theme != systemColorsTheme;
611  if (realTheme) {
612  QString themePath = KStandardDirs::locate("data", QLatin1Literal("desktoptheme/") % theme % QLatin1Char('/'));
613  if (themePath.isEmpty() && themeName.isEmpty()) {
614  themePath = KStandardDirs::locate("data", "desktoptheme/default/");
615 
616  if (themePath.isEmpty()) {
617  return;
618  }
619 
620  theme = ThemePrivate::defaultTheme;
621  }
622  }
623 
624  // check again as ThemePrivate::defaultTheme might be empty
625  if (themeName == theme) {
626  return;
627  }
628 
629  themeName = theme;
630 
631  // load the color scheme config
632  const QString colorsFile = realTheme ? KStandardDirs::locate("data", QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/colors"))
633  : QString();
634 
635  //kDebug() << "we're going for..." << colorsFile << "*******************";
636 
637  // load the wallpaper settings, if any
638  if (realTheme) {
639  const QString metadataPath(KStandardDirs::locate("data", QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/metadata.desktop")));
640  KConfig metadata(metadataPath);
641 
642  processWallpaperSettings(&metadata);
643 
644  AnimationScriptEngine::clearAnimations();
645  animationMapping.clear();
646  processAnimationSettings(themeName, &metadata);
647 
648  KConfigGroup cg(&metadata, "Settings");
649  useNativeWidgetStyle = cg.readEntry("UseNativeWidgetStyle", false);
650  QString fallback = cg.readEntry("FallbackTheme", QString());
651 
652  fallbackThemes.clear();
653  while (!fallback.isEmpty() && !fallbackThemes.contains(fallback)) {
654  fallbackThemes.append(fallback);
655 
656  QString metadataPath(KStandardDirs::locate("data", QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/metadata.desktop")));
657  KConfig metadata(metadataPath);
658  KConfigGroup cg(&metadata, "Settings");
659  fallback = cg.readEntry("FallbackTheme", QString());
660  }
661 
662  if (!fallbackThemes.contains("oxygen")) {
663  fallbackThemes.append("oxygen");
664  }
665 
666  if (!fallbackThemes.contains(ThemePrivate::defaultTheme)) {
667  fallbackThemes.append(ThemePrivate::defaultTheme);
668  }
669 
670  foreach (const QString &theme, fallbackThemes) {
671  QString metadataPath(KStandardDirs::locate("data", QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/metadata.desktop")));
672  KConfig metadata(metadataPath);
673  processAnimationSettings(theme, &metadata);
674  processWallpaperSettings(&metadata);
675  }
676  }
677 
678  if (colorsFile.isEmpty()) {
679  colors = 0;
680  QObject::connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
681  q, SLOT(colorsChanged()), Qt::UniqueConnection);
682  } else {
683  QObject::disconnect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
684  q, SLOT(colorsChanged()));
685  colors = KSharedConfig::openConfig(colorsFile);
686  }
687 
688  colorScheme = KColorScheme(QPalette::Active, KColorScheme::Window, colors);
689  buttonColorScheme = KColorScheme(QPalette::Active, KColorScheme::Button, colors);
690  viewColorScheme = KColorScheme(QPalette::Active, KColorScheme::View, colors);
691  hasWallpapers = KStandardDirs::exists(KStandardDirs::locateLocal("data", QLatin1Literal("desktoptheme/") % theme % QLatin1Literal("/wallpapers/")));
692 
693  if (realTheme && isDefault && writeSettings) {
694  // we're the default theme, let's save our state
695  KConfigGroup &cg = config();
696  if (ThemePrivate::defaultTheme == themeName) {
697  cg.deleteEntry("name");
698  } else {
699  cg.writeEntry("name", themeName);
700  }
701  cg.sync();
702  }
703 
704  scheduleThemeChangeNotification(SvgElementsCache);
705 }
706 
707 QString Theme::themeName() const
708 {
709  return d->themeName;
710 }
711 
712 QString Theme::imagePath(const QString &name) const
713 {
714  // look for a compressed svg file in the theme
715  if (name.contains("../") || name.isEmpty()) {
716  // we don't support relative paths
717  //kDebug() << "Theme says: bad image path " << name;
718  return QString();
719  }
720 
721  const QString svgzName = name % QLatin1Literal(".svgz");
722  QString path = d->findInTheme(svgzName, d->themeName);
723 
724  if (path.isEmpty()) {
725  // try for an uncompressed svg file
726  const QString svgName = name % QLatin1Literal(".svg");
727  path = d->findInTheme(svgName, d->themeName);
728 
729  // search in fallback themes if necessary
730  for (int i = 0; path.isEmpty() && i < d->fallbackThemes.count(); ++i) {
731  if (d->themeName == d->fallbackThemes[i]) {
732  continue;
733  }
734 
735  // try a compressed svg file in the fallback theme
736  path = d->findInTheme(svgzName, d->fallbackThemes[i]);
737 
738  if (path.isEmpty()) {
739  // try an uncompressed svg file in the fallback theme
740  path = d->findInTheme(svgName, d->fallbackThemes[i]);
741  }
742  }
743  }
744 
745  /*
746  if (path.isEmpty()) {
747  kDebug() << "Theme says: bad image path " << name;
748  }
749  */
750 
751  return path;
752 }
753 
754 QString Theme::styleSheet(const QString &css) const
755 {
756  return d->processStyleSheet(css);
757 }
758 
759 QString Theme::animationPath(const QString &name) const
760 {
761  const QString path = d->animationMapping.value(name);
762  if (path.isEmpty()) {
763  //kError() << "****** FAILED TO FIND IN MAPPING!";
764  return path;
765  }
766 
767  return KStandardDirs::locate("data", path);
768 }
769 
770 QString Theme::wallpaperPath(const QSize &size) const
771 {
772  QString fullPath;
773  QString image = d->defaultWallpaperTheme;
774 
775  image.append("/contents/images/%1x%2").append(d->defaultWallpaperSuffix);
776  QString defaultImage = image.arg(d->defaultWallpaperWidth).arg(d->defaultWallpaperHeight);
777 
778  if (size.isValid()) {
779  // try to customize the paper to the size requested
780  //TODO: this should do better than just fallback to the default size.
781  // a "best fit" matching would be far better, so we don't end
782  // up returning a 1920x1200 wallpaper for a 640x480 request ;)
783  image = image.arg(size.width()).arg(size.height());
784  } else {
785  image = defaultImage;
786  }
787 
788  //TODO: the theme's wallpaper overrides regularly installed wallpapers.
789  // should it be possible for user installed (e.g. locateLocal) wallpapers
790  // to override the theme?
791  if (d->hasWallpapers) {
792  // check in the theme first
793  fullPath = d->findInTheme(QLatin1Literal("wallpapers/") % image, d->themeName);
794 
795  if (fullPath.isEmpty()) {
796  fullPath = d->findInTheme(QLatin1Literal("wallpapers/") % defaultImage, d->themeName);
797  }
798  }
799 
800  if (fullPath.isEmpty()) {
801  // we failed to find it in the theme, so look in the standard directories
802  //kDebug() << "looking for" << image;
803  fullPath = KStandardDirs::locate("wallpaper", image);
804  }
805 
806  if (fullPath.isEmpty()) {
807  // we still failed to find it in the theme, so look for the default in
808  // the standard directories
809  //kDebug() << "looking for" << defaultImage;
810  fullPath = KStandardDirs::locate("wallpaper", defaultImage);
811 
812  if (fullPath.isEmpty()) {
813  kDebug() << "exhausted every effort to find a wallpaper.";
814  }
815  }
816 
817  return fullPath;
818 }
819 
820 bool Theme::currentThemeHasImage(const QString &name) const
821 {
822  if (name.contains("../")) {
823  // we don't support relative paths
824  return false;
825  }
826 
827  return !(d->findInTheme(name % QLatin1Literal(".svgz"), d->themeName, false).isEmpty()) ||
828  !(d->findInTheme(name % QLatin1Literal(".svg"), d->themeName, false).isEmpty());
829 }
830 
831 KSharedConfigPtr Theme::colorScheme() const
832 {
833  return d->colors;
834 }
835 
836 QColor Theme::color(ColorRole role) const
837 {
838  switch (role) {
839  case TextColor:
840  return d->colorScheme.foreground(KColorScheme::NormalText).color();
841 
842  case HighlightColor:
843  return d->colorScheme.decoration(KColorScheme::HoverColor).color();
844 
845  case BackgroundColor:
846  return d->colorScheme.background(KColorScheme::NormalBackground).color();
847 
848  case ButtonTextColor:
849  return d->buttonColorScheme.foreground(KColorScheme::NormalText).color();
850 
851  case ButtonBackgroundColor:
852  return d->buttonColorScheme.background(KColorScheme::NormalBackground).color();
853 
854  case ButtonHoverColor:
855  return d->buttonColorScheme.decoration(KColorScheme::HoverColor).color();
856 
857  case ButtonFocusColor:
858  return d->buttonColorScheme.decoration(KColorScheme::FocusColor).color();
859 
860  case ViewTextColor:
861  return d->viewColorScheme.foreground(KColorScheme::NormalText).color();
862 
863  case ViewBackgroundColor:
864  return d->viewColorScheme.background(KColorScheme::NormalBackground).color();
865 
866  case ViewHoverColor:
867  return d->viewColorScheme.decoration(KColorScheme::HoverColor).color();
868 
869  case ViewFocusColor:
870  return d->viewColorScheme.decoration(KColorScheme::FocusColor).color();
871 
872  case LinkColor:
873  return d->viewColorScheme.foreground(KColorScheme::LinkText).color();
874 
875  case VisitedLinkColor:
876  return d->viewColorScheme.foreground(KColorScheme::VisitedText).color();
877  }
878 
879  return QColor();
880 }
881 
882 void Theme::setFont(const QFont &font, FontRole role)
883 {
884  Q_UNUSED(role)
885  d->generalFont = font;
886 }
887 
888 QFont Theme::font(FontRole role) const
889 {
890  switch (role) {
891  case DesktopFont: {
892  KConfigGroup cg(KGlobal::config(), "General");
893  return cg.readEntry("desktopFont", d->generalFont);
894  }
895  break;
896 
897  case DefaultFont:
898  default:
899  return d->generalFont;
900  break;
901 
902  case SmallestFont:
903  return KGlobalSettings::smallestReadableFont();
904  break;
905  }
906 
907  return d->generalFont;
908 }
909 
910 QFontMetrics Theme::fontMetrics() const
911 {
912  //TODO: allow this to be overridden with a plasma specific font?
913  return QFontMetrics(d->generalFont);
914 }
915 
916 bool Theme::windowTranslucencyEnabled() const
917 {
918  return d->compositingActive;
919 }
920 
921 void Theme::setUseGlobalSettings(bool useGlobal)
922 {
923  if (d->useGlobal == useGlobal) {
924  return;
925  }
926 
927  d->useGlobal = useGlobal;
928  d->cfg = KConfigGroup();
929  d->themeName.clear();
930  settingsChanged();
931 }
932 
933 bool Theme::useGlobalSettings() const
934 {
935  return d->useGlobal;
936 }
937 
938 bool Theme::useNativeWidgetStyle() const
939 {
940  return d->useNativeWidgetStyle;
941 }
942 
943 bool Theme::findInCache(const QString &key, QPixmap &pix)
944 {
945  if (d->useCache()) {
946  const QString id = d->keysToCache.value(key);
947  if (d->pixmapsToCache.contains(id)) {
948  pix = d->pixmapsToCache.value(id);
949  return !pix.isNull();
950  }
951 
952  QPixmap temp;
953  if (d->pixmapCache->findPixmap(key, &temp) && !temp.isNull()) {
954  pix = temp;
955  return true;
956  }
957  }
958 
959  return false;
960 }
961 
962 // BIC FIXME: Should be merged with the other findInCache method above when we break BC
963 bool Theme::findInCache(const QString &key, QPixmap &pix, unsigned int lastModified)
964 {
965  if (d->useCache() && lastModified > uint(d->pixmapCache->lastModifiedTime())) {
966  return false;
967  }
968 
969  return findInCache(key, pix);
970 }
971 
972 void Theme::insertIntoCache(const QString& key, const QPixmap& pix)
973 {
974  if (d->useCache()) {
975  d->pixmapCache->insertPixmap(key, pix);
976  }
977 }
978 
979 void Theme::insertIntoCache(const QString& key, const QPixmap& pix, const QString& id)
980 {
981  if (d->useCache()) {
982  d->pixmapsToCache.insert(id, pix);
983 
984  if (d->idsToCache.contains(id)) {
985  d->keysToCache.remove(d->idsToCache[id]);
986  }
987 
988  d->keysToCache.insert(key, id);
989  d->idsToCache.insert(id, key);
990  d->saveTimer->start();
991  }
992 }
993 
994 bool Theme::findInRectsCache(const QString &image, const QString &element, QRectF &rect) const
995 {
996  if (!d->svgElementsCache) {
997  return false;
998  }
999 
1000  KConfigGroup imageGroup(d->svgElementsCache, image);
1001  rect = imageGroup.readEntry(element % QLatin1Literal("Size"), QRectF());
1002 
1003  if (rect.isValid()) {
1004  return true;
1005  }
1006 
1007  //Name starting by _ means the element is empty and we're asked for the size of
1008  //the whole image, so the whole image is never invalid
1009  if (element.indexOf('_') <= 0) {
1010  return false;
1011  }
1012 
1013  bool invalid = false;
1014 
1015  QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
1016  if (it == d->invalidElements.end()) {
1017  QSet<QString> elements = imageGroup.readEntry("invalidElements", QStringList()).toSet();
1018  d->invalidElements.insert(image, elements);
1019  invalid = elements.contains(element);
1020  } else {
1021  invalid = it.value().contains(element);
1022  }
1023 
1024  return invalid;
1025 }
1026 
1027 QStringList Theme::listCachedRectKeys(const QString &image) const
1028 {
1029  if (!d->svgElementsCache) {
1030  return QStringList();
1031  }
1032 
1033  KConfigGroup imageGroup(d->svgElementsCache, image);
1034  QStringList keys = imageGroup.keyList();
1035 
1036  QMutableListIterator<QString> i(keys);
1037  while (i.hasNext()) {
1038  QString key = i.next();
1039  if (key.endsWith("Size")) {
1040  // The actual cache id used from outside doesn't end on "Size".
1041  key.resize(key.size() - 4);
1042  i.setValue(key);
1043  } else {
1044  i.remove();
1045  }
1046  }
1047  return keys;
1048 }
1049 
1050 void Theme::insertIntoRectsCache(const QString& image, const QString &element, const QRectF &rect)
1051 {
1052  if (!d->svgElementsCache) {
1053  return;
1054  }
1055 
1056  if (rect.isValid()) {
1057  KConfigGroup imageGroup(d->svgElementsCache, image);
1058  imageGroup.writeEntry(element % QLatin1Literal("Size"), rect);
1059  } else {
1060  QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
1061  if (it == d->invalidElements.end()) {
1062  d->invalidElements[image].insert(element);
1063  } else if (!it.value().contains(element)) {
1064  if (it.value().count() > 1000) {
1065  it.value().erase(it.value().begin());
1066  }
1067 
1068  it.value().insert(element);
1069  }
1070  }
1071 }
1072 
1073 void Theme::invalidateRectsCache(const QString& image)
1074 {
1075  if (d->svgElementsCache) {
1076  KConfigGroup imageGroup(d->svgElementsCache, image);
1077  imageGroup.deleteGroup();
1078  }
1079 
1080  d->invalidElements.remove(image);
1081 }
1082 
1083 void Theme::releaseRectsCache(const QString &image)
1084 {
1085  QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
1086  if (it != d->invalidElements.end()) {
1087  if (!d->svgElementsCache) {
1088  KConfigGroup imageGroup(d->svgElementsCache, it.key());
1089  imageGroup.writeEntry("invalidElements", it.value().toList());
1090  }
1091 
1092  d->invalidElements.erase(it);
1093  }
1094 }
1095 
1096 void Theme::setCacheLimit(int kbytes)
1097 {
1098  Q_UNUSED(kbytes)
1099  if (d->useCache()) {
1100  ;
1101  // Too late for you bub.
1102  // d->pixmapCache->setCacheLimit(kbytes);
1103  }
1104 }
1105 
1106 KUrl Theme::homepage() const
1107 {
1108  const QString metadataPath(KStandardDirs::locate("data", QLatin1Literal("desktoptheme/") % d->themeName % QLatin1Literal("/metadata.desktop")));
1109  KConfig metadata(metadataPath);
1110  KConfigGroup brandConfig(&metadata, "Branding");
1111  return brandConfig.readEntry("homepage", KUrl("http://www.kde.org"));
1112 }
1113 
1114 int Theme::toolTipDelay() const
1115 {
1116  return d->toolTipDelay;
1117 }
1118 
1119 }
1120 
1121 #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:712
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:1050
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:943
Plasma::Theme::setThemeName
void setThemeName(const QString &themeName)
Sets the current theme being used.
Definition: theme.cpp:545
Plasma::Theme::useNativeWidgetStyle
bool useNativeWidgetStyle() const
Definition: theme.cpp:938
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:537
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:759
Plasma::Theme::colorScheme
Q_INVOKABLE KSharedConfigPtr colorScheme() const
Returns the color scheme configurationthat goes along this theme.
Definition: theme.cpp:831
Plasma::Theme::font
Q_INVOKABLE QFont font(FontRole role) const
Returns the font to be used by themed items.
Definition: theme.cpp:888
Plasma::Theme::TextColor
the text color to be used by items resting on the background
Definition: theme.h:63
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:1096
QObject
Plasma::Theme::packageStructure
static PackageStructure::Ptr packageStructure()
Definition: theme.cpp:513
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:472
Plasma::Theme::listThemeInfo
static KPluginInfo::List listThemeInfo()
Definition: theme.cpp:522
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:882
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:820
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:1083
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:916
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:754
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:921
Plasma::Theme::wallpaperPath
Q_INVOKABLE QString wallpaperPath(const QSize &size=QSize()) const
Retrieves the default wallpaper associated with this theme.
Definition: theme.cpp:770
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:910
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:1073
Plasma::Theme::ButtonBackgroundColor
text color for buttons
Definition: theme.h:68
Plasma::Theme::toolTipDelay
int toolTipDelay() const
Definition: theme.cpp:1114
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:1027
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:994
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:972
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:836
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
Plasma::Theme::useGlobalSettings
bool useGlobalSettings() const
Definition: theme.cpp:933
Plasma::Theme::~Theme
~Theme()
Definition: theme.cpp:498
Plasma::Theme::homepage
KUrl homepage() const
Definition: theme.cpp:1106
Plasma::Theme::themeName
QString themeName() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Jun 17 2014 17:07:42 by doxygen 1.8.5 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-4.10.5 API Reference

Skip menu "kdelibs-4.10.5 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
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
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