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

KDEUI

  • sources
  • kde-4.14
  • kdelibs
  • kdeui
  • icons
kiconloader.cpp
Go to the documentation of this file.
1 /* vi: ts=8 sts=4 sw=4
2  *
3  * kiconloader.cpp: An icon loader for KDE with theming functionality.
4  *
5  * This file is part of the KDE project, module kdeui.
6  * Copyright (C) 2000 Geert Jansen <jansen@kde.org>
7  * Antonio Larrosa <larrosa@kde.org>
8  * 2010 Michael Pyne <mpyne@kde.org>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License version 2 as published by the Free Software Foundation.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB. If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24 
25 #include "kiconloader.h"
26 
27 #include <sys/types.h>
28 #include <stdlib.h> //for abs
29 #include <unistd.h> //for readlink
30 #include <dirent.h>
31 #include <assert.h>
32 
33 #include <QtCore/QCache>
34 #include <QtCore/QFileInfo>
35 #include <QtCore/QDir>
36 #include <QtCore/QBuffer>
37 #include <QtCore/QDataStream>
38 #include <QtCore/QByteArray>
39 #include <QtCore/QStringBuilder> // % operator for QString
40 #include <QtGui/QIcon>
41 #include <QtGui/QImage>
42 #include <QtGui/QMovie>
43 #include <QtGui/QPainter>
44 #include <QtGui/QPixmap>
45 #include <QtGui/QPixmapCache>
46 #ifndef _WIN32_WCE
47 #include <QtSvg/QSvgRenderer>
48 #endif
49 
50 // kdecore
51 #include <kconfig.h>
52 #include <kconfiggroup.h>
53 #include <kdebug.h>
54 #include <kstandarddirs.h>
55 #include <kglobal.h>
56 #include <kglobalsettings.h>
57 #include <kcomponentdata.h>
58 #include <kde_file.h>
59 #include <kshareddatacache.h>
60 
61 // kdeui
62 #include "kicontheme.h"
63 #include "kiconeffect.h"
64 #include "k3icon_p.h"
65 
66 // Used to make cache keys for icons with no group. Result type is QString*
67 K_GLOBAL_STATIC_WITH_ARGS(QString, NULL_EFFECT_FINGERPRINT, (QString::fromLatin1("noeffect")))
68 
69 
72 static bool pathIsRelative(const QString &path)
73 {
74 #ifdef Q_OS_UNIX
75  return (!path.isEmpty() && path[0] != QChar('/'));
76 #else
77  return QDir::isRelativePath(path);
78 #endif
79 }
80 
84 struct PixmapWithPath
85 {
86  QPixmap pixmap;
87  QString path;
88 };
89 
90 /*** KIconThemeNode: A node in the icon theme dependancy tree. ***/
91 
92 class KIconThemeNode
93 {
94 public:
95 
96  KIconThemeNode(KIconTheme *_theme);
97  ~KIconThemeNode();
98 
99  void queryIcons(QStringList *lst, int size, KIconLoader::Context context) const;
100  void queryIconsByContext(QStringList *lst, int size, KIconLoader::Context context) const;
101  K3Icon findIcon(const QString& name, int size, KIconLoader::MatchType match) const;
102  void printTree(QString& dbgString) const;
103 
104  KIconTheme *theme;
105 };
106 
107 KIconThemeNode::KIconThemeNode(KIconTheme *_theme)
108 {
109  theme = _theme;
110 }
111 
112 KIconThemeNode::~KIconThemeNode()
113 {
114  delete theme;
115 }
116 
117 void KIconThemeNode::printTree(QString& dbgString) const
118 {
119  /* This method doesn't have much sense anymore, so maybe it should
120  be removed in the (near?) future */
121  dbgString += '(';
122  dbgString += theme->name();
123  dbgString += ')';
124 }
125 
126 void KIconThemeNode::queryIcons(QStringList *result,
127  int size, KIconLoader::Context context) const
128 {
129  // add the icons of this theme to it
130  *result += theme->queryIcons(size, context);
131 }
132 
133 void KIconThemeNode::queryIconsByContext(QStringList *result,
134  int size, KIconLoader::Context context) const
135 {
136  // add the icons of this theme to it
137  *result += theme->queryIconsByContext(size, context);
138 }
139 
140 K3Icon KIconThemeNode::findIcon(const QString& name, int size,
141  KIconLoader::MatchType match) const
142 {
143  return theme->iconPath(name, size, match);
144 }
145 
146 
147 /*** KIconGroup: Icon type description. ***/
148 
149 struct KIconGroup
150 {
151  int size;
152  bool alphaBlending;
153 };
154 
155 
156 /*** d pointer for KIconLoader. ***/
157 class KIconLoaderPrivate
158 {
159 public:
160  KIconLoaderPrivate(KIconLoader *q)
161  : q(q)
162  , mpGroups(0)
163  , mIconCache(0)
164  {
165  }
166 
167  ~KIconLoaderPrivate()
168  {
169  /* antlarr: There's no need to delete d->mpThemeRoot as it's already
170  deleted when the elements of d->links are deleted */
171  qDeleteAll(links);
172  delete[] mpGroups;
173  delete mIconCache;
174  }
175 
179  void init( const QString& _appname, KStandardDirs *_dirs );
180 
184  bool initIconThemes();
185 
191  K3Icon findMatchingIcon(const QString& name, int size) const;
192 
199  K3Icon findMatchingIconWithGenericFallbacks(const QString& name, int size) const;
200 
205  void addAppThemes(const QString& appname);
206 
212  void addBaseThemes(KIconThemeNode *node, const QString &appname);
213 
219  void addInheritedThemes(KIconThemeNode *node, const QString &appname);
220 
227  void addThemeByName(const QString &themename, const QString &appname);
228 
233  QString unknownIconPath( int size ) const;
234 
239  QString removeIconExtension(const QString &name) const;
240 
247  void normalizeIconMetadata(KIconLoader::Group &group, int &size, int &state) const;
248 
254  QString makeCacheKey(const QString &name, KIconLoader::Group group, const QStringList &overlays,
255  int size, int state) const;
256 
263  QImage createIconImage(const QString &path, int size = 0);
264 
269  void insertCachedPixmapWithPath(const QString &key, const QPixmap &data, const QString &path);
270 
276  bool findCachedPixmapWithPath(const QString &key, QPixmap &data, QString &path);
277 
278  KIconLoader *const q;
279 
280  QStringList mThemesInTree;
281  KIconGroup *mpGroups;
282  KIconThemeNode *mpThemeRoot;
283  KStandardDirs *mpDirs;
284  KIconEffect mpEffect;
285  QList<KIconThemeNode *> links;
286 
287  // This shares the icons across all processes
288  KSharedDataCache* mIconCache;
289 
290  // This caches rendered QPixmaps in just this process.
291  QCache<QString, PixmapWithPath> mPixmapCache;
292 
293  bool extraDesktopIconsLoaded :1;
294  // lazy loading: initIconThemes() is only needed when the "links" list is needed
295  // mIconThemeInited is used inside initIconThemes() to init only once
296  bool mIconThemeInited :1;
297  QString appname;
298 
299  void drawOverlays(const KIconLoader *loader, KIconLoader::Group group, int state, QPixmap& pix, const QStringList& overlays);
300 };
301 
302 class KIconLoaderGlobalData
303 {
304 public:
305  KIconLoaderGlobalData() {
306  const QStringList genericIconsFiles = KGlobal::dirs()->findAllResources("xdgdata-mime", "generic-icons");
307  //kDebug() << genericIconsFiles;
308  Q_FOREACH(const QString& file, genericIconsFiles) {
309  parseGenericIconsFiles(file);
310  }
311  }
312 
313  QString genericIconFor(const QString& icon) const {
314  return m_genericIcons.value(icon);
315  }
316 
317 private:
318  void parseGenericIconsFiles(const QString& fileName);
319  QHash<QString, QString> m_genericIcons;
320 };
321 
322 void KIconLoaderGlobalData::parseGenericIconsFiles(const QString& fileName)
323 {
324  QFile file(fileName);
325  if (file.open(QIODevice::ReadOnly)) {
326  QTextStream stream(&file);
327  stream.setCodec("ISO 8859-1");
328  while (!stream.atEnd()) {
329  const QString line = stream.readLine();
330  if (line.isEmpty() || line[0] == '#')
331  continue;
332  const int pos = line.indexOf(':');
333  if (pos == -1) // syntax error
334  continue;
335  QString mimeIcon = line.left(pos);
336  const int slashindex = mimeIcon.indexOf(QLatin1Char('/'));
337  if (slashindex != -1) {
338  mimeIcon[slashindex] = QLatin1Char('-');
339  }
340 
341  const QString genericIcon = line.mid(pos+1);
342  m_genericIcons.insert(mimeIcon, genericIcon);
343  //kDebug(264) << mimeIcon << "->" << genericIcon;
344  }
345  }
346 }
347 
348 K_GLOBAL_STATIC(KIconLoaderGlobalData, s_globalData)
349 
350 void KIconLoaderPrivate::drawOverlays(const KIconLoader *iconLoader, KIconLoader::Group group, int state, QPixmap& pix, const QStringList& overlays)
351 {
352  if (overlays.isEmpty()) {
353  return;
354  }
355 
356  const int width = pix.size().width();
357  const int height = pix.size().height();
358  const int iconSize = qMin(width, height);
359  int overlaySize;
360 
361  if (iconSize < 32) {
362  overlaySize = 8;
363  } else if (iconSize <= 48) {
364  overlaySize = 16;
365  } else if (iconSize <= 96) {
366  overlaySize = 22;
367  } else if (iconSize < 256) {
368  overlaySize = 32;
369  } else {
370  overlaySize = 64;
371  }
372 
373  QPainter painter(&pix);
374 
375  int count = 0;
376  foreach (const QString& overlay, overlays) {
377  // Ensure empty strings fill up a emblem spot
378  // Needed when you have several emblems to ensure they're always painted
379  // at the same place, even if one is not here
380  if (overlay.isEmpty()) {
381  ++count;
382  continue;
383  }
384 
385  //TODO: should we pass in the kstate? it results in a slower
386  // path, and perhaps emblems should remain in the default state
387  // anyways?
388  const QPixmap pixmap = iconLoader->loadIcon(overlay, group, overlaySize, state, QStringList(), 0, true);
389 
390  if (pixmap.isNull()) {
391  continue;
392  }
393 
394  QPoint startPoint;
395  switch (count) {
396  case 0:
397  // bottom left corner
398  startPoint = QPoint(2, height - overlaySize - 2);
399  break;
400  case 1:
401  // bottom right corner
402  startPoint = QPoint(width - overlaySize - 2,
403  height - overlaySize - 2);
404  break;
405  case 2:
406  // top right corner
407  startPoint = QPoint(width - overlaySize - 2, 2);
408  break;
409  case 3:
410  // top left corner
411  startPoint = QPoint(2, 2);
412  break;
413  }
414 
415  painter.drawPixmap(startPoint, pixmap);
416 
417  ++count;
418  if (count > 3) {
419  break;
420  }
421  }
422 }
423 
424 KIconLoader::KIconLoader(const QString& _appname, KStandardDirs *_dirs, QObject* parent)
425  : QObject(parent)
426 {
427  setObjectName(_appname);
428  d = new KIconLoaderPrivate(this);
429 
430  connect(KGlobalSettings::self(), SIGNAL(iconChanged(int)),
431  this, SLOT(newIconLoader()));
432  d->init( _appname, _dirs );
433 }
434 
435 KIconLoader::KIconLoader(const KComponentData &componentData, QObject* parent)
436  : QObject(parent)
437 {
438  setObjectName(componentData.componentName());
439  d = new KIconLoaderPrivate(this);
440 
441  connect(KGlobalSettings::self(), SIGNAL(iconChanged(int)),
442  this, SLOT(newIconLoader()));
443  d->init(componentData.componentName(), componentData.dirs());
444 }
445 
446 void KIconLoader::reconfigure( const QString& _appname, KStandardDirs *_dirs )
447 {
448  d->mIconCache->clear();
449  delete d;
450  d = new KIconLoaderPrivate(this);
451  d->init( _appname, _dirs );
452 }
453 
454 void KIconLoaderPrivate::init( const QString& _appname, KStandardDirs *_dirs )
455 {
456  extraDesktopIconsLoaded=false;
457  mIconThemeInited = false;
458  mpThemeRoot = 0;
459 
460  if (_dirs)
461  mpDirs = _dirs;
462  else
463  mpDirs = KGlobal::dirs();
464 
465  appname = _appname;
466  if (appname.isEmpty())
467  appname = KGlobal::mainComponent().componentName();
468 
469  // Initialize icon cache
470  mIconCache = new KSharedDataCache("icon-cache", 10 * 1024 * 1024);
471  // Cost here is number of pixels, not size. So this is actually a bit
472  // smaller.
473  mPixmapCache.setMaxCost(10 * 1024 * 1024);
474 
475  // These have to match the order in kicontheme.h
476  static const char * const groups[] = { "Desktop", "Toolbar", "MainToolbar", "Small", "Panel", "Dialog", 0L };
477  KSharedConfig::Ptr config = KGlobal::config();
478 
479  // loading config and default sizes
480  initIconThemes();
481  KIconTheme *defaultSizesTheme = links.empty() ? 0 : links.first()->theme;
482  mpGroups = new KIconGroup[(int) KIconLoader::LastGroup];
483  for (KIconLoader::Group i = KIconLoader::FirstGroup; i < KIconLoader::LastGroup; ++i) {
484  if (groups[i] == 0L) {
485  break;
486  }
487 
488  KConfigGroup cg(config, QLatin1String(groups[i]) + "Icons");
489  mpGroups[i].size = cg.readEntry("Size", 0);
490  if (QPixmap::defaultDepth() > 8) {
491  mpGroups[i].alphaBlending = cg.readEntry("AlphaBlending", true);
492  } else {
493  mpGroups[i].alphaBlending = false;
494  }
495 
496  if (!mpGroups[i].size && defaultSizesTheme) {
497  mpGroups[i].size = defaultSizesTheme->defaultSize(i);
498  }
499  }
500 }
501 
502 bool KIconLoaderPrivate::initIconThemes()
503 {
504  if (mIconThemeInited) {
505  // If mpThemeRoot isn't 0 then initing has succeeded
506  return (mpThemeRoot != 0);
507  }
508  //kDebug(264);
509  mIconThemeInited = true;
510 
511  // Add the default theme and its base themes to the theme tree
512  KIconTheme *def = new KIconTheme(KIconTheme::current(), appname);
513  if (!def->isValid())
514  {
515  delete def;
516  // warn, as this is actually a small penalty hit
517  kDebug(264) << "Couldn't find current icon theme, falling back to default.";
518  def = new KIconTheme(KIconTheme::defaultThemeName(), appname);
519  if (!def->isValid())
520  {
521  kError(264) << "Error: standard icon theme" << KIconTheme::defaultThemeName() << "not found!" << endl;
522  delete def;
523  return false;
524  }
525  }
526  mpThemeRoot = new KIconThemeNode(def);
527  mThemesInTree.append(def->internalName());
528  links.append(mpThemeRoot);
529  addBaseThemes(mpThemeRoot, appname);
530 
531  // Insert application specific themes at the top.
532  mpDirs->addResourceType("appicon", "data", appname + "/pics/");
533  // ################## KDE5: consider removing the toolbar directory
534  mpDirs->addResourceType("appicon", "data", appname + "/toolbar/");
535 
536  // Add legacy icon dirs.
537  QStringList dirs;
538  dirs += mpDirs->resourceDirs("icon");
539  dirs += mpDirs->resourceDirs("pixmap");
540  dirs += mpDirs->resourceDirs("xdgdata-icon");
541  dirs += "/usr/share/pixmaps";
542  // These are not in the icon spec, but e.g. GNOME puts some icons there anyway.
543  dirs += mpDirs->resourceDirs("xdgdata-pixmap");
544  for (QStringList::ConstIterator it = dirs.constBegin(); it != dirs.constEnd(); ++it)
545  mpDirs->addResourceDir("appicon", *it);
546 
547 #ifndef NDEBUG
548  QString dbgString = "Theme tree: ";
549  mpThemeRoot->printTree(dbgString);
550  kDebug(264) << dbgString;
551 #endif
552 
553  return true;
554 }
555 
556 KIconLoader::~KIconLoader()
557 {
558  delete d;
559 }
560 
561 void KIconLoader::addAppDir(const QString& appname)
562 {
563  d->initIconThemes();
564 
565  d->mpDirs->addResourceType("appicon", "data", appname + "/pics/");
566  // ################## KDE5: consider removing the toolbar directory
567  d->mpDirs->addResourceType("appicon", "data", appname + "/toolbar/");
568  d->addAppThemes(appname);
569 }
570 
571 void KIconLoaderPrivate::addAppThemes(const QString& appname)
572 {
573  initIconThemes();
574 
575  KIconTheme *def = new KIconTheme(KIconTheme::current(), appname);
576  if (!def->isValid()) {
577  delete def;
578  def = new KIconTheme(KIconTheme::defaultThemeName(), appname);
579  }
580  KIconThemeNode* node = new KIconThemeNode(def);
581  bool addedToLinks = false;
582 
583  if (!mThemesInTree.contains(node->theme->internalName())) {
584  mThemesInTree.append(node->theme->internalName());
585  links.append(node);
586  addedToLinks = true;
587  }
588  addBaseThemes(node, appname);
589 
590  if (!addedToLinks) {
591  // Nodes in links are being deleted later - this one needs manual care.
592  delete node;
593  }
594 }
595 
596 void KIconLoaderPrivate::addBaseThemes(KIconThemeNode *node, const QString &appname)
597 {
598  // Quote from the icon theme specification:
599  // The lookup is done first in the current theme, and then recursively
600  // in each of the current theme's parents, and finally in the
601  // default theme called "hicolor" (implementations may add more
602  // default themes before "hicolor", but "hicolor" must be last).
603  //
604  // So we first make sure that all inherited themes are added, then we
605  // add the KDE default theme as fallback for all icons that might not be
606  // present in an inherited theme, and hicolor goes last.
607 
608  addInheritedThemes(node, appname);
609  addThemeByName(KIconTheme::defaultThemeName(), appname);
610  addThemeByName("hicolor", appname);
611 }
612 
613 void KIconLoaderPrivate::addInheritedThemes(KIconThemeNode *node, const QString &appname)
614 {
615  const QStringList lst = node->theme->inherits();
616 
617  for (QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it) {
618  if ((*it) == "hicolor") {
619  // The icon theme spec says that "hicolor" must be the very last
620  // of all inherited themes, so don't add it here but at the very end
621  // of addBaseThemes().
622  continue;
623  }
624  addThemeByName(*it, appname);
625  }
626 }
627 
628 void KIconLoaderPrivate::addThemeByName(const QString &themename, const QString &appname)
629 {
630  if (mThemesInTree.contains(themename + appname)) {
631  return;
632  }
633  KIconTheme *theme = new KIconTheme(themename, appname);
634  if (!theme->isValid()) {
635  delete theme;
636  return;
637  }
638  KIconThemeNode *n = new KIconThemeNode(theme);
639  mThemesInTree.append(themename + appname);
640  links.append(n);
641  addInheritedThemes(n, appname);
642 }
643 
644 void KIconLoader::addExtraDesktopThemes()
645 {
646  if ( d->extraDesktopIconsLoaded ) return;
647 
648  d->initIconThemes();
649 
650  QStringList list;
651  const QStringList icnlibs = KGlobal::dirs()->resourceDirs("icon");
652  QStringList::ConstIterator it;
653  char buf[1000];
654  int r;
655  for (it=icnlibs.begin(); it!=icnlibs.end(); ++it)
656  {
657  QDir dir(*it);
658  if (!dir.exists())
659  continue;
660  const QStringList lst = dir.entryList(QStringList( "default.*" ), QDir::Dirs);
661  QStringList::ConstIterator it2;
662  for (it2=lst.begin(); it2!=lst.end(); ++it2)
663  {
664  if (!KStandardDirs::exists(*it + *it2 + "/index.desktop")
665  && !KStandardDirs::exists(*it + *it2 + "/index.theme"))
666  continue;
667  r=readlink( QFile::encodeName(*it + *it2) , buf, sizeof(buf)-1);
668  if ( r>0 )
669  {
670  buf[r]=0;
671  const QDir dir2( buf );
672  QString themeName=dir2.dirName();
673 
674  if (!list.contains(themeName))
675  list.append(themeName);
676  }
677  }
678  }
679 
680  for (it = list.constBegin(); it != list.constEnd(); ++it)
681  {
682  // Don't add the KDE defaults once more, we have them anyways.
683  if (*it == QLatin1String("default.kde")
684  || *it == QLatin1String("default.kde4")) {
685  continue;
686  }
687  d->addThemeByName(*it, "");
688  }
689 
690  d->extraDesktopIconsLoaded=true;
691 
692 }
693 
694 bool KIconLoader::extraDesktopThemesAdded() const
695 {
696  return d->extraDesktopIconsLoaded;
697 }
698 
699 void KIconLoader::drawOverlays(const QStringList &overlays, QPixmap &pixmap, KIconLoader::Group group, int state) const
700 {
701  d->drawOverlays(this, group, state, pixmap, overlays);
702 }
703 
704 QString KIconLoaderPrivate::removeIconExtension(const QString &name) const
705 {
706  if (name.endsWith(QLatin1String(".png"))
707  || name.endsWith(QLatin1String(".xpm"))
708  || name.endsWith(QLatin1String(".svg"))) {
709  return name.left(name.length() - 4);
710  } else if (name.endsWith(QLatin1String(".svgz"))) {
711  return name.left(name.length() - 5);
712  }
713 
714  return name;
715 }
716 
717 void KIconLoaderPrivate::normalizeIconMetadata(KIconLoader::Group &group, int &size, int &state) const
718 {
719  if ((state < 0) || (state >= KIconLoader::LastState))
720  {
721  kWarning(264) << "Illegal icon state: " << state;
722  state = KIconLoader::DefaultState;
723  }
724 
725  if (size < 0) {
726  size = 0;
727  }
728 
729  // For "User" icons, bail early since the size should be based on the size on disk,
730  // which we've already checked.
731  if (group == KIconLoader::User) {
732  return;
733  }
734 
735  if ((group < -1) || (group >= KIconLoader::LastGroup))
736  {
737  kWarning(264) << "Illegal icon group: " << group;
738  group = KIconLoader::Desktop;
739  }
740 
741  // If size == 0, use default size for the specified group.
742  if (size == 0)
743  {
744  if (group < 0)
745  {
746  kWarning(264) << "Neither size nor group specified!";
747  group = KIconLoader::Desktop;
748  }
749  size = mpGroups[group].size;
750  }
751 }
752 
753 QString KIconLoaderPrivate::makeCacheKey(const QString &name, KIconLoader::Group group,
754  const QStringList &overlays, int size, int state) const
755 {
756  // The KSharedDataCache is shared so add some namespacing. The following code
757  // uses QStringBuilder (new in Qt 4.6)
758 
759  return (group == KIconLoader::User
760  ? QLatin1Literal("$kicou_")
761  : QLatin1Literal("$kico_"))
762  % name
763  % QLatin1Char('_')
764  % QString::number(size)
765  % QLatin1Char('_')
766  % overlays.join("_")
767  % ( group >= 0 ? mpEffect.fingerprint(group, state)
768  : *NULL_EFFECT_FINGERPRINT);
769 }
770 
771 QImage KIconLoaderPrivate::createIconImage(const QString &path, int size)
772 {
773  // Use the extension as the format. Works for XPM and PNG, but not for SVG. The
774  // "VGZ" is the last 3 characters of "SVGZ"
775  QString ext = path.right(3).toUpper();
776  QImage img;
777 
778  if (ext != "SVG" && ext != "VGZ")
779  {
780  // Not a SVG or SVGZ
781  img = QImage(path, ext.toLatin1());
782 
783  if (size != 0 && !img.isNull()) {
784  img = img.scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
785  }
786  }
787  else
788  {
789 #ifndef _WIN32_WCE
790  QSvgRenderer renderer(path, q);
791 
792  if (renderer.isValid()) {
793  img = QImage(size, size, QImage::Format_ARGB32_Premultiplied);
794  img.fill(0);
795  QPainter p(&img);
796  renderer.render(&p);
797  }
798 #endif
799  }
800 
801  return img;
802 }
803 
804 void KIconLoaderPrivate::insertCachedPixmapWithPath(
805  const QString &key,
806  const QPixmap &data,
807  const QString &path = QString())
808 {
809  // Even if the pixmap is null, we add it to the caches so that we record
810  // the fact that whatever icon led to us getting a null pixmap doesn't
811  // exist.
812 
813  QBuffer output;
814  output.open(QIODevice::WriteOnly);
815 
816  QDataStream outputStream(&output);
817  outputStream.setVersion(QDataStream::Qt_4_6);
818 
819  outputStream << path;
820 
821  // Convert the QPixmap to PNG. This is actually done by Qt's own operator.
822  outputStream << data;
823 
824  output.close();
825 
826  // The byte array contained in the QBuffer is what we want in the cache.
827  mIconCache->insert(key, output.buffer());
828 
829  // Also insert the object into our process-local cache for even more
830  // speed.
831  PixmapWithPath *pixmapPath = new PixmapWithPath;
832  pixmapPath->pixmap = data;
833  pixmapPath->path = path;
834 
835  mPixmapCache.insert(key, pixmapPath, data.width() * data.height() + 1);
836 }
837 
838 bool KIconLoaderPrivate::findCachedPixmapWithPath(const QString &key, QPixmap &data, QString &path)
839 {
840  // If the pixmap is present in our local process cache, use that since we
841  // don't need to decompress and upload it to the X server/graphics card.
842  const PixmapWithPath *pixmapPath = mPixmapCache.object(key);
843  if (pixmapPath) {
844  path = pixmapPath->path;
845  data = pixmapPath->pixmap;
846 
847  return true;
848  }
849 
850  // Otherwise try to find it in our shared memory cache since that will
851  // be quicker than the disk, especially for SVGs.
852  QByteArray result;
853 
854  if (!mIconCache->find(key, &result) || result.isEmpty()) {
855  return false;
856  }
857 
858  QBuffer buffer;
859  buffer.setBuffer(&result);
860  buffer.open(QIODevice::ReadOnly);
861 
862  QDataStream inputStream(&buffer);
863  inputStream.setVersion(QDataStream::Qt_4_6);
864 
865  QString tempPath;
866  inputStream >> tempPath;
867 
868  if (inputStream.status() == QDataStream::Ok) {
869  QPixmap tempPixmap;
870  inputStream >> tempPixmap;
871 
872  if (inputStream.status() == QDataStream::Ok) {
873  data = tempPixmap;
874  path = tempPath;
875 
876  // Since we're here we didn't have a QPixmap cache entry, add one now.
877  PixmapWithPath *newPixmapWithPath = new PixmapWithPath;
878  newPixmapWithPath->pixmap = data;
879  newPixmapWithPath->path = path;
880 
881  mPixmapCache.insert(key, newPixmapWithPath, data.width() * data.height() + 1);
882 
883  return true;
884  }
885  }
886 
887  return false;
888 }
889 
890 K3Icon KIconLoaderPrivate::findMatchingIconWithGenericFallbacks(const QString& name, int size) const
891 {
892  K3Icon icon = findMatchingIcon(name, size);
893  if (icon.isValid())
894  return icon;
895 
896  const QString genericIcon = s_globalData->genericIconFor(name);
897  if (!genericIcon.isEmpty()) {
898  icon = findMatchingIcon(genericIcon, size);
899  }
900  return icon;
901 }
902 
903 K3Icon KIconLoaderPrivate::findMatchingIcon(const QString& name, int size) const
904 {
905  const_cast<KIconLoaderPrivate*>(this)->initIconThemes();
906 
907  K3Icon icon;
908 
909  const char * const ext[4] = { ".png", ".svgz", ".svg", ".xpm" };
910  bool genericFallback = name.endsWith(QLatin1String("-x-generic"));
911 
912  // Do two passes through themeNodes.
913  //
914  // The first pass looks for an exact match in each themeNode one after the other.
915  // If one is found and it is an app icon then return that icon.
916  //
917  // In the next pass (assuming the first pass failed), it looks for exact matches
918  // and then generic fallbacks in each themeNode one after the other
919  //
920  // The reasoning is that application icons should always match exactly, all other
921  // icons may fallback. Since we do not know what the context is here when we start
922  // looking for it, we can only go by the path found.
923  foreach (KIconThemeNode *themeNode, links) {
924  for (int i = 0 ; i < 4 ; i++) {
925  icon = themeNode->theme->iconPath(name + ext[i], size, KIconLoader::MatchExact);
926  if (icon.isValid()) {
927  break;
928  }
929 
930  icon = themeNode->theme->iconPath(name + ext[i], size, KIconLoader::MatchBest);
931  if (icon.isValid()) {
932  break;
933  }
934  }
935 
936  if (icon.isValid() && icon.path.contains("/apps/")) {
937  return icon;
938  }
939  }
940 
941  foreach (KIconThemeNode *themeNode, links) {
942  QString currentName = name;
943 
944  while (!currentName.isEmpty()) {
945  //kDebug(264) << "Looking up" << currentName;
946 
947  for (int i = 0 ; i < 4 ; i++) {
948  icon = themeNode->theme->iconPath(currentName + ext[i], size, KIconLoader::MatchExact);
949  if (icon.isValid()) {
950  return icon;
951  }
952 
953  icon = themeNode->theme->iconPath(currentName + ext[i], size, KIconLoader::MatchBest);
954  if (icon.isValid()) {
955  return icon;
956  }
957  }
958  //kDebug(264) << "Looking up" << currentName;
959 
960  if (genericFallback) {
961  // we already tested the base name
962  break;
963  }
964 
965  int rindex = currentName.lastIndexOf('-');
966  if (rindex > 1) { // > 1 so that we don't split x-content or x-epoc
967  currentName.truncate(rindex);
968 
969  if (currentName.endsWith(QLatin1String("-x")))
970  currentName.chop(2);
971  } else {
972  // From update-mime-database.c
973  static const QSet<QString> mediaTypes = QSet<QString>()
974  << "text" << "application" << "image" << "audio"
975  << "inode" << "video" << "message" << "model" << "multipart"
976  << "x-content" << "x-epoc";
977  // Shared-mime-info spec says:
978  // "If [generic-icon] is not specified then the mimetype is used to generate the
979  // generic icon by using the top-level media type (e.g. "video" in "video/ogg")
980  // and appending "-x-generic" (i.e. "video-x-generic" in the previous example)."
981  if (mediaTypes.contains(currentName)) {
982  currentName += QLatin1String("-x-generic");
983  genericFallback = true;
984  } else {
985  break;
986  }
987  }
988  }
989  }
990  return icon;
991 }
992 
993 inline QString KIconLoaderPrivate::unknownIconPath( int size ) const
994 {
995  static const QString &str_unknown = KGlobal::staticQString("unknown");
996 
997  K3Icon icon = findMatchingIcon(str_unknown, size);
998  if (!icon.isValid())
999  {
1000  kDebug(264) << "Warning: could not find \"Unknown\" icon for size = "
1001  << size << endl;
1002  return QString();
1003  }
1004  return icon.path;
1005 }
1006 
1007 // Finds the absolute path to an icon.
1008 
1009 QString KIconLoader::iconPath(const QString& _name, int group_or_size,
1010  bool canReturnNull) const
1011 {
1012  if (!d->initIconThemes()) {
1013  return QString();
1014  }
1015 
1016  if (_name.isEmpty() || !pathIsRelative(_name))
1017  {
1018  // we have either an absolute path or nothing to work with
1019  return _name;
1020  }
1021 
1022  QString name = d->removeIconExtension( _name );
1023 
1024  QString path;
1025  if (group_or_size == KIconLoader::User)
1026  {
1027  static const QString &png_ext = KGlobal::staticQString(".png");
1028  static const QString &xpm_ext = KGlobal::staticQString(".xpm");
1029  path = d->mpDirs->findResource("appicon", name + png_ext);
1030 
1031  static const QString &svgz_ext = KGlobal::staticQString(".svgz");
1032  static const QString &svg_ext = KGlobal::staticQString(".svg");
1033  if (path.isEmpty())
1034  path = d->mpDirs->findResource("appicon", name + svgz_ext);
1035  if (path.isEmpty())
1036  path = d->mpDirs->findResource("appicon", name + svg_ext);
1037  if (path.isEmpty())
1038  path = d->mpDirs->findResource("appicon", name + xpm_ext);
1039  return path;
1040  }
1041 
1042  if (group_or_size >= KIconLoader::LastGroup)
1043  {
1044  kDebug(264) << "Illegal icon group: " << group_or_size;
1045  return path;
1046  }
1047 
1048  int size;
1049  if (group_or_size >= 0)
1050  size = d->mpGroups[group_or_size].size;
1051  else
1052  size = -group_or_size;
1053 
1054  if (_name.isEmpty()) {
1055  if (canReturnNull)
1056  return QString();
1057  else
1058  return d->unknownIconPath(size);
1059  }
1060 
1061  K3Icon icon = d->findMatchingIconWithGenericFallbacks(name, size);
1062 
1063  if (!icon.isValid())
1064  {
1065  // Try "User" group too.
1066  path = iconPath(name, KIconLoader::User, true);
1067  if (!path.isEmpty() || canReturnNull)
1068  return path;
1069 
1070  return d->unknownIconPath(size);
1071  }
1072  return icon.path;
1073 }
1074 
1075 QPixmap KIconLoader::loadMimeTypeIcon( const QString& _iconName, KIconLoader::Group group, int size,
1076  int state, const QStringList& overlays, QString *path_store ) const
1077 {
1078  QString iconName = _iconName;
1079  const int slashindex = iconName.indexOf(QLatin1Char('/'));
1080  if (slashindex != -1) {
1081  iconName[slashindex] = QLatin1Char('-');
1082  }
1083 
1084  if ( !d->extraDesktopIconsLoaded )
1085  {
1086  const QPixmap pixmap = loadIcon( iconName, group, size, state, overlays, path_store, true );
1087  if (!pixmap.isNull() ) {
1088  return pixmap;
1089  }
1090  const_cast<KIconLoader *>(this)->addExtraDesktopThemes();
1091  }
1092  const QPixmap pixmap = loadIcon(iconName, group, size, state, overlays, path_store, true);
1093  if (pixmap.isNull()) {
1094  // Icon not found, fallback to application/octet-stream
1095  return loadIcon("application-octet-stream", group, size, state, overlays, path_store, false);
1096  }
1097  return pixmap;
1098 }
1099 
1100 QPixmap KIconLoader::loadIcon(const QString& _name, KIconLoader::Group group, int size,
1101  int state, const QStringList& overlays,
1102  QString *path_store, bool canReturnNull) const
1103 {
1104  QString name = _name;
1105  bool favIconOverlay = false;
1106 
1107  if (size < 0 || _name.isEmpty())
1108  return QPixmap();
1109 
1110  /*
1111  * This method works in a kind of pipeline, with the following steps:
1112  * 1. Sanity checks.
1113  * 2. Convert _name, group, size, etc. to a key name.
1114  * 3. Check if the key is already cached.
1115  * 4. If not, initialize the theme and find/load the icon.
1116  * 4a Apply overlays
1117  * 4b Re-add to cache.
1118  */
1119 
1120  // Special case for absolute path icons.
1121  if (name.startsWith(QLatin1String("favicons/")))
1122  {
1123  favIconOverlay = true;
1124  name = KStandardDirs::locateLocal("cache", name+".png");
1125  }
1126 
1127  bool absolutePath = !pathIsRelative(name);
1128  if (!absolutePath) {
1129  name = d->removeIconExtension(name);
1130  }
1131 
1132  // Don't bother looking for an icon with no name.
1133  if (name.isEmpty()) {
1134  return QPixmap();
1135  }
1136 
1137  // May modify group, size, or state. This function puts them into sane
1138  // states.
1139  d->normalizeIconMetadata(group, size, state);
1140 
1141  // See if the image is already cached.
1142  QString key = d->makeCacheKey(name, group, overlays, size, state);
1143  QPixmap pix;
1144  bool iconWasUnknown = false;
1145  K3Icon icon;
1146 
1147  // icon.path would be empty for "unknown" icons, which should be searched for
1148  // anew each time.
1149  if (d->findCachedPixmapWithPath(key, pix, icon.path) && !icon.path.isEmpty()) {
1150  if (path_store) {
1151  *path_store = icon.path;
1152  }
1153 
1154  return pix;
1155  }
1156 
1157  // Image is not cached... go find it and apply effects.
1158  if (!d->initIconThemes()) {
1159  return QPixmap();
1160  }
1161 
1162  favIconOverlay = favIconOverlay && size > 22;
1163 
1164  // First we look for non-User icons. If we don't find one we'd search in
1165  // the User space anyways...
1166  if (group != KIconLoader::User) {
1167  // K3Icon seems to hold some needed information.
1168 
1169  if (absolutePath && !favIconOverlay)
1170  {
1171  icon.context = KIconLoader::Any;
1172  icon.type = KIconLoader::Scalable;
1173  icon.path = name;
1174  }
1175  else
1176  {
1177  icon = d->findMatchingIconWithGenericFallbacks(favIconOverlay ? QString("text-html") : name, size);
1178  }
1179  }
1180 
1181  if (icon.path.isEmpty()) {
1182  // We do have a "User" icon, or we couldn't find the non-User one.
1183  icon.path = (absolutePath) ? name :
1184  iconPath(name, KIconLoader::User, canReturnNull);
1185  }
1186 
1187  // Still can't find it? Use "unknown" if we can't return null.
1188  // We keep going in the function so we can ensure this result gets cached.
1189  if (icon.path.isEmpty() && !canReturnNull) {
1190  icon.path = d->unknownIconPath(size);
1191  iconWasUnknown = true;
1192  }
1193 
1194  QImage img = d->createIconImage(icon.path, size);
1195 
1196  if (group >= 0)
1197  {
1198  img = d->mpEffect.apply(img, group, state);
1199  }
1200 
1201  if (favIconOverlay)
1202  {
1203  QImage favIcon(name, "PNG");
1204  if (!favIcon.isNull()) // if favIcon not there yet, don't try to blend it
1205  {
1206  QPainter p(&img);
1207 
1208  // Align the favicon overlay
1209  QRect r(favIcon.rect());
1210  r.moveBottomRight(img.rect().bottomRight());
1211  r.adjust(-1, -1, -1, -1); // Move off edge
1212 
1213  // Blend favIcon over img.
1214  p.drawImage(r, favIcon);
1215  }
1216  }
1217 
1218  pix = QPixmap::fromImage(img);
1219 
1220  // TODO: If we make a loadIcon that returns the image we can convert
1221  // drawOverlays to use the image instead of pixmaps as well so we don't
1222  // have to transfer so much to the graphics card.
1223  d->drawOverlays(this, group, state, pix, overlays);
1224 
1225  // Don't add the path to our unknown icon to the cache, only cache the
1226  // actual image.
1227  if (iconWasUnknown) {
1228  icon.path.clear();
1229  }
1230 
1231  d->insertCachedPixmapWithPath(key, pix, icon.path);
1232 
1233  if (path_store) {
1234  *path_store = icon.path;
1235  }
1236 
1237  return pix;
1238 }
1239 
1240 QMovie *KIconLoader::loadMovie(const QString& name, KIconLoader::Group group, int size, QObject *parent) const
1241 {
1242  QString file = moviePath( name, group, size );
1243  if (file.isEmpty())
1244  return 0;
1245  int dirLen = file.lastIndexOf('/');
1246  QString icon = iconPath(name, size ? -size : group, true);
1247  if (!icon.isEmpty() && file.left(dirLen) != icon.left(dirLen))
1248  return 0;
1249  QMovie *movie = new QMovie(file, QByteArray(), parent);
1250  if (!movie->isValid())
1251  {
1252  delete movie;
1253  return 0;
1254  }
1255  return movie;
1256 }
1257 
1258 QString KIconLoader::moviePath(const QString& name, KIconLoader::Group group, int size) const
1259 {
1260  if (!d->mpGroups) return QString();
1261 
1262  d->initIconThemes();
1263 
1264  if ( (group < -1 || group >= KIconLoader::LastGroup) && group != KIconLoader::User )
1265  {
1266  kDebug(264) << "Illegal icon group: " << group;
1267  group = KIconLoader::Desktop;
1268  }
1269  if (size == 0 && group < 0)
1270  {
1271  kDebug(264) << "Neither size nor group specified!";
1272  group = KIconLoader::Desktop;
1273  }
1274 
1275  QString file = name + ".mng";
1276  if (group == KIconLoader::User)
1277  {
1278  file = d->mpDirs->findResource("appicon", file);
1279  }
1280  else
1281  {
1282  if (size == 0)
1283  size = d->mpGroups[group].size;
1284 
1285  K3Icon icon;
1286 
1287  foreach(KIconThemeNode *themeNode, d->links)
1288  {
1289  icon = themeNode->theme->iconPath(file, size, KIconLoader::MatchExact);
1290  if (icon.isValid())
1291  break;
1292  }
1293 
1294  if ( !icon.isValid() )
1295  {
1296  foreach(KIconThemeNode *themeNode, d->links)
1297  {
1298  icon = themeNode->theme->iconPath(file, size, KIconLoader::MatchBest);
1299  if (icon.isValid())
1300  break;
1301  }
1302  }
1303 
1304  file = icon.isValid() ? icon.path : QString();
1305  }
1306  return file;
1307 }
1308 
1309 
1310 QStringList KIconLoader::loadAnimated(const QString& name, KIconLoader::Group group, int size) const
1311 {
1312  QStringList lst;
1313 
1314  if (!d->mpGroups) return lst;
1315 
1316  d->initIconThemes();
1317 
1318  if ((group < -1) || (group >= KIconLoader::LastGroup))
1319  {
1320  kDebug(264) << "Illegal icon group: " << group;
1321  group = KIconLoader::Desktop;
1322  }
1323  if ((size == 0) && (group < 0))
1324  {
1325  kDebug(264) << "Neither size nor group specified!";
1326  group = KIconLoader::Desktop;
1327  }
1328 
1329  QString file = name + "/0001";
1330  if (group == KIconLoader::User)
1331  {
1332  file = d->mpDirs->findResource("appicon", file + ".png");
1333  } else
1334  {
1335  if (size == 0)
1336  size = d->mpGroups[group].size;
1337  K3Icon icon = d->findMatchingIcon(file, size);
1338  file = icon.isValid() ? icon.path : QString();
1339 
1340  }
1341  if (file.isEmpty())
1342  return lst;
1343 
1344  QString path = file.left(file.length()-8);
1345  DIR* dp = opendir( QFile::encodeName(path) );
1346  if(!dp)
1347  return lst;
1348 
1349  KDE_struct_dirent* ep;
1350  while( ( ep = KDE_readdir( dp ) ) != 0L )
1351  {
1352  QString fn(QFile::decodeName(ep->d_name));
1353  if(!(fn.left(4)).toUInt())
1354  continue;
1355 
1356  lst += path + fn;
1357  }
1358  closedir ( dp );
1359  lst.sort();
1360  return lst;
1361 }
1362 
1363 KIconTheme *KIconLoader::theme() const
1364 {
1365  d->initIconThemes();
1366  if (d->mpThemeRoot) return d->mpThemeRoot->theme;
1367  return 0L;
1368 }
1369 
1370 int KIconLoader::currentSize(KIconLoader::Group group) const
1371 {
1372  if (!d->mpGroups) return -1;
1373 
1374  if (group < 0 || group >= KIconLoader::LastGroup)
1375  {
1376  kDebug(264) << "Illegal icon group: " << group;
1377  return -1;
1378  }
1379  return d->mpGroups[group].size;
1380 }
1381 
1382 QStringList KIconLoader::queryIconsByDir( const QString& iconsDir ) const
1383 {
1384  const QDir dir(iconsDir);
1385  const QStringList formats = QStringList() << "*.png" << "*.xpm" << "*.svg" << "*.svgz";
1386  const QStringList lst = dir.entryList(formats, QDir::Files);
1387  QStringList result;
1388  QStringList::ConstIterator it;
1389  for (it=lst.begin(); it!=lst.end(); ++it)
1390  result += iconsDir + '/' + *it;
1391  return result;
1392 }
1393 
1394 QStringList KIconLoader::queryIconsByContext(int group_or_size,
1395  KIconLoader::Context context) const
1396 {
1397  d->initIconThemes();
1398 
1399  QStringList result;
1400  if (group_or_size >= KIconLoader::LastGroup)
1401  {
1402  kDebug(264) << "Illegal icon group: " << group_or_size;
1403  return result;
1404  }
1405  int size;
1406  if (group_or_size >= 0)
1407  size = d->mpGroups[group_or_size].size;
1408  else
1409  size = -group_or_size;
1410 
1411  foreach(KIconThemeNode *themeNode, d->links)
1412  themeNode->queryIconsByContext(&result, size, context);
1413 
1414  // Eliminate duplicate entries (same icon in different directories)
1415  QString name;
1416  QStringList res2, entries;
1417  QStringList::ConstIterator it;
1418  for (it=result.constBegin(); it!=result.constEnd(); ++it)
1419  {
1420  int n = (*it).lastIndexOf('/');
1421  if (n == -1)
1422  name = *it;
1423  else
1424  name = (*it).mid(n+1);
1425  name = d->removeIconExtension(name);
1426  if (!entries.contains(name))
1427  {
1428  entries += name;
1429  res2 += *it;
1430  }
1431  }
1432  return res2;
1433 
1434 }
1435 
1436 QStringList KIconLoader::queryIcons(int group_or_size, KIconLoader::Context context) const
1437 {
1438  d->initIconThemes();
1439 
1440  QStringList result;
1441  if (group_or_size >= KIconLoader::LastGroup)
1442  {
1443  kDebug(264) << "Illegal icon group: " << group_or_size;
1444  return result;
1445  }
1446  int size;
1447  if (group_or_size >= 0)
1448  size = d->mpGroups[group_or_size].size;
1449  else
1450  size = -group_or_size;
1451 
1452  foreach(KIconThemeNode *themeNode, d->links)
1453  themeNode->queryIcons(&result, size, context);
1454 
1455  // Eliminate duplicate entries (same icon in different directories)
1456  QString name;
1457  QStringList res2, entries;
1458  QStringList::ConstIterator it;
1459  for (it=result.constBegin(); it!=result.constEnd(); ++it)
1460  {
1461  int n = (*it).lastIndexOf('/');
1462  if (n == -1)
1463  name = *it;
1464  else
1465  name = (*it).mid(n+1);
1466  name = d->removeIconExtension(name);
1467  if (!entries.contains(name))
1468  {
1469  entries += name;
1470  res2 += *it;
1471  }
1472  }
1473  return res2;
1474 }
1475 
1476 // used by KIconDialog to find out which contexts to offer in a combobox
1477 bool KIconLoader::hasContext(KIconLoader::Context context) const
1478 {
1479  d->initIconThemes();
1480 
1481  foreach(KIconThemeNode *themeNode, d->links)
1482  if( themeNode->theme->hasContext( context ))
1483  return true;
1484  return false;
1485 }
1486 
1487 KIconEffect * KIconLoader::iconEffect() const
1488 {
1489  return &d->mpEffect;
1490 }
1491 
1492 bool KIconLoader::alphaBlending(KIconLoader::Group group) const
1493 {
1494  if (!d->mpGroups) return false;
1495 
1496  if (group < 0 || group >= KIconLoader::LastGroup)
1497  {
1498  kDebug(264) << "Illegal icon group: " << group;
1499  return false;
1500  }
1501  return d->mpGroups[group].alphaBlending;
1502 }
1503 
1504 // deprecated
1505 #ifndef KDE_NO_DEPRECATED
1506 QIcon KIconLoader::loadIconSet( const QString& name, KIconLoader::Group g, int s,
1507  bool canReturnNull )
1508 {
1509  QIcon iconset;
1510  QPixmap tmp = loadIcon(name, g, s, KIconLoader::ActiveState, QStringList(), NULL, canReturnNull);
1511  iconset.addPixmap( tmp, QIcon::Active, QIcon::On );
1512  // we don't use QIconSet's resizing anyway
1513  tmp = loadIcon(name, g, s, KIconLoader::DisabledState, QStringList(), NULL, canReturnNull);
1514  iconset.addPixmap( tmp, QIcon::Disabled, QIcon::On );
1515  tmp = loadIcon(name, g, s, KIconLoader::DefaultState, QStringList(), NULL, canReturnNull);
1516  iconset.addPixmap( tmp, QIcon::Normal, QIcon::On );
1517  return iconset;
1518 }
1519 #endif
1520 
1521 // Easy access functions
1522 
1523 QPixmap DesktopIcon(const QString& name, int force_size, int state, const QStringList &overlays)
1524 {
1525  KIconLoader *loader = KIconLoader::global();
1526  return loader->loadIcon(name, KIconLoader::Desktop, force_size, state, overlays);
1527 }
1528 
1529 // deprecated
1530 #ifndef KDE_NO_DEPRECATED
1531 QIcon DesktopIconSet(const QString& name, int force_size)
1532 {
1533  KIconLoader *loader = KIconLoader::global();
1534  return loader->loadIconSet(name, KIconLoader::Desktop, force_size);
1535 }
1536 #endif
1537 
1538 QPixmap BarIcon(const QString& name, int force_size, int state, const QStringList &overlays)
1539 {
1540  KIconLoader *loader = KIconLoader::global();
1541  return loader->loadIcon(name, KIconLoader::Toolbar, force_size, state, overlays);
1542 }
1543 
1544 // deprecated
1545 #ifndef KDE_NO_DEPRECATED
1546 QIcon BarIconSet(const QString& name, int force_size)
1547 {
1548  KIconLoader *loader = KIconLoader::global();
1549  return loader->loadIconSet( name, KIconLoader::Toolbar, force_size );
1550 }
1551 #endif
1552 
1553 QPixmap SmallIcon(const QString& name, int force_size, int state, const QStringList &overlays)
1554 {
1555  KIconLoader *loader = KIconLoader::global();
1556  return loader->loadIcon(name, KIconLoader::Small, force_size, state, overlays);
1557 }
1558 
1559 // deprecated
1560 #ifndef KDE_NO_DEPRECATED
1561 QIcon SmallIconSet(const QString& name, int force_size)
1562 {
1563  KIconLoader *loader = KIconLoader::global();
1564  return loader->loadIconSet( name, KIconLoader::Small, force_size );
1565 }
1566 #endif
1567 
1568 QPixmap MainBarIcon(const QString& name, int force_size, int state, const QStringList &overlays)
1569 {
1570  KIconLoader *loader = KIconLoader::global();
1571  return loader->loadIcon(name, KIconLoader::MainToolbar, force_size, state, overlays);
1572 }
1573 
1574 // deprecated
1575 #ifndef KDE_NO_DEPRECATED
1576 QIcon MainBarIconSet(const QString& name, int force_size)
1577 {
1578  KIconLoader *loader = KIconLoader::global();
1579  return loader->loadIconSet( name, KIconLoader::MainToolbar, force_size );
1580 }
1581 #endif
1582 
1583 QPixmap UserIcon(const QString& name, int state, const QStringList &overlays)
1584 {
1585  KIconLoader *loader = KIconLoader::global();
1586  return loader->loadIcon(name, KIconLoader::User, 0, state, overlays);
1587 }
1588 
1589 // deprecated
1590 #ifndef KDE_NO_DEPRECATED
1591 QIcon UserIconSet(const QString& name)
1592 {
1593  KIconLoader *loader = KIconLoader::global();
1594  return loader->loadIconSet( name, KIconLoader::User );
1595 }
1596 #endif
1597 
1598 int IconSize(KIconLoader::Group group)
1599 {
1600  KIconLoader *loader = KIconLoader::global();
1601  return loader->currentSize(group);
1602 }
1603 
1604 QPixmap KIconLoader::unknown()
1605 {
1606  QPixmap pix;
1607  if ( QPixmapCache::find("unknown", pix) ) //krazy:exclude=iconnames
1608  return pix;
1609 
1610  QString path = global()->iconPath("unknown", KIconLoader::Small, true); //krazy:exclude=iconnames
1611  if (path.isEmpty())
1612  {
1613  kDebug(264) << "Warning: Cannot find \"unknown\" icon.";
1614  pix = QPixmap(32,32);
1615  } else
1616  {
1617  pix.load(path);
1618  QPixmapCache::insert("unknown", pix); //krazy:exclude=iconnames
1619  }
1620 
1621  return pix;
1622 }
1623 
1624 /*** the global icon loader ***/
1625 K_GLOBAL_STATIC_WITH_ARGS(KIconLoader, globalIconLoader, (KGlobal::mainComponent(), 0))
1626 
1627 KIconLoader *KIconLoader::global()
1628 {
1629  return globalIconLoader;
1630 }
1631 
1632 void KIconLoader::newIconLoader()
1633 {
1634  if ( global() == this) {
1635  KIconTheme::reconfigure();
1636  }
1637 
1638  reconfigure( objectName(), d->mpDirs );
1639  emit iconLoaderSettingsChanged();
1640 }
1641 
1642 #include "kiconloader.moc"
1643 
KIconTheme::reconfigure
static void reconfigure()
Reconfigure the theme.
Definition: kicontheme.cpp:587
KIconLoader::DefaultState
The default state.
Definition: kiconloader.h:172
KIconLoader::loadAnimated
QStringList loadAnimated(const QString &name, KIconLoader::Group group, int size=0) const
Loads an animated icon as a series of still frames.
Definition: kiconloader.cpp:1310
KIconTheme::defaultSize
int defaultSize(KIconLoader::Group group) const
The default size of this theme for a certain icon group.
Definition: kicontheme.cpp:321
KIconLoader::newIconLoader
void newIconLoader()
Re-initialize the global icon loader.
Definition: kiconloader.cpp:1632
KSharedPtr< KSharedConfig >
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
KIconLoader::IconSize
int IconSize(KIconLoader::Group group)
Definition: kiconloader.cpp:1598
KIconLoader::addExtraDesktopThemes
void addExtraDesktopThemes()
Adds all the default themes from other desktops at the end of the list of icon themes.
Definition: kiconloader.cpp:644
KIconLoader::currentSize
int currentSize(KIconLoader::Group group) const
Returns the current size of the icon group.
Definition: kiconloader.cpp:1370
QString::toUpper
QString toUpper() const
KIconLoader::loadMovie
QMovie * loadMovie(const QString &name, KIconLoader::Group group, int size=0, QObject *parent=0) const
Loads an animated icon.
Definition: kiconloader.cpp:1240
KIconLoader::addAppDir
void addAppDir(const QString &appname)
Adds appname to the list of application specific directories.
Definition: kiconloader.cpp:561
QString::truncate
void truncate(int position)
QRect::moveBottomRight
void moveBottomRight(const QPoint &position)
KIconLoader::MainBarIcon
QPixmap MainBarIcon(const QString &name, int size=0, int state=KIconLoader::DefaultState, const QStringList &overlays=QStringList())
Definition: kiconloader.cpp:1568
QPixmap::width
int width() const
kdebug.h
KIconLoader::hasContext
bool hasContext(KIconLoader::Context context) const
Definition: kiconloader.cpp:1477
QByteArray
KIconLoader::global
static KIconLoader * global()
Returns the global icon loader initialized with the global KComponentData.
kglobalsettings.h
KIconTheme::isValid
bool isValid() const
The icon theme exists?
Definition: kicontheme.cpp:306
QDataStream
QChar
K_GLOBAL_STATIC
#define K_GLOBAL_STATIC(TYPE, NAME)
KIconLoader::Scalable
Scalable-size icon.
Definition: kiconloader.h:112
kconfig.h
QMovie::isValid
bool isValid() const
QSvgRenderer
QMovie
QRect::bottomRight
QPoint bottomRight() const
KGlobal::dirs
KStandardDirs * dirs()
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
QByteArray::isEmpty
bool isEmpty() const
KStandardAction::name
const char * name(StandardAction id)
This will return the internal name of a given standard action.
Definition: kstandardaction.cpp:223
kError
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
QPixmap::fromImage
QPixmap fromImage(const QImage &image, QFlags< Qt::ImageConversionFlag > flags)
QBuffer
kiconloader.h
QPoint
QStringList::join
QString join(const QString &separator) const
QImage::isNull
bool isNull() const
KIconLoader::alphaBlending
bool alphaBlending(KIconLoader::Group group) const
Checks whether the user wants to blend the icons with the background using the alpha channel informat...
Definition: kiconloader.cpp:1492
KGlobalSettings::self
static KGlobalSettings * self()
Return the KGlobalSettings singleton.
Definition: kglobalsettings.cpp:188
KIconLoader::moviePath
QString moviePath(const QString &name, KIconLoader::Group group, int size=0) const
Returns the path to an animated icon.
Definition: kiconloader.cpp:1258
kDebug
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
QString::chop
void chop(int n)
KStandardDirs::exists
static bool exists(const QString &fullPath)
KIconLoader::queryIcons
QStringList queryIcons(int group_or_size, KIconLoader::Context context=KIconLoader::Any) const
Queries all available icons for a specific group, having a specific context.
Definition: kiconloader.cpp:1436
KIconLoader::Desktop
Desktop icons.
Definition: kiconloader.h:131
KIconLoader::UserIconSet
QIcon UserIconSet(const QString &name)
Definition: kiconloader.cpp:1591
QBuffer::buffer
QByteArray & buffer()
QFile
QTextStream
config
KSharedConfigPtr config()
QString::lastIndexOf
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
KIconLoader::queryIconsByContext
QStringList queryIconsByContext(int group_or_size, KIconLoader::Context context=KIconLoader::Any) const
Queries all available icons for a specific context.
Definition: kiconloader.cpp:1394
KIconLoader::SmallIcon
QPixmap SmallIcon(const QString &name, int size=0, int state=KIconLoader::DefaultState, const QStringList &overlays=QStringList())
Definition: kiconloader.cpp:1553
KStandardGuiItem::Ok
Definition: kstandardguiitem.h:50
KIconLoader::Any
Some icon with unknown purpose.
Definition: kiconloader.h:92
QObject::name
const char * name() const
QRect
KIconLoader::DisabledState
Icon is disabled.
Definition: kiconloader.h:174
kglobal.h
KIconLoader::loadIcon
QPixmap loadIcon(const QString &name, KIconLoader::Group group, int size=0, int state=KIconLoader::DefaultState, const QStringList &overlays=QStringList(), QString *path_store=0L, bool canReturnNull=false) const
Loads an icon.
Definition: kiconloader.cpp:1100
QString::number
QString number(int n, int base)
QDir::exists
bool exists() const
QList::append
void append(const T &value)
QString::insert
QString & insert(int position, QChar ch)
QImage::fill
void fill(uint pixelValue)
KIconLoader::Small
Small icons, e.g. for buttons.
Definition: kiconloader.h:139
QHash< QString, QString >
KIconLoader::ActiveState
Icon is active.
Definition: kiconloader.h:173
output
void output(QList< Action > actions, QHash< QString, QString > domain)
QObject
KIconLoader::LastGroup
Last group.
Definition: kiconloader.h:145
KStandardDirs
QPainter
QObject::setObjectName
void setObjectName(const QString &name)
QString::isEmpty
bool isEmpty() const
QImage::rect
QRect rect() const
KIconLoader::MatchBest
Take the best match if there is no exact match.
Definition: kiconloader.h:121
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
KIconLoader::loadMimeTypeIcon
QPixmap loadMimeTypeIcon(const QString &iconName, KIconLoader::Group group, int size=0, int state=KIconLoader::DefaultState, const QStringList &overlays=QStringList(), QString *path_store=0) const
Loads an icon for a mimetype.
Definition: kiconloader.cpp:1075
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
KSharedDataCache
QBuffer::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > flags)
QIcon::addPixmap
void addPixmap(const QPixmap &pixmap, Mode mode, State state)
QSet< QString >
KIconLoader::SmallIconSet
QIcon SmallIconSet(const QString &name, int size=0)
Definition: kiconloader.cpp:1561
KComponentData::componentName
QString componentName() const
QString
QList< KIconThemeNode * >
K_GLOBAL_STATIC_WITH_ARGS
K_GLOBAL_STATIC_WITH_ARGS(QString, NULL_EFFECT_FINGERPRINT,(QString::fromLatin1("noeffect"))) static bool pathIsRelative(const QString &path)
Checks for relative paths quickly on UNIX-alikes, slowly on everything else.
Definition: kiconloader.cpp:67
QPixmap::load
bool load(const QString &fileName, const char *format, QFlags< Qt::ImageConversionFlag > flags)
KIconLoader::theme
KIconTheme * theme() const
Returns a pointer to the current theme.
Definition: kiconloader.cpp:1363
QStringList
QCache< QString, PixmapWithPath >
KIconLoader::iconEffect
KIconEffect * iconEffect() const
Returns a pointer to the KIconEffect object used by the icon loader.
Definition: kiconloader.cpp:1487
QString::right
QString right(int n) const
QPixmap
QList::end
iterator end()
kshareddatacache.h
QPixmap::isNull
bool isNull() const
QLatin1Char
QPixmap::height
int height() const
KIconLoader::DesktopIcon
QPixmap DesktopIcon(const QString &name, int size=0, int state=KIconLoader::DefaultState, const QStringList &overlays=QStringList())
Definition: kiconloader.cpp:1523
KIconLoader::extraDesktopThemesAdded
bool extraDesktopThemesAdded() const
Returns if the default icon themes of other desktops have been added to the list of icon themes where...
Definition: kiconloader.cpp:694
KIconLoader::MainToolbar
Main toolbar icons.
Definition: kiconloader.h:137
KStandardDirs::resourceDirs
QStringList resourceDirs(const char *type) const
QDir::isRelativePath
bool isRelativePath(const QString &path)
KIconLoader::UserIcon
QPixmap UserIcon(const QString &name, int state=KIconLoader::DefaultState, const QStringList &overlays=QStringList())
Definition: kiconloader.cpp:1583
KIconLoader::BarIconSet
QIcon BarIconSet(const QString &name, int size=0)
Definition: kiconloader.cpp:1546
QImage
KIconLoader::MatchType
MatchType
The type of a match.
Definition: kiconloader.h:119
KIconLoader::MainBarIconSet
QIcon MainBarIconSet(const QString &name, int size=0)
Definition: kiconloader.cpp:1576
QSet::contains
bool contains(const T &value) const
kicontheme.h
QDir
KConfigGroup
QBuffer::close
virtual void close()
KIconLoader::Toolbar
Toolbar icons.
Definition: kiconloader.h:135
QString::toLatin1
QByteArray toLatin1() const
QPainter::drawImage
void drawImage(const QRectF &target, const QImage &image, const QRectF &source, QFlags< Qt::ImageConversionFlag > flags)
QString::mid
QString mid(int position, int n) const
QDir::dirName
QString dirName() const
QLatin1String
KIconLoader::LastState
Last state (last constant)
Definition: kiconloader.h:175
KStandardDirs::locateLocal
static QString locateLocal(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
kstandarddirs.h
KIconLoader::iconLoaderSettingsChanged
void iconLoaderSettingsChanged()
Emitted by newIconLoader once the new settings have been loaded.
QDir::entryList
QStringList entryList(QFlags< QDir::Filter > filters, QFlags< QDir::SortFlag > sort) const
KIconLoader::Context
Context
Defines the context of the icon.
Definition: kiconloader.h:91
KIconLoader::MatchExact
Only try to find an exact match.
Definition: kiconloader.h:120
KIconLoader::Group
Group
The group of the icon.
Definition: kiconloader.h:127
QList::ConstIterator
typedef ConstIterator
QPixmapCache::find
QPixmap * find(const QString &key)
KIconLoader::reconfigure
void reconfigure(const QString &_appname, KStandardDirs *_dirs)
Called by KComponentData::newIconLoader to reconfigure the icon loader.
Definition: kiconloader.cpp:446
KGlobal::mainComponent
const KComponentData & mainComponent()
QBuffer::setBuffer
void setBuffer(QByteArray *byteArray)
KIconLoader::KIconLoader
KIconLoader(const QString &appname=QString(), KStandardDirs *dirs=0, QObject *parent=0)
Constructs an iconloader.
Definition: kiconloader.cpp:424
KIconTheme::defaultThemeName
static QString defaultThemeName()
Returns the default icon theme.
Definition: kicontheme.cpp:594
QString::length
int length() const
KIconLoader::loadIconSet
QIcon loadIconSet(const QString &name, KIconLoader::Group group, int size=0, bool canReturnNull=false)
Creates an icon set, that will do on-demand loading of the icon.
Definition: kiconloader.cpp:1506
kWarning
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KIconLoader::User
User icons.
Definition: kiconloader.h:147
QString::left
QString left(int n) const
QString::fromLatin1
QString fromLatin1(const char *str, int size)
KIconLoader::FirstGroup
First group.
Definition: kiconloader.h:133
QStringList::sort
void sort()
KIconLoader::drawOverlays
void drawOverlays(const QStringList &overlays, QPixmap &pixmap, KIconLoader::Group group, int state=KIconLoader::DefaultState) const
Draws overlays on the specified pixmap, it takes the width and height of the pixmap into consideratio...
Definition: kiconloader.cpp:699
KGlobal::staticQString
const QString & staticQString(const char *str)
KStandardDirs::findAllResources
QStringList findAllResources(const char *type, const QString &filter=QString(), SearchOptions options=NoSearchOptions) const
KIconLoader::queryIconsByDir
QStringList queryIconsByDir(const QString &iconsDir) const
Returns a list of all icons (*.png or *.xpm extension) in the given directory.
Definition: kiconloader.cpp:1382
QList::constEnd
const_iterator constEnd() const
QList::constBegin
const_iterator constBegin() const
kcomponentdata.h
QPixmapCache::insert
bool insert(const QString &key, const QPixmap &pixmap)
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KIconEffect
Applies effects to icons.
Definition: kiconeffect.h:47
QPixmap::defaultDepth
int defaultDepth()
KIconLoader::unknown
static QPixmap unknown()
Returns the unknown icon.
Definition: kiconloader.cpp:1604
KIconTheme
Definition: kicontheme.h:46
QList::begin
iterator begin()
KComponentData
QImage::scaled
QImage scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const
QFile::encodeName
QByteArray encodeName(const QString &fileName)
QFile::decodeName
QString decodeName(const QByteArray &localFileName)
kconfiggroup.h
KIconTheme::current
static QString current()
Returns the current icon theme.
Definition: kicontheme.cpp:522
KIconLoader::DesktopIconSet
QIcon DesktopIconSet(const QString &name, int size=0)
Definition: kiconloader.cpp:1531
QIcon
KIconTheme::internalName
QString internalName() const
The internal name of the icon theme (same as the name argument passed to the constructor).
Definition: kicontheme.cpp:276
KIconLoader
Iconloader for KDE.
Definition: kiconloader.h:77
KIconLoader::~KIconLoader
~KIconLoader()
Cleanup.
Definition: kiconloader.cpp:556
kiconeffect.h
KIconLoader::BarIcon
QPixmap BarIcon(const QString &name, int size=0, int state=KIconLoader::DefaultState, const QStringList &overlays=QStringList())
Definition: kiconloader.cpp:1538
KComponentData::dirs
KStandardDirs * dirs() const
KIconLoader::iconPath
QString iconPath(const QString &name, int group_or_size, bool canReturnNull=false) const
Returns the path of an icon.
Definition: kiconloader.cpp:1009
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:23:59 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • 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
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • 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