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

KDEUI

  • sources
  • kde-4.12
  • kdelibs
  • kdeui
  • icons
kiconcache.cpp
Go to the documentation of this file.
1 /*
2  *
3  * This file is part of the KDE project.
4  * Copyright (C) 2007 Rivo Laks <rivolaks@hot.ee>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License version 2 as published by the Free Software Foundation.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB. If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #include "kiconcache.h"
22 
23 #include <QtCore/QString>
24 #include <QtGui/QPixmap>
25 #include <QtCore/QFile>
26 #include <QtCore/QDataStream>
27 #include <QtCore/QFileInfo>
28 #include <QtCore/QDateTime>
29 
30 #include <kglobal.h>
31 #include <kstandarddirs.h>
32 #include <kdebug.h>
33 
34 #include <sys/file.h>
35 #include <time.h>
36 
37 
38 #define KDE_ICONCACHE_NAME "kde-icon-cache"
39 #define KDE_ICONCACHE_VERSION 0x000100
40 
41 
42 class KIconCache::Private
43 {
44 public:
45  Private(KIconCache* _q)
46  {
47  q = _q;
48  mUpdatesCheckedTime = 0;
49  }
50  bool themeDirsChanged()
51  {
52  if (q->existingIconThemeDirs(mThemeNames) != mThemeDirs ||
53  q->mostRecentMTime(mThemeDirs) != mThemesMTime) {
54  kDebug(264) << "Theme directory has been modified";
55  return true;
56  } else {
57  return false;
58  }
59  }
60  void checkForThemeUpdates()
61  {
62  if (!q->isEnabled()) {
63  return;
64  }
65  // Don't check more often than every 5 secs
66  const quint32 now = ::time(0);
67  if (now < mUpdatesCheckedTime + 5) {
68  return;
69  }
70 
71  mUpdatesCheckedTime = now;
72  // Perhaps another process has already checked for updates in last 5 secs
73  const QFileInfo fi(mUpdatesFile);
74  if (fi.exists() && fi.lastModified().toTime_t() + 5 > now) {
75  return;
76  }
77  // Check for theme updates
78  if (themeDirsChanged()) {
79  // Update themes info and discard the cache
80  mThemeDirs = q->existingIconThemeDirs(mThemeNames);
81  mThemesMTime = q->mostRecentMTime(mThemeDirs);
82  q->discard();
83  }
84  // Update timestamp file
85  QFile f(mUpdatesFile);
86  f.open(QIODevice::WriteOnly);
87  }
88 
89  KIconCache* q;
90 
91  qint32 mDefaultIconSize[6];
92  QStringList mThemeNames;
93  QSet<QString> mThemeDirs;
94  quint32 mThemesMTime;
95  QString mUpdatesFile;
96  quint32 mUpdatesCheckedTime;
97 
98  QString* mLoadPath;
99  QString mSavePath;
100 };
101 
102 
103 KIconCache::KIconCache()
104  : KPixmapCache(KDE_ICONCACHE_NAME), d(new Private(this))
105 {
106  d->mUpdatesFile = KGlobal::dirs()->locateLocal("cache", "kpc/"KDE_ICONCACHE_NAME".updated");
107  // Set limit to 10 MB
108  setCacheLimit(10 * 1024);
109 }
110 
111 KIconCache::~KIconCache()
112 {
113  delete d;
114 }
115 
116 void KIconCache::deleteCache()
117 {
118  KPixmapCache::deleteCache(KDE_ICONCACHE_NAME);
119 }
120 
121 bool KIconCache::loadCustomIndexHeader(QDataStream& stream)
122 {
123  if (stream.atEnd()) {
124  return false;
125  }
126 
127  // Load version
128  quint32 version;
129  stream >> version;
130  if (version != KDE_ICONCACHE_VERSION) {
131  kDebug(264) << "Obsolete iconcache version" << version << "will recreate";
132  return false;
133  }
134 
135  // Load default sizes of icons
136  for (int i = 0; i < 6; i++) {
137  stream >> d->mDefaultIconSize[i];
138  }
139 
140 
141  stream >> d->mThemeNames;
142  stream >> d->mThemeDirs;
143  // TODO: use KPixmapCache's timestamp instead
144  stream >> d->mThemesMTime;
145 
146  if (stream.status() != QDataStream::Ok) {
147  kWarning() << "Failed to read index file's header";
148  recreateCacheFiles();
149  return false;
150  }
151 
152  // Make sure at least one theme was read
153  if (!d->mThemeNames.count()) {
154  kDebug(264) << "Empty themes list";
155  return false;
156  }
157 
158  // Make sure the theme dirs haven't changed
159  if (d->themeDirsChanged()) {
160  return false;
161  }
162  d->mUpdatesCheckedTime= ::time(0);
163 
164  return true;
165 }
166 
167 void KIconCache::writeCustomIndexHeader(QDataStream& stream)
168 {
169  setValid(false);
170 
171  stream << (quint32)KDE_ICONCACHE_VERSION;
172 
173  for (int i = 0; i < 6; i++) {
174  stream << d->mDefaultIconSize[i];
175  }
176 
177  // Save iconthemes info
178  stream << d->mThemeNames;
179  stream << d->mThemeDirs;
180  stream << d->mThemesMTime;
181 
182  // Cache is valid if header was successfully written and we actually have
183  // the icontheme name(s)
184  if (stream.status() == QDataStream::Ok && d->mThemeNames.count()) {
185  setValid(true);
186  }
187 }
188 
189 QSet<QString> KIconCache::existingIconThemeDirs(const QStringList& themeNames) const
190 {
191  // Find all possible icontheme dirs
192  // This has been taken from kicontheme.cpp
193  QStringList icondirs = KGlobal::dirs()->resourceDirs("icon")
194  << KGlobal::dirs()->resourceDirs("xdgdata-icon")
195  << "/usr/share/pixmaps/"
196  // These are not in the icon spec, but e.g. GNOME puts some icons there anyway.
197  << KGlobal::dirs()->resourceDirs("xdgdata-pixmap");
198  icondirs.removeDuplicates();
199 
200  // Check which of theme actually contain existing dir of one of the
201  // given themes
202  QSet<QString> dirs;
203  for (QStringList::ConstIterator it = icondirs.constBegin(); it != icondirs.constEnd(); ++it) {
204  QStringList::ConstIterator themeIt;
205  for (themeIt = themeNames.begin(); themeIt != themeNames.end(); ++themeIt) {
206  QString dirName = *it + *themeIt + '/';
207  if (KStandardDirs::exists(dirName)) {
208  dirs.insert(dirName);
209  }
210  }
211  }
212 
213  return dirs;
214 }
215 
216 unsigned int KIconCache::mostRecentMTime(const QSet<QString>& dirNames) const
217 {
218  unsigned int timestamp = 0;
219  foreach (const QString &dir, dirNames) {
220  unsigned int mtime = QFileInfo(dir).lastModified().toTime_t();
221  if (timestamp < mtime) {
222  timestamp = mtime;
223  }
224  }
225 
226  return timestamp;
227 }
228 
229 int KIconCache::defaultIconSize(KIconLoader::Group group) const
230 {
231  if ((group < 0) || (group >= KIconLoader::LastGroup))
232  {
233  kDebug(264) << "Illegal icon group:" << group;
234  return -1;
235  }
236  return d->mDefaultIconSize[group];
237 }
238 
239 void KIconCache::setThemeInfo(const QList<KIconTheme*>& themes)
240 {
241  if (themes.isEmpty()) {
242  for (KIconLoader::Group i = KIconLoader::FirstGroup; i < KIconLoader::LastGroup; ++i) {
243  d->mDefaultIconSize[i] = 0;
244  }
245  return;
246  }
247  // This as to be done always, even if the cache itself is disabled
248  for (KIconLoader::Group i = KIconLoader::FirstGroup; i < KIconLoader::LastGroup; ++i) {
249  d->mDefaultIconSize[i] = themes.first()->defaultSize(i);
250  }
251 
252  if (!isEnabled()) {
253  return;
254  }
255  setValid(false);
256 
257  // Save internal names and dirs of all themes
258  d->mThemeNames.clear();
259  foreach (KIconTheme* theme, themes) {
260  d->mThemeNames.append(theme->internalName());
261  }
262  d->mThemeDirs = existingIconThemeDirs(d->mThemeNames);
263  d->mThemesMTime = mostRecentMTime(d->mThemeDirs);
264  d->mUpdatesCheckedTime= ::time(0);
265 
266  // Recreate the cache
267  recreateCacheFiles();
268 }
269 
270 bool KIconCache::find(const QString& key, QPixmap& pix, QString* path)
271 {
272  d->checkForThemeUpdates();
273 
274  d->mLoadPath = path;
275  // We can use QPixmapCache only if we don't need the path
276  setUseQPixmapCache(!path);
277  //kDebug(264) << "use QPC = " << useQPixmapCache();
278  bool ret = find(key, pix);
279  d->mLoadPath = 0;
280  return ret;
281 }
282 
283 void KIconCache::insert(const QString& key, const QPixmap& pix, const QString& path)
284 {
285  d->mSavePath = path;
286  insert(key, pix);
287  d->mSavePath.clear();
288 }
289 
290 bool KIconCache::find(const QString& key, QPixmap& pix)
291 {
292  // TODO: make sure that cache is still valid
293  return KPixmapCache::find(key, pix);
294 }
295 
296 void KIconCache::insert(const QString& key, const QPixmap& pix)
297 {
298  // TODO: make sure that cache is still valid
299  KPixmapCache::insert(key, pix);
300 }
301 
302 bool KIconCache::loadCustomData(QDataStream& stream)
303 {
304  QString path;
305  stream >> path;
306  if (d->mLoadPath) {
307  *d->mLoadPath = path;
308  }
309 
310  return true;
311 }
312 
313 bool KIconCache::writeCustomData(QDataStream& stream)
314 {
315  stream << d->mSavePath;
316  return true;
317 }
318 
KPixmapCache::setValid
void setValid(bool valid)
Sets whether this cache is valid or not.
Definition: kpixmapcache.cpp:1060
KIconCache::loadCustomData
virtual bool loadCustomData(QDataStream &stream)
Can be used by subclasses to load custom data from the stream.
Definition: kiconcache.cpp:302
kdebug.h
KPixmapCache::insert
virtual void insert(const QString &key, const QPixmap &pix)
Inserts the pixmap pix into the cache, associated with the key key.
Definition: kpixmapcache.cpp:1366
KIconCache::find
bool find(const QString &key, QPixmap &pix, QString *path)
Definition: kiconcache.cpp:270
KGlobal::dirs
KStandardDirs * dirs()
KPixmapCache::timestamp
unsigned int timestamp() const
Definition: kpixmapcache.cpp:1066
KPixmapCache
General-purpose pixmap cache for KDE.
Definition: kpixmapcache.h:85
quint32
KIconCache::writeCustomIndexHeader
virtual void writeCustomIndexHeader(QDataStream &stream)
Can be used by subclasses to write custom data into cache's header.
Definition: kiconcache.cpp:167
QString
kDebug
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KStandardDirs::exists
static bool exists(const QString &fullPath)
KIconCache::loadCustomIndexHeader
virtual bool loadCustomIndexHeader(QDataStream &stream)
Can be used by subclasses to load custom data from cache's header.
Definition: kiconcache.cpp:121
KPixmapCache::recreateCacheFiles
bool recreateCacheFiles()
This function causes the cache files to be recreate by invalidating the cache.
Definition: kpixmapcache.cpp:1156
KStandardGuiItem::Ok
Definition: kstandardguiitem.h:50
kglobal.h
KPixmapCache::find
virtual bool find(const QString &key, QPixmap &pix)
Tries to load pixmap with the specified key from cache.
Definition: kpixmapcache.cpp:1272
KIconCache::~KIconCache
virtual ~KIconCache()
Definition: kiconcache.cpp:111
KPixmapCache::setUseQPixmapCache
void setUseQPixmapCache(bool use)
Sets whether QPixmapCache (memory caching) should be used in addition to disk cache.
Definition: kpixmapcache.cpp:1112
KIconLoader::LastGroup
Last group.
Definition: kiconloader.h:145
QStringList
KIconCache::defaultIconSize
int defaultIconSize(KIconLoader::Group group) const
The default size of current theme for a certain icon group.
Definition: kiconcache.cpp:229
KDE_ICONCACHE_VERSION
#define KDE_ICONCACHE_VERSION
Definition: kiconcache.cpp:39
KPixmapCache::deleteCache
static void deleteCache(const QString &name)
Deletes a pixmap cache.
Definition: kpixmapcache.cpp:1217
KIconCache::deleteCache
static void deleteCache()
Deletes the icon cache.
Definition: kiconcache.cpp:116
QSet< QString >
KIconCache::insert
void insert(const QString &key, const QPixmap &pix, const QString &path)
Definition: kiconcache.cpp:283
KStandardDirs::resourceDirs
QStringList resourceDirs(const char *type) const
KIconCache::writeCustomData
virtual bool writeCustomData(QDataStream &stream)
Can be used by subclasses to write custom data into the stream.
Definition: kiconcache.cpp:313
KIconCache
Icon cache for KDE.
Definition: kiconcache.h:48
KIconCache::Private
friend class Private
Definition: kiconcache.h:90
KStandardDirs::locateLocal
static QString locateLocal(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
kstandarddirs.h
version
unsigned int version()
KIconLoader::Group
Group
The group of the icon.
Definition: kiconloader.h:127
kiconcache.h
KIconCache::mostRecentMTime
unsigned int mostRecentMTime(const QSet< QString > &dirNames) const
Definition: kiconcache.cpp:216
kWarning
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
qint32
KIconLoader::FirstGroup
First group.
Definition: kiconloader.h:133
KIconCache::KIconCache
KIconCache()
Constucts the icon cache object.
Definition: kiconcache.cpp:103
KDE_ICONCACHE_NAME
#define KDE_ICONCACHE_NAME
Definition: kiconcache.cpp:38
KPixmapCache::setCacheLimit
void setCacheLimit(int kbytes)
Sets the maximum size of the cache (in kilobytes).
Definition: kpixmapcache.cpp:1127
KIconCache::setThemeInfo
void setThemeInfo(const QList< KIconTheme * > &themes)
Definition: kiconcache.cpp:239
KIconCache::existingIconThemeDirs
QSet< QString > existingIconThemeDirs(const QStringList &themeNames) const
Definition: kiconcache.cpp:189
KIconTheme
Definition: kicontheme.h:46
KPixmapCache::isEnabled
bool isEnabled() const
Cache will be disabled when e.g.
Definition: kpixmapcache.cpp:1048
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
QList
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:49:14 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
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



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

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