• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • 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         const 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         const 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     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     icondirs.removeDuplicates();
00199 
00200     // Check which of theme actually contain existing dir of one of the
00201     //  given themes
00202     QSet<QString> dirs;
00203     for (QStringList::ConstIterator it = icondirs.constBegin(); it != icondirs.constEnd(); ++it) {
00204         QStringList::ConstIterator themeIt;
00205         for (themeIt = themeNames.begin(); themeIt != themeNames.end(); ++themeIt) {
00206             QString dirName = *it + *themeIt + '/';
00207             if (KStandardDirs::exists(dirName)) {
00208                 dirs.insert(dirName);
00209             }
00210         }
00211     }
00212 
00213     return dirs;
00214 }
00215 
00216 unsigned int KIconCache::mostRecentMTime(const QSet<QString>& dirNames) const
00217 {
00218     unsigned int timestamp = 0;
00219     foreach (const QString &dir, dirNames) {
00220         unsigned int mtime = QFileInfo(dir).lastModified().toTime_t();
00221         if (timestamp < mtime) {
00222             timestamp = mtime;
00223         }
00224     }
00225 
00226     return timestamp;
00227 }
00228 
00229 int KIconCache::defaultIconSize(KIconLoader::Group group) const
00230 {
00231     if ((group < 0) || (group >= KIconLoader::LastGroup))
00232     {
00233         kDebug(264) << "Illegal icon group:" << group;
00234         return -1;
00235     }
00236     return d->mDefaultIconSize[group];
00237 }
00238 
00239 void KIconCache::setThemeInfo(const QList<KIconTheme*>& themes)
00240 {
00241     if (themes.isEmpty()) {
00242         for (KIconLoader::Group i = KIconLoader::FirstGroup; i < KIconLoader::LastGroup; ++i) {
00243             d->mDefaultIconSize[i] = 0;
00244         }
00245         return;
00246     }
00247     // This as to be done always, even if the cache itself is disabled
00248     for (KIconLoader::Group i = KIconLoader::FirstGroup; i < KIconLoader::LastGroup; ++i) {
00249         d->mDefaultIconSize[i] = themes.first()->defaultSize(i);
00250     }
00251 
00252     if (!isEnabled()) {
00253         return;
00254     }
00255     setValid(false);
00256 
00257     // Save internal names and dirs of all themes
00258     d->mThemeNames.clear();
00259     foreach (KIconTheme* theme, themes) {
00260         d->mThemeNames.append(theme->internalName());
00261     }
00262     d->mThemeDirs = existingIconThemeDirs(d->mThemeNames);
00263     d->mThemesMTime = mostRecentMTime(d->mThemeDirs);
00264     d->mUpdatesCheckedTime= ::time(0);
00265 
00266     // Recreate the cache
00267     recreateCacheFiles();
00268 }
00269 
00270 bool KIconCache::find(const QString& key, QPixmap& pix, QString* path)
00271 {
00272     d->checkForThemeUpdates();
00273 
00274     d->mLoadPath = path;
00275     // We can use QPixmapCache only if we don't need the path
00276     setUseQPixmapCache(!path);
00277     //kDebug(264) << "use QPC = " << useQPixmapCache();
00278     bool ret = find(key, pix);
00279     d->mLoadPath = 0;
00280     return ret;
00281 }
00282 
00283 void KIconCache::insert(const QString& key, const QPixmap& pix, const QString& path)
00284 {
00285     d->mSavePath = path;
00286     insert(key, pix);
00287     d->mSavePath.clear();
00288 }
00289 
00290 bool KIconCache::find(const QString& key, QPixmap& pix)
00291 {
00292     // TODO: make sure that cache is still valid
00293     return KPixmapCache::find(key, pix);
00294 }
00295 
00296 void KIconCache::insert(const QString& key, const QPixmap& pix)
00297 {
00298     // TODO: make sure that cache is still valid
00299     KPixmapCache::insert(key, pix);
00300 }
00301 
00302 bool KIconCache::loadCustomData(QDataStream& stream)
00303 {
00304     QString path;
00305     stream >> path;
00306     if (d->mLoadPath) {
00307         *d->mLoadPath = path;
00308     }
00309 
00310     return true;
00311 }
00312 
00313 bool KIconCache::writeCustomData(QDataStream& stream)
00314 {
00315     stream << d->mSavePath;
00316     return true;
00317 }
00318 

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
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
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