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

KDEUI

kiconcache.cpp

Go to the documentation of this file.
00001 /*
00002  *
00003  * This file is part of the KDE project.
00004  * Copyright (C) 2007 Rivo Laks <rivolaks@hot.ee>
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License version 2 as published by the Free Software Foundation.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public License
00016  * along with this library; see the file COPYING.LIB.  If not, write to
00017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019  */
00020 
00021 #include "kiconcache.h"
00022 
00023 #include <QtCore/QString>
00024 #include <QtGui/QPixmap>
00025 #include <QtCore/QFile>
00026 #include <QtCore/QDataStream>
00027 #include <QtCore/QFileInfo>
00028 #include <QtCore/QDateTime>
00029 
00030 #include <kglobal.h>
00031 #include <kstandarddirs.h>
00032 #include <kdebug.h>
00033 
00034 #include <sys/file.h>
00035 #include <time.h>
00036 
00037 
00038 #define KDE_ICONCACHE_NAME "kde-icon-cache"
00039 #define KDE_ICONCACHE_VERSION 0x000100
00040 
00041 
00042 class KIconCache::Private
00043 {
00044 public:
00045     Private(KIconCache* _q)
00046     {
00047         q = _q;
00048         mUpdatesCheckedTime = 0;
00049     }
00050     bool themeDirsChanged()
00051     {
00052         if (q->existingIconThemeDirs(mThemeNames) != mThemeDirs ||
00053             q->mostRecentMTime(mThemeDirs) != mThemesMTime) {
00054             kDebug(264) << "Theme directory has been modified";
00055             return true;
00056         } else {
00057             return false;
00058         }
00059     }
00060     void checkForThemeUpdates()
00061     {
00062         if (!q->isEnabled()) {
00063             return;
00064         }
00065         // Don't check more often than every 5 secs
00066         quint32 now = ::time(0);
00067         if (now < mUpdatesCheckedTime + 5) {
00068             return;
00069         }
00070 
00071         mUpdatesCheckedTime = now;
00072         // Perhaps another process has already checked for updates in last 5 secs
00073         QFileInfo fi(mUpdatesFile);
00074         if (fi.exists() && fi.lastModified().toTime_t() + 5 > now) {
00075             return;
00076         }
00077         // Check for theme updates
00078         if (themeDirsChanged()) {
00079             // Update themes info and discard the cache
00080             mThemeDirs = q->existingIconThemeDirs(mThemeNames);
00081             mThemesMTime = q->mostRecentMTime(mThemeDirs);
00082             q->discard();
00083         }
00084         // Update timestamp file
00085         QFile f(mUpdatesFile);
00086         f.open(QIODevice::WriteOnly);
00087     }
00088 
00089     KIconCache* q;
00090 
00091     qint32 mDefaultIconSize[6];
00092     QStringList mThemeNames;
00093     QSet<QString> mThemeDirs;
00094     quint32 mThemesMTime;
00095     QString mUpdatesFile;
00096     quint32 mUpdatesCheckedTime;
00097 
00098     QString* mLoadPath;
00099     QString mSavePath;
00100 };
00101 
00102 
00103 KIconCache::KIconCache()
00104     : KPixmapCache(KDE_ICONCACHE_NAME), d(new Private(this))
00105 {
00106     d->mUpdatesFile  = KGlobal::dirs()->locateLocal("cache", "kpc/"KDE_ICONCACHE_NAME".updated");
00107     // Set limit to 10 MB
00108     setCacheLimit(10 * 1024);
00109 }
00110 
00111 KIconCache::~KIconCache()
00112 {
00113     delete d;
00114 }
00115 
00116 void KIconCache::deleteCache()
00117 {
00118     KPixmapCache::deleteCache(KDE_ICONCACHE_NAME);
00119 }
00120 
00121 bool KIconCache::loadCustomIndexHeader(QDataStream& stream)
00122 {
00123     if (stream.atEnd()) {
00124         return false;
00125     }
00126 
00127     // Load version
00128     quint32 version;
00129     stream >> version;
00130     if (version != KDE_ICONCACHE_VERSION) {
00131         kDebug(264) << "Obsolete iconcache version" << version << "will recreate";
00132         return false;
00133     }
00134 
00135     // Load default sizes of icons
00136     for (int i = 0; i < 6; i++) {
00137         stream >> d->mDefaultIconSize[i];
00138     }
00139 
00140 
00141     stream >> d->mThemeNames;
00142     stream >> d->mThemeDirs;
00143     // TODO: use KPixmapCache's timestamp instead
00144     stream >> d->mThemesMTime;
00145 
00146     if (stream.status() != QDataStream::Ok) {
00147         kWarning() << "Failed to read index file's header";
00148         recreateCacheFiles();
00149         return false;
00150     }
00151 
00152     // Make sure at least one theme was read
00153     if (!d->mThemeNames.count()) {
00154         kDebug(264) << "Empty themes list";
00155         return false;
00156     }
00157 
00158     // Make sure the theme dirs haven't changed
00159     if (d->themeDirsChanged()) {
00160         return false;
00161     }
00162     d->mUpdatesCheckedTime= ::time(0);
00163 
00164     return true;
00165 }
00166 
00167 void KIconCache::writeCustomIndexHeader(QDataStream& stream)
00168 {
00169     setValid(false);
00170 
00171     stream << (quint32)KDE_ICONCACHE_VERSION;
00172 
00173     for (int i = 0; i < 6; i++) {
00174         stream << d->mDefaultIconSize[i];
00175     }
00176 
00177     // Save iconthemes info
00178     stream << d->mThemeNames;
00179     stream << d->mThemeDirs;
00180     stream << d->mThemesMTime;
00181 
00182     // Cache is valid if header was successfully written and we actually have
00183     //  the icontheme name(s)
00184     if (stream.status() == QDataStream::Ok && d->mThemeNames.count()) {
00185         setValid(true);
00186     }
00187 }
00188 
00189 QSet<QString> KIconCache::existingIconThemeDirs(const QStringList& themeNames) const
00190 {
00191     // Find all possible icontheme dirs
00192     // This has been taken from kicontheme.cpp
00193     const QStringList icondirs = KGlobal::dirs()->resourceDirs("icon")
00194             << KGlobal::dirs()->resourceDirs("xdgdata-icon")
00195             << "/usr/share/pixmaps"
00196             // These are not in the icon spec, but e.g. GNOME puts some icons there anyway.
00197             << KGlobal::dirs()->resourceDirs("xdgdata-pixmap");
00198 
00199     // Check which of theme actually contain existing dir of one of the
00200     //  given themes
00201     QSet<QString> dirs;
00202     for (QStringList::ConstIterator it = icondirs.begin(); it != icondirs.end(); ++it) {
00203         QStringList::ConstIterator themeIt;
00204         for (themeIt = themeNames.begin(); themeIt != themeNames.end(); ++themeIt) {
00205             QString dirName = *it + *themeIt + '/';
00206             if (KStandardDirs::exists(dirName)) {
00207                 dirs.insert(dirName);
00208             }
00209         }
00210     }
00211 
00212     return dirs;
00213 }
00214 
00215 unsigned int KIconCache::mostRecentMTime(const QSet<QString>& dirNames) const
00216 {
00217     unsigned int timestamp = 0;
00218     foreach (const QString &dir, dirNames) {
00219         unsigned int mtime = QFileInfo(dir).lastModified().toTime_t();
00220         if (timestamp < mtime) {
00221             timestamp = mtime;
00222         }
00223     }
00224 
00225     return timestamp;
00226 }
00227 
00228 int KIconCache::defaultIconSize(KIconLoader::Group group) const
00229 {
00230     if ((group < 0) || (group >= KIconLoader::LastGroup))
00231     {
00232         kDebug(264) << "Illegal icon group:" << group;
00233         return -1;
00234     }
00235     return d->mDefaultIconSize[group];
00236 }
00237 
00238 void KIconCache::setThemeInfo(const QList<KIconTheme*>& themes)
00239 {
00240     if (themes.isEmpty()) {
00241         for (KIconLoader::Group i = KIconLoader::FirstGroup; i < KIconLoader::LastGroup; i++) {
00242             d->mDefaultIconSize[i] = 0;
00243         }
00244         return;
00245     }
00246     // This as to be done always, even if the cache itself is disabled
00247     for (KIconLoader::Group i = KIconLoader::FirstGroup; i < KIconLoader::LastGroup; i++) {
00248         d->mDefaultIconSize[i] = themes.first()->defaultSize(i);
00249     }
00250 
00251     if (!isEnabled()) {
00252         return;
00253     }
00254     setValid(false);
00255 
00256     // Save internal names and dirs of all themes
00257     d->mThemeNames.clear();
00258     foreach (KIconTheme* theme, themes) {
00259         d->mThemeNames.append(theme->internalName());
00260     }
00261     d->mThemeDirs = existingIconThemeDirs(d->mThemeNames);
00262     d->mThemesMTime = mostRecentMTime(d->mThemeDirs);
00263     d->mUpdatesCheckedTime= ::time(0);
00264 
00265     // Recreate the cache
00266     recreateCacheFiles();
00267 }
00268 
00269 bool KIconCache::find(const QString& key, QPixmap& pix, QString* path)
00270 {
00271     d->checkForThemeUpdates();
00272 
00273     d->mLoadPath = path;
00274     // We can use QPixmapCache only if we don't need the path
00275     setUseQPixmapCache(!path);
00276     //kDebug(264) << "use QPC = " << useQPixmapCache();
00277     bool ret = find(key, pix);
00278     d->mLoadPath = 0;
00279     return ret;
00280 }
00281 
00282 void KIconCache::insert(const QString& key, const QPixmap& pix, const QString& path)
00283 {
00284     d->mSavePath = path;
00285     insert(key, pix);
00286     d->mSavePath = QString();
00287 }
00288 
00289 bool KIconCache::find(const QString& key, QPixmap& pix)
00290 {
00291     // TODO: make sure that cache is still valid
00292     return KPixmapCache::find(key, pix);
00293 }
00294 
00295 void KIconCache::insert(const QString& key, const QPixmap& pix)
00296 {
00297     // TODO: make sure that cache is still valid
00298     KPixmapCache::insert(key, pix);
00299 }
00300 
00301 bool KIconCache::loadCustomData(QDataStream& stream)
00302 {
00303     QString path;
00304     stream >> path;
00305     if (d->mLoadPath) {
00306         *d->mLoadPath = path;
00307     }
00308 
00309     return true;
00310 }
00311 
00312 bool KIconCache::writeCustomData(QDataStream& stream)
00313 {
00314     stream << d->mSavePath;
00315     return true;
00316 }
00317 

KDEUI

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal