KIconThemes

kicontheme.cpp
1 /* vi: ts=8 sts=4 sw=4
2  *
3  * kicontheme.cpp: Lowlevel icon theme handling.
4  *
5  * This file is part of the KDE project, module kdecore.
6  * Copyright (C) 2000 Geert Jansen <[email protected]>
7  * Antonio Larrosa <[email protected]>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License version 2 as published by the Free Software Foundation.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB. If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23 
24 #include "kicontheme.h"
25 
26 #include <qplatformdefs.h>
27 
28 #include <QCoreApplication>
29 #include <QAction>
30 #include <QMap>
31 #include <QSet>
32 #include <QFileInfo>
33 #include <QDir>
34 #include <QDebug>
35 #include <QResource>
36 
37 #include <KLocalizedString> // KLocalizedString::localizedFilePath. Need such functionality in, hmm, QLocale? QStandardPaths?
38 
39 #include <KSharedConfig>
40 
41 #include <KConfigGroup>
42 #include <cmath>
43 
44 Q_GLOBAL_STATIC(QString, _themeOverride)
45 
46 // Support for icon themes in RCC files.
47 // The intended use case is standalone apps on Windows / MacOS / etc.
48 // For this reason we use AppDataLocation: BINDIR/data on Windows, Resources on OS X
49 void initRCCIconTheme()
50 {
51  const QString iconThemeRcc = QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral("icontheme.rcc"));
52  if (!iconThemeRcc.isEmpty()) {
53  const QString iconThemeName = QStringLiteral("kf5_rcc_theme");
54  const QString iconSubdir = QStringLiteral("/icons/") + iconThemeName;
55  if (QResource::registerResource(iconThemeRcc, iconSubdir)) {
56  if (QFileInfo::exists(QLatin1Char(':') + iconSubdir + QStringLiteral("/index.theme"))) {
57  // Tell Qt about the theme
58  // Note that since qtbase commit a8621a3f8, this means the QPA (i.e. KIconLoader) will NOT be used.
59  QIcon::setThemeName(iconThemeName); // Qt looks under :/icons automatically
60  // Tell KIconTheme about the theme, in case KIconLoader is used directly
61  *_themeOverride() = iconThemeName;
62  } else {
63  qWarning() << "No index.theme found in" << iconThemeRcc;
64  QResource::unregisterResource(iconThemeRcc, iconSubdir);
65  }
66  } else {
67  qWarning() << "Invalid rcc file" << iconThemeRcc;
68  }
69  }
70 }
71 Q_COREAPP_STARTUP_FUNCTION(initRCCIconTheme)
72 
73 // Set the icon theme fallback to breeze
74 // Most of our apps use "lots" of icons that most of the times
75 // are only available with breeze, we still honour the user icon
76 // theme but if the icon is not found there, we go to breeze
77 // since it's almost sure it'll be there
78 static void setBreezeFallback()
79 {
80  QIcon::setFallbackThemeName(QStringLiteral("breeze"));
81 }
82 
83 Q_COREAPP_STARTUP_FUNCTION(setBreezeFallback)
84 
85 class Q_DECL_HIDDEN KIconTheme::KIconThemePrivate
86 {
87 public:
88  QString example, screenshot;
89  bool hidden;
90  KSharedConfig::Ptr sharedConfig;
91 
92  int mDefSize[6];
93  QList<int> mSizes[6];
94 
95  int mDepth;
96  QString mDir, mName, mInternalName, mDesc;
97  QStringList mInherits;
98  QStringList mExtensions;
100  QVector<KIconThemeDir *> mScaledDirs;
101  bool followsColorScheme : 1;
102 
104  QString iconPath(const QVector<KIconThemeDir *> &dirs, const QString &name, int size, qreal scale, KIconLoader::MatchType match) const;
105 };
106 Q_GLOBAL_STATIC(QString, _theme)
107 Q_GLOBAL_STATIC(QStringList, _theme_list)
108 
112 class KIconThemeDir
113 {
114 public:
115  KIconThemeDir(const QString &basedir, const QString &themedir, const KConfigGroup &config);
116 
117  bool isValid() const
118  {
119  return mbValid;
120  }
121  QString iconPath(const QString &name) const;
122  QStringList iconList() const;
123  QString constructFileName(const QString &file) const
124  {
125  return mBaseDir + mThemeDir + QLatin1Char('/') + file;
126  }
127 
128  KIconLoader::Context context() const
129  {
130  return mContext;
131  }
132  KIconLoader::Type type() const
133  {
134  return mType;
135  }
136  int size() const
137  {
138  return mSize;
139  }
140  int scale() const
141  {
142  return mScale;
143  }
144  int minSize() const
145  {
146  return mMinSize;
147  }
148  int maxSize() const
149  {
150  return mMaxSize;
151  }
152  int threshold() const
153  {
154  return mThreshold;
155  }
156 
157 private:
158  bool mbValid;
159  KIconLoader::Type mType;
160  KIconLoader::Context mContext;
161  int mSize, mScale, mMinSize, mMaxSize;
162  int mThreshold;
163 
164  const QString mBaseDir;
165  const QString mThemeDir;
166 };
167 
168 QString KIconTheme::KIconThemePrivate::iconPath(const QVector<KIconThemeDir *> &dirs, const QString &name, int size, qreal scale, KIconLoader::MatchType match) const
169 {
170  QString path;
171  QString tempPath; // used to cache icon path if it exists
172 
173  int delta = -INT_MAX; // current icon size delta of 'icon'
174  int dw = INT_MAX; // icon size delta of current directory
175 
176  // Rather downsample than upsample
177  int integerScale = std::ceil(scale);
178 
179  // Search the directory that contains the icon which matches best to the requested
180  // size. If there is no directory which matches exactly to the requested size, the
181  // following criterias get applied:
182  // - Take a directory having icons with a minimum difference to the requested size.
183  // - Prefer directories that allow a downscaling even if the difference to
184  // the requested size is bigger than a directory where an upscaling is required.
185  for (KIconThemeDir *dir : dirs) {
186  if (dir->scale() != integerScale) {
187  continue;
188  }
189 
190  if (match == KIconLoader::MatchExact) {
191  if ((dir->type() == KIconLoader::Fixed) && (dir->size() != size)) {
192  continue;
193  }
194  if ((dir->type() == KIconLoader::Scalable) &&
195  ((size < dir->minSize()) || (size > dir->maxSize()))) {
196  continue;
197  }
198  if ((dir->type() == KIconLoader::Threshold) &&
199  (abs(dir->size() - size) > dir->threshold())) {
200  continue;
201  }
202  } else {
203  // dw < 0 means need to scale up to get an icon of the requested size.
204  // Upscaling should only be done if no larger icon is available.
205  if (dir->type() == KIconLoader::Fixed) {
206  dw = dir->size() - size;
207  } else if (dir->type() == KIconLoader::Scalable) {
208  if (size < dir->minSize()) {
209  dw = dir->minSize() - size;
210  } else if (size > dir->maxSize()) {
211  dw = dir->maxSize() - size;
212  } else {
213  dw = 0;
214  }
215  } else if (dir->type() == KIconLoader::Threshold) {
216  if (size < dir->size() - dir->threshold()) {
217  dw = dir->size() - dir->threshold() - size;
218  } else if (size > dir->size() + dir->threshold()) {
219  dw = dir->size() + dir->threshold() - size;
220  } else {
221  dw = 0;
222  }
223  }
224  // Usually if the delta (= 'dw') of the current directory is
225  // not smaller than the delta (= 'delta') of the currently best
226  // matching icon, this candidate can be skipped. But skipping
227  // the candidate may only be done, if this does not imply
228  // in an upscaling of the icon (it is OK to use a directory with
229  // smaller icons that what we've already found, however).
230  if ((abs(dw) >= abs(delta)) && ((dw < 0) || (delta > 0))) {
231  continue;
232  }
233  }
234 
235  // cache the result of iconPath() call which checks if file exists
236  tempPath = dir->iconPath(name);
237 
238  if (tempPath.isEmpty()) {
239  continue;
240  }
241 
242  path = tempPath;
243 
244  // if we got in MatchExact that far, we find no better
245  if (match == KIconLoader::MatchExact) {
246  return path;
247  }
248  delta = dw;
249  if (delta == 0) {
250  return path; // We won't find a better match anyway
251  }
252  }
253  return path;
254 }
255 
256 KIconTheme::KIconTheme(const QString &name, const QString &appName, const QString &basePathHint)
257  : d(new KIconThemePrivate)
258 {
259  d->mInternalName = name;
260 
261  QStringList themeDirs;
262  QSet<QString> addedDirs; // Used for avoiding duplicates.
263 
264  // Applications can have local additions to the global "locolor" and
265  // "hicolor" icon themes. For these, the _global_ theme description
266  // files are used..
267 
268  if (!appName.isEmpty() &&
269  (name == defaultThemeName() || name == QLatin1String("hicolor") || name == QLatin1String("locolor"))) {
271  for (QStringList::ConstIterator it = icnlibs.constBegin(), total = icnlibs.constEnd(); it != total; ++it) {
272  const QString cDir = *it + QLatin1Char('/') + appName + QStringLiteral("/icons/") + name + QLatin1Char('/');
273  if (QFileInfo::exists(cDir)) {
274  themeDirs += cDir;
275  }
276  }
277 
278  if (!basePathHint.isEmpty()) {
279  // Checks for dir existing are done below
280  themeDirs += basePathHint + QLatin1Char('/') + name + QLatin1Char('/');
281  }
282  }
283 
284  // Find the theme description file. These are either locally in the :/icons resource path or global.
285  QStringList icnlibs;
286 
287  // local embedded icons have preference
288  icnlibs << QStringLiteral(":/icons");
289 
290  // global icons
292 
293  // These are not in the icon spec, but e.g. GNOME puts some icons there anyway.
295 
296  QString fileName, mainSection;
297  for (QStringList::ConstIterator it = icnlibs.constBegin(), total = icnlibs.constEnd(); it != total; ++it) {
298  const QString cDir = *it + QLatin1Char('/') + name + QLatin1Char('/');
299  if (QDir(cDir).exists()) {
300  themeDirs += cDir;
301  if (d->mDir.isEmpty()) {
302  if (QFileInfo::exists(cDir + QStringLiteral("index.theme"))) {
303  d->mDir = cDir;
304  fileName = d->mDir + QStringLiteral("index.theme");
305  mainSection = QStringLiteral("Icon Theme");
306  } else if (QFileInfo::exists(cDir + QStringLiteral("index.desktop"))) {
307  d->mDir = cDir;
308  fileName = d->mDir + QStringLiteral("index.desktop");
309  mainSection = QStringLiteral("KDE Icon Theme");
310  }
311  }
312  }
313  }
314 
315  if (d->mDir.isEmpty()) {
316  qWarning() << "Icon theme" << name << "not found.";
317  return;
318  }
319 
320  // Use KSharedConfig to avoid parsing the file many times, from each component.
321  // Need to keep a ref to it to make this useful
322  d->sharedConfig = KSharedConfig::openConfig(fileName, KConfig::NoGlobals);
323 
324  KConfigGroup cfg(d->sharedConfig, mainSection);
325  d->mName = cfg.readEntry("Name");
326  d->mDesc = cfg.readEntry("Comment");
327  d->mDepth = cfg.readEntry("DisplayDepth", 32);
328  d->mInherits = cfg.readEntry("Inherits", QStringList());
329  if (name != defaultThemeName()) {
330  for (QStringList::Iterator it = d->mInherits.begin(), total = d->mInherits.end(); it != total; ++it) {
331  if (*it == QLatin1String("default")) {
332  *it = defaultThemeName();
333  }
334  }
335  }
336 
337  d->hidden = cfg.readEntry("Hidden", false);
338  d->followsColorScheme = cfg.readEntry("FollowsColorScheme", false);
339  d->example = cfg.readPathEntry("Example", QString());
340  d->screenshot = cfg.readPathEntry("ScreenShot", QString());
341  d->mExtensions = cfg.readEntry("KDE-Extensions", QStringList{ QStringLiteral(".png"), QStringLiteral(".svgz"), QStringLiteral(".svg"), QStringLiteral(".xpm") });
342 
343  const QStringList dirs = cfg.readPathEntry("Directories", QStringList())
344  + cfg.readPathEntry("ScaledDirectories", QStringList());
345  for (QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) {
346  KConfigGroup cg(d->sharedConfig, *it);
347  for (QStringList::ConstIterator itDir = themeDirs.constBegin(); itDir != themeDirs.constEnd(); ++itDir) {
348  const QString currentDir(*itDir + *it + QLatin1Char('/'));
349  if (!addedDirs.contains(currentDir) && QDir(currentDir).exists()) {
350  addedDirs.insert(currentDir);
351  KIconThemeDir *dir = new KIconThemeDir(*itDir, *it, cg);
352  if (dir->isValid()) {
353  if (dir->scale() > 1) {
354  d->mScaledDirs.append(dir);
355  } else {
356  d->mDirs.append(dir);
357  }
358  } else {
359  delete dir;
360  }
361  }
362  }
363  }
364 
365  QStringList groups;
366  groups += QStringLiteral("Desktop");
367  groups += QStringLiteral("Toolbar");
368  groups += QStringLiteral("MainToolbar");
369  groups += QStringLiteral("Small");
370  groups += QStringLiteral("Panel");
371  groups += QStringLiteral("Dialog");
372  const int defDefSizes[] = { 32, 22, 22, 16, 48, 32 };
373  KConfigGroup cg(d->sharedConfig, mainSection);
374  for (int i = 0; i < groups.size(); ++i) {
375  const QString group = groups.at(i);
376  d->mDefSize[i] = cg.readEntry(group + QStringLiteral("Default"), defDefSizes[i]);
377  d->mSizes[i] = cg.readEntry(group + QStringLiteral("Sizes"), QList<int>());
378  }
379 }
380 
381 KIconTheme::~KIconTheme()
382 {
383  qDeleteAll(d->mDirs);
384  qDeleteAll(d->mScaledDirs);
385  delete d;
386 }
387 
389 {
390  return d->mName;
391 }
392 
394 {
395  return d->mInternalName;
396 }
397 
399 {
400  return d->mDesc;
401 }
402 
404 {
405  return d->example;
406 }
407 
409 {
410  return d->screenshot;
411 }
412 
414 {
415  return d->mDir;
416 }
417 
419 {
420  return d->mInherits;
421 }
422 
424 {
425  return !d->mDirs.isEmpty() || !d->mScaledDirs.isEmpty();
426 }
427 
429 {
430  return d->hidden;
431 }
432 
433 int KIconTheme::depth() const
434 {
435  return d->mDepth;
436 }
437 
439 {
440  if ((group < 0) || (group >= KIconLoader::LastGroup)) {
441  qWarning() << "Illegal icon group: " << group;
442  return -1;
443  }
444  return d->mDefSize[group];
445 }
446 
448 {
449  if ((group < 0) || (group >= KIconLoader::LastGroup)) {
450  qWarning() << "Illegal icon group: " << group;
451  return QList<int>();
452  }
453  return d->mSizes[group];
454 }
455 
457 {
458  // Try to find exact match
459  QStringList result;
460  const auto listDirs = d->mDirs + d->mScaledDirs;
461  for (KIconThemeDir* dir : listDirs) {
462  if ((context != KIconLoader::Any) && (context != dir->context())) {
463  continue;
464  }
465  if ((dir->type() == KIconLoader::Fixed) && (dir->size() == size)) {
466  result += dir->iconList();
467  continue;
468  }
469  if ((dir->type() == KIconLoader::Scalable) &&
470  (size >= dir->minSize()) && (size <= dir->maxSize())) {
471  result += dir->iconList();
472  continue;
473  }
474  if ((dir->type() == KIconLoader::Threshold) &&
475  (abs(size - dir->size()) < dir->threshold())) {
476  result += dir->iconList();
477  }
478  }
479 
480  return result;
481 
482  /*
483  int delta = 1000, dw;
484 
485  // Find close match
486  KIconThemeDir *best = 0L;
487  for(int i=0; i<d->mDirs.size(); ++i) {
488  dir = d->mDirs.at(i);
489  if ((context != KIconLoader::Any) && (context != dir->context())) {
490  continue;
491  }
492  dw = dir->size() - size;
493  if ((dw > 6) || (abs(dw) >= abs(delta)))
494  continue;
495  delta = dw;
496  best = dir;
497  }
498  if (best == 0L) {
499  return QStringList();
500  }
501 
502  return best->iconList();
503  */
504 }
505 
507 {
508  int dw;
509 
510  // We want all the icons for a given context, but we prefer icons
511  // of size size . Note that this may (will) include duplicate icons
512  //QStringList iconlist[34]; // 33 == 48-16+1
513  QStringList iconlist[128]; // 33 == 48-16+1
514  // Usually, only the 0, 6 (22-16), 10 (32-22), 16 (48-32 or 32-16),
515  // 26 (48-22) and 32 (48-16) will be used, but who knows if someone
516  // will make icon themes with different icon sizes.
517  const auto listDirs = d->mDirs + d->mScaledDirs;
518  for (KIconThemeDir* dir : listDirs) {
519  if ((context != KIconLoader::Any) && (context != dir->context())) {
520  continue;
521  }
522  dw = abs(dir->size() - size);
523  iconlist[(dw < 127) ? dw : 127] += dir->iconList();
524  }
525 
526  QStringList iconlistResult;
527  for (int i = 0; i < 128; i++) {
528  iconlistResult += iconlist[i];
529  }
530 
531  return iconlistResult;
532 }
533 
535 {
536  const auto listDirs = d->mDirs + d->mScaledDirs;
537  for (KIconThemeDir* dir : listDirs) {
538  if ((context == KIconLoader::Any) || (context == dir->context())) {
539  return true;
540  }
541  }
542  return false;
543 }
544 
545 QString KIconTheme::iconPathByName(const QString &iconName, int size, KIconLoader::MatchType match) const
546 {
547  return iconPathByName(iconName, size, match, 1 /*scale*/);
548 }
549 
550 QString KIconTheme::iconPathByName(const QString &iconName, int size, KIconLoader::MatchType match, qreal scale) const
551 {
552  for (const QString &current : qAsConst(d->mExtensions)) {
553  const QString path = iconPath(iconName + current, size, match, scale);
554  if (!path.isEmpty())
555  return path;
556  }
557  return QString();
558 }
559 
561 {
562  return d->followsColorScheme;
563 }
564 
565 QString KIconTheme::iconPath(const QString &name, int size, KIconLoader::MatchType match) const
566 {
567  return iconPath(name, size, match, 1 /*scale*/);
568 }
569 
570 QString KIconTheme::iconPath(const QString &name, int size, KIconLoader::MatchType match, qreal scale) const
571 {
572  // first look for a scaled image at exactly the requested size
573  QString path = d->iconPath(d->mScaledDirs, name, size, scale, KIconLoader::MatchExact);
574 
575  // then look for an unscaled one but request it at larger size so it doesn't become blurry
576  if (path.isEmpty()) {
577  path = d->iconPath(d->mDirs, name, size * scale, 1, match);
578  }
579  return path;
580 }
581 
582 // static
584 {
585  // Static pointers because of unloading problems wrt DSO's.
586  if (_themeOverride && !_themeOverride->isEmpty()) {
587  *_theme() = *_themeOverride();
588  }
589  if (!_theme()->isEmpty()) {
590  return *_theme();
591  }
592 
593  QString theme;
594  // Check application specific config for a theme setting.
596  theme = app_cg.readEntry("Theme", QString());
597  if (theme.isEmpty() || theme == QLatin1String("hicolor")) {
598  // No theme, try to use Qt's. A Platform plugin might have set
599  // a good theme there.
600  theme = QIcon::themeName();
601  }
602  if (theme.isEmpty() || theme == QLatin1String("hicolor")) {
603  // Still no theme, try config with kdeglobals.
605  theme = cg.readEntry("Theme", QStringLiteral("breeze"));
606  }
607  if (theme.isEmpty() || theme == QLatin1String("hicolor")) {
608  // Still no good theme, use default.
609  theme = defaultThemeName();
610  }
611  *_theme() = theme;
612  return *_theme();
613 }
614 
616 {
617  *_themeOverride() = themeName;
618  _theme()->clear(); // ::current sets this again based on conditions
619 }
620 
621 // static
623 {
624  // Static pointer because of unloading problems wrt DSO's.
625  if (!_theme_list()->isEmpty()) {
626  return *_theme_list();
627  }
628 
629  // Find the theme description file. These are either locally in the :/icons resource path or global.
630  QStringList icnlibs;
631 
632  // local embedded icons have preference
633  icnlibs << QStringLiteral(":/icons");
634 
635  // global icons
637 
638  // These are not in the icon spec, but e.g. GNOME puts some icons there anyway.
640 
641  for (const QString &it : qAsConst(icnlibs)) {
642  QDir dir(it);
644  for (QStringList::ConstIterator it2 = lst.begin(), total = lst.end(); it2 != total; ++it2) {
645  if ((*it2).startsWith(QLatin1String("default."))) {
646  continue;
647  }
648  if (!QFileInfo::exists(it + QLatin1Char('/') + *it2 + QLatin1String("/index.desktop")) &&
649  !QFileInfo::exists(it + QLatin1Char('/') + *it2 + QLatin1String("/index.theme"))) {
650  continue;
651  }
652  KIconTheme oink(*it2);
653  if (!oink.isValid()) {
654  continue;
655  }
656 
657  if (!_theme_list()->contains(*it2)) {
658  _theme_list()->append(*it2);
659  }
660  }
661  }
662  return *_theme_list();
663 }
664 
665 // static
667 {
668  _theme()->clear();
669  _theme_list()->clear();
670 }
671 
672 // static
674 {
675  return QStringLiteral("hicolor");
676 }
677 
678 #if KICONTHEMES_BUILD_DEPRECATED_SINCE(5, 64)
680  QList<QAction *> actions)
681 {
682  switch (type) {
683  // FIXME: This code depends on Qt's action ordering.
684  case TextEditor:
685  enum { UndoAct, RedoAct, Separator1, CutAct, CopyAct, PasteAct, DeleteAct, ClearAct,
686  Separator2, SelectAllAct, NCountActs
687  };
688 
689  if (actions.count() < NCountActs) {
690  return;
691  }
692 
693  actions[UndoAct]->setIcon(QIcon::fromTheme(QStringLiteral("edit-undo")));
694  actions[RedoAct]->setIcon(QIcon::fromTheme(QStringLiteral("edit-redo")));
695  actions[CutAct]->setIcon(QIcon::fromTheme(QStringLiteral("edit-cut")));
696  actions[CopyAct]->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy")));
697  actions[PasteAct]->setIcon(QIcon::fromTheme(QStringLiteral("edit-paste")));
698  actions[ClearAct]->setIcon(QIcon::fromTheme(QStringLiteral("edit-clear")));
699  actions[DeleteAct]->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete")));
700  actions[SelectAllAct]->setIcon(QIcon::fromTheme(QStringLiteral("edit-select-all")));
701  break;
702 
703  case ReadOnlyText:
704  if (actions.count() < 1) {
705  return;
706  }
707 
708  actions[0]->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy")));
709  break;
710  }
711 }
712 #endif
713 
714 /*** KIconThemeDir ***/
715 
716 KIconThemeDir::KIconThemeDir(const QString &basedir, const QString &themedir, const KConfigGroup &config)
717  : mbValid(false)
718  , mType(KIconLoader::Fixed)
719  , mSize(config.readEntry("Size", 0))
720  , mScale(config.readEntry("Scale", 1))
721  , mMinSize(1) // just set the variables to something
722  , mMaxSize(50) // meaningful in case someone calls minSize or maxSize
723  , mThreshold(2)
724  , mBaseDir(basedir)
725  , mThemeDir(themedir)
726 {
727  if (mSize == 0) {
728  return;
729  }
730 
731  QString tmp = config.readEntry(QStringLiteral("Context"));
732  if (tmp == QLatin1String("Devices")) {
733  mContext = KIconLoader::Device;
734  } else if (tmp == QLatin1String("MimeTypes")) {
735  mContext = KIconLoader::MimeType;
736 #if KICONTHEMES_BUILD_DEPRECATED_SINCE(4, 8)
737  } else if (tmp == QLatin1String("FileSystems")) {
738  mContext = KIconLoader::FileSystem;
739 #endif
740  } else if (tmp == QLatin1String("Applications")) {
741  mContext = KIconLoader::Application;
742  } else if (tmp == QLatin1String("Actions")) {
743  mContext = KIconLoader::Action;
744  } else if (tmp == QLatin1String("Animations")) {
745  mContext = KIconLoader::Animation;
746  } else if (tmp == QLatin1String("Categories")) {
747  mContext = KIconLoader::Category;
748  } else if (tmp == QLatin1String("Emblems")) {
749  mContext = KIconLoader::Emblem;
750  } else if (tmp == QLatin1String("Emotes")) {
751  mContext = KIconLoader::Emote;
752  } else if (tmp == QLatin1String("International")) {
753  mContext = KIconLoader::International;
754  } else if (tmp == QLatin1String("Places")) {
755  mContext = KIconLoader::Place;
756  } else if (tmp == QLatin1String("Status")) {
757  mContext = KIconLoader::StatusIcon;
758  } else if (tmp == QLatin1String("Stock")) { // invalid, but often present context, skip warning
759  return;
760  } else if (tmp.isEmpty()) {
761  // do nothing. key not required
762  } else {
763  qWarning() << "Invalid Context=" << tmp << "line for icon theme: " << constructFileName(QString());
764  return;
765  }
766  tmp = config.readEntry(QStringLiteral("Type"), QStringLiteral("Threshold"));
767  if (tmp == QLatin1String("Fixed")) {
768  mType = KIconLoader::Fixed;
769  } else if (tmp == QLatin1String("Scalable")) {
770  mType = KIconLoader::Scalable;
771  } else if (tmp == QLatin1String("Threshold")) {
772  mType = KIconLoader::Threshold;
773  } else {
774  qWarning() << "Invalid Type=" << tmp << "line for icon theme: " << constructFileName(QString());
775  return;
776  }
777  if (mType == KIconLoader::Scalable) {
778  mMinSize = config.readEntry(QStringLiteral("MinSize"), mSize);
779  mMaxSize = config.readEntry(QStringLiteral("MaxSize"), mSize);
780  } else if (mType == KIconLoader::Threshold) {
781  mThreshold = config.readEntry(QStringLiteral("Threshold"), 2);
782  }
783  mbValid = true;
784 }
785 
786 QString KIconThemeDir::iconPath(const QString &name) const
787 {
788  if (!mbValid) {
789  return QString();
790  }
791 
792  const QString file = constructFileName(name);
793  if (QFileInfo::exists(file)) {
795  }
796 
797  return QString();
798 }
799 
800 QStringList KIconThemeDir::iconList() const
801 {
802  const QDir icondir = constructFileName(QString());
803 
804  const QStringList formats = QStringList() << QStringLiteral("*.png") << QStringLiteral("*.svg") << QStringLiteral("*.svgz") << QStringLiteral("*.xpm");
805  const QStringList lst = icondir.entryList(formats, QDir::Files);
806 
807  QStringList result;
808  result.reserve(lst.size());
809  for (const QString &file : lst) {
810  result += constructFileName(file);
811  }
812  return result;
813 }
static void reconfigure()
Reconfigure the theme.
Definition: kicontheme.cpp:666
QString screenshot() const
Return the name of the screenshot.
Definition: kicontheme.cpp:408
QString iconPathByName(const QString &name, int size, KIconLoader::MatchType match) const
Lookup an icon in the theme.
Definition: kicontheme.cpp:545
QString readPathEntry(const QString &pKey, const QString &aDefault) const
An icon that represents a mime type (or file type).
Definition: kiconloader.h:96
int defaultSize(KIconLoader::Group group) const
The default size of this theme for a certain icon group.
Definition: kicontheme.cpp:438
An icon that represents an event.
Definition: kiconloader.h:103
void setFallbackThemeName(const QString &name)
bool registerResource(const QString &rccFileName, const QString &mapRoot)
QStringList locateAll(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options)
bool isHidden() const
The icon theme should be hidden to the user?
Definition: kicontheme.cpp:428
bool isValid() const
The icon theme exists?
Definition: kicontheme.cpp:423
An icon that expresses an emotion.
Definition: kiconloader.h:100
A threshold icon.
Definition: kiconloader.h:113
void setThemeName(const QString &name)
void reserve(int alloc)
int depth() const
The minimum display depth required for this theme.
Definition: kicontheme.cpp:433
Scalable-size icon.
Definition: kiconloader.h:112
static void forceThemeForTests(const QString &themeName)
Force a current theme and disable automatic resolution of the current theme in favor of the forced th...
Definition: kicontheme.cpp:615
const T & at(int i) const const
int size() const const
QString dir() const
Returns the toplevel theme directory.
Definition: kicontheme.cpp:413
ContextMenus
Defines the context menus that assignIconsToContextMenus is aware of.
Definition: kicontheme.h:282
An icon that represents a location (e.g. &#39;home&#39;, &#39;trash&#39;).
Definition: kiconloader.h:102
QSet::iterator insert(const T &value)
An icon that is animated.
Definition: kiconloader.h:97
int size() const const
QStringList standardLocations(QStandardPaths::StandardLocation type)
QList< int > querySizes(KIconLoader::Group group) const
Query available sizes for a group.
Definition: kicontheme.cpp:447
QString iconPath(const QString &name, int size, KIconLoader::MatchType match) const
Lookup an icon in the theme.
Definition: kicontheme.cpp:565
void clear()
An icon that represents a country&#39;s flag.
Definition: kiconloader.h:101
Some icon with unknown purpose.
Definition: kiconloader.h:87
int count(const T &value) const const
bool exists() const const
An icon that represents a category.
Definition: kiconloader.h:98
Type type(const QSqlDatabase &db)
bool isEmpty() const const
An icon that represents a file system.
Definition: kiconloader.h:92
typedef Iterator
bool followsColorScheme() const
If true, this theme is made of SVG icons that will be colorized following the system color scheme...
Definition: kicontheme.cpp:560
bool hasContext(KIconLoader::Context context) const
Returns true if the theme has any icons for the given context.
Definition: kicontheme.cpp:534
An action icon (e.g. &#39;save&#39;, &#39;print&#39;).
Definition: kiconloader.h:88
static QString localizedFilePath(const QString &filePath)
Type
The type of the icon.
Definition: kiconloader.h:110
QStringList inherits() const
The themes this icon theme falls back on.
Definition: kicontheme.cpp:418
QList::iterator end()
bool exists() const const
QStringList queryIconsByContext(int size, KIconLoader::Context context=KIconLoader::Any) const
Query available icons for a context and preferred size.
Definition: kicontheme.cpp:506
QString example() const
Return the name of the "example" icon.
Definition: kicontheme.cpp:403
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
MatchType
The type of a match.
Definition: kiconloader.h:120
bool contains(const T &value) const const
QStringList queryIcons(int size, KIconLoader::Context context=KIconLoader::Any) const
Query available icons for a size and context.
Definition: kicontheme.cpp:456
An icon that represents an application.
Definition: kiconloader.h:89
KIconTheme(const QString &name, const QString &appName=QString(), const QString &basePathHint=QString())
Load an icon theme by name.
Definition: kicontheme.cpp:256
QString themeName()
An icon that represents a device.
Definition: kiconloader.h:90
KIOFILEWIDGETS_EXPORT QString dir(const QString &fileClass)
bool unregisterResource(const QString &rccFileName, const QString &mapRoot)
QStringList entryList(QDir::Filters filters, QDir::SortFlags sort) const const
Context
Defines the context of the icon.
Definition: kiconloader.h:86
Only try to find an exact match.
Definition: kiconloader.h:121
Group
The group of the icon.
Definition: kiconloader.h:129
typedef ConstIterator
static QString defaultThemeName()
Returns the default icon theme.
Definition: kicontheme.cpp:673
Fixed-size icon.
Definition: kiconloader.h:111
QIcon fromTheme(const QString &name)
QList::const_iterator constEnd() const const
QList::const_iterator constBegin() const const
QString description() const
A description for the icon theme.
Definition: kicontheme.cpp:398
static void assignIconsToContextMenu(ContextMenus type, QList< QAction * > actions)
Assigns standard icons to the various standard text edit context menus.
Definition: kicontheme.cpp:679
QString name() const
The stylized name of the icon theme.
Definition: kicontheme.cpp:388
T readEntry(const QString &key, const T &aDefault) const
QList::iterator begin()
static QString current()
Returns the current icon theme.
Definition: kicontheme.cpp:583
QString internalName() const
The internal name of the icon theme (same as the name argument passed to the constructor).
Definition: kicontheme.cpp:393
QString locate(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options)
An icon that adds information to an existing icon.
Definition: kiconloader.h:99
static QStringList list()
List all icon themes installed on the system, global and local.
Definition: kicontheme.cpp:622
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sun Jul 12 2020 22:41:33 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.