kiconloader.cpp

00001 /* vi: ts=8 sts=4 sw=4
00002  *
00003  * $Id: kiconloader.cpp 601485 2006-11-03 12:50:30Z lunakl $
00004  *
00005  * This file is part of the KDE project, module kdecore.
00006  * Copyright (C) 2000 Geert Jansen <jansen@kde.org>
00007  *                    Antonio Larrosa <larrosa@kde.org>
00008  *
00009  * This is free software; it comes under the GNU Library General
00010  * Public License, version 2. See the file "COPYING.LIB" for the
00011  * exact licensing terms.
00012  *
00013  * kiconloader.cpp: An icon loader for KDE with theming functionality.
00014  */
00015 
00016 #include <qstring.h>
00017 #include <qstringlist.h>
00018 #include <qptrlist.h>
00019 #include <qintdict.h>
00020 #include <qpixmap.h>
00021 #include <qpixmapcache.h>
00022 #include <qimage.h>
00023 #include <qfileinfo.h>
00024 #include <qdir.h>
00025 #include <qiconset.h>
00026 #include <qmovie.h>
00027 #include <qbitmap.h>
00028 
00029 #include <kapplication.h>
00030 #include <kipc.h>
00031 #include <kdebug.h>
00032 #include <kstandarddirs.h>
00033 #include <kglobal.h>
00034 #include <kconfig.h>
00035 #include <ksimpleconfig.h>
00036 #include <kinstance.h>
00037 
00038 #include <kicontheme.h>
00039 #include <kiconloader.h>
00040 #include <kiconeffect.h>
00041 
00042 #include <sys/types.h>
00043 #include <stdlib.h> //for abs
00044 #include <unistd.h>     //for readlink
00045 #include <dirent.h>
00046 #include <config.h>
00047 #include <assert.h>
00048 
00049 #ifdef HAVE_LIBART
00050 #include "svgicons/ksvgiconengine.h"
00051 #include "svgicons/ksvgiconpainter.h"
00052 #endif
00053 
00054 #include "kiconloader_p.h"
00055 
00056 /*** KIconThemeNode: A node in the icon theme dependancy tree. ***/
00057 
00058 KIconThemeNode::KIconThemeNode(KIconTheme *_theme)
00059 {
00060     theme = _theme;
00061 }
00062 
00063 KIconThemeNode::~KIconThemeNode()
00064 {
00065     delete theme;
00066 }
00067 
00068 void KIconThemeNode::printTree(QString& dbgString) const
00069 {
00070     /* This method doesn't have much sense anymore, so maybe it should
00071        be removed in the (near?) future */
00072     dbgString += "(";
00073     dbgString += theme->name();
00074     dbgString += ")";
00075 }
00076 
00077 void KIconThemeNode::queryIcons(QStringList *result,
00078                 int size, KIcon::Context context) const
00079 {
00080     // add the icons of this theme to it
00081     *result += theme->queryIcons(size, context);
00082 }
00083 
00084 void KIconThemeNode::queryIconsByContext(QStringList *result,
00085                 int size, KIcon::Context context) const
00086 {
00087     // add the icons of this theme to it
00088     *result += theme->queryIconsByContext(size, context);
00089 }
00090 
00091 KIcon KIconThemeNode::findIcon(const QString& name, int size,
00092                    KIcon::MatchType match) const
00093 {
00094     return theme->iconPath(name, size, match);
00095 }
00096 
00097 
00098 /*** KIconGroup: Icon type description. ***/
00099 
00100 struct KIconGroup
00101 {
00102     int size;
00103     bool dblPixels;
00104     bool alphaBlending;
00105 };
00106 
00107 #define KICONLOADER_CHECKS
00108 #ifdef KICONLOADER_CHECKS
00109 // Keep a list of recently created and destroyed KIconLoader instances in order
00110 // to detect bugs like #68528.
00111 struct KIconLoaderDebug
00112     {
00113     KIconLoaderDebug( KIconLoader* l, const QString& a )
00114         : loader( l ), appname( a ), valid( true )
00115         {}
00116     KIconLoaderDebug() {}; // this QValueList feature annoys me
00117     KIconLoader* loader;
00118     QString appname;
00119     bool valid;
00120     QString delete_bt;
00121     };
00122 
00123 static QValueList< KIconLoaderDebug > *kiconloaders;
00124 #endif
00125 
00126 /*** KIconLoader: the icon loader ***/
00127 
00128 KIconLoader::KIconLoader(const QString& _appname, KStandardDirs *_dirs)
00129 {
00130 #ifdef KICONLOADER_CHECKS
00131     if( kiconloaders == NULL )
00132         kiconloaders = new QValueList< KIconLoaderDebug>();
00133     // check for the (very unlikely case) that new KIconLoader gets allocated
00134     // at exactly same address like some previous one
00135     for( QValueList< KIconLoaderDebug >::Iterator it = kiconloaders->begin();
00136          it != kiconloaders->end();
00137          )
00138         {
00139         if( (*it).loader == this )
00140             it = kiconloaders->remove( it );
00141         else
00142             ++it;
00143         }
00144     kiconloaders->append( KIconLoaderDebug( this, _appname ));
00145 #endif
00146     d = new KIconLoaderPrivate;
00147     d->q = this;
00148     d->mpGroups = 0L;
00149     d->imgDict.setAutoDelete(true);
00150     d->links.setAutoDelete(true);
00151 
00152     if (kapp) {
00153         kapp->addKipcEventMask(KIPC::IconChanged);
00154         QObject::connect(kapp, SIGNAL(updateIconLoaders()), d, SLOT(reconfigure()));
00155     }
00156 
00157     init( _appname, _dirs );
00158 }
00159 
00160 void KIconLoader::reconfigure( const QString& _appname, KStandardDirs *_dirs )
00161 {
00162     d->links.clear();
00163     d->imgDict.clear();
00164     d->mThemesInTree.clear();
00165     d->lastImage.reset();
00166     d->lastImageKey = QString::null;
00167     delete [] d->mpGroups;
00168 
00169     init( _appname, _dirs );
00170 }
00171 
00172 void KIconLoader::init( const QString& _appname, KStandardDirs *_dirs )
00173 {
00174     // If this is unequal to 0, the iconloader is initialized
00175     // successfully.
00176     d->mpThemeRoot = 0L;
00177 
00178     d->appname = _appname;
00179     d->extraDesktopIconsLoaded = false;
00180     d->delayedLoading = false;
00181 
00182     if (_dirs)
00183         d->mpDirs = _dirs;
00184     else
00185         d->mpDirs = KGlobal::dirs();
00186 
00187     QString appname = _appname;
00188     if (appname.isEmpty())
00189         appname = KGlobal::instance()->instanceName();
00190 
00191     // Add the default theme and its base themes to the theme tree
00192     KIconTheme *def = new KIconTheme(KIconTheme::current(), appname);
00193     if (!def->isValid())
00194     {
00195         delete def;
00196         // warn, as this is actually a small penalty hit
00197         kdDebug(264) << "Couldn't find current icon theme, falling back to default." << endl;
00198     def = new KIconTheme(KIconTheme::defaultThemeName(), appname);
00199         if (!def->isValid())
00200         {
00201             kdError(264) << "Error: standard icon theme"
00202                          << " \"" << KIconTheme::defaultThemeName() << "\" "
00203                          << " not found!" << endl;
00204             d->mpGroups=0L;
00205             return;
00206         }
00207     }
00208     d->mpThemeRoot = new KIconThemeNode(def);
00209     d->links.append(d->mpThemeRoot);
00210     d->mThemesInTree += KIconTheme::current();
00211     addBaseThemes(d->mpThemeRoot, appname);
00212 
00213     // These have to match the order in kicontheme.h
00214     static const char * const groups[] = { "Desktop", "Toolbar", "MainToolbar", "Small", "Panel", 0L };
00215     KConfig *config = KGlobal::config();
00216     KConfigGroupSaver cs(config, "dummy");
00217 
00218     // loading config and default sizes
00219     d->mpGroups = new KIconGroup[(int) KIcon::LastGroup];
00220     for (KIcon::Group i=KIcon::FirstGroup; i<KIcon::LastGroup; i++)
00221     {
00222     if (groups[i] == 0L)
00223         break;
00224     config->setGroup(QString::fromLatin1(groups[i]) + "Icons");
00225     d->mpGroups[i].size = config->readNumEntry("Size", 0);
00226     d->mpGroups[i].dblPixels = config->readBoolEntry("DoublePixels", false);
00227     if (QPixmap::defaultDepth()>8)
00228         d->mpGroups[i].alphaBlending = config->readBoolEntry("AlphaBlending", true);
00229     else
00230         d->mpGroups[i].alphaBlending = false;
00231 
00232     if (!d->mpGroups[i].size)
00233         d->mpGroups[i].size = d->mpThemeRoot->theme->defaultSize(i);
00234     }
00235 
00236     // Insert application specific themes at the top.
00237     d->mpDirs->addResourceType("appicon", KStandardDirs::kde_default("data") +
00238         appname + "/pics/");
00239     // ################## KDE4: consider removing the toolbar directory
00240     d->mpDirs->addResourceType("appicon", KStandardDirs::kde_default("data") +
00241         appname + "/toolbar/");
00242 
00243     // Add legacy icon dirs.
00244     QStringList dirs;
00245     dirs += d->mpDirs->resourceDirs("icon");
00246     dirs += d->mpDirs->resourceDirs("pixmap");
00247     dirs += d->mpDirs->resourceDirs("xdgdata-icon");
00248     dirs += "/usr/share/pixmaps";
00249     // These are not in the icon spec, but e.g. GNOME puts some icons there anyway.
00250     dirs += d->mpDirs->resourceDirs("xdgdata-pixmap");
00251     for (QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it)
00252     d->mpDirs->addResourceDir("appicon", *it);
00253 
00254 #ifndef NDEBUG
00255     QString dbgString = "Theme tree: ";
00256     d->mpThemeRoot->printTree(dbgString);
00257     kdDebug(264) << dbgString << endl;
00258 #endif
00259 }
00260 
00261 KIconLoader::~KIconLoader()
00262 {
00263 #ifdef KICONLOADER_CHECKS
00264     for( QValueList< KIconLoaderDebug >::Iterator it = kiconloaders->begin();
00265          it != kiconloaders->end();
00266          ++it )
00267         {
00268         if( (*it).loader == this )
00269             {
00270             (*it).valid = false;
00271             (*it).delete_bt = kdBacktrace();
00272             break;
00273             }
00274         }
00275 #endif
00276     /* antlarr: There's no need to delete d->mpThemeRoot as it's already
00277        deleted when the elements of d->links are deleted */
00278     d->mpThemeRoot=0;
00279     delete[] d->mpGroups;
00280     delete d;
00281 }
00282 
00283 void KIconLoader::enableDelayedIconSetLoading( bool enable )
00284 {
00285     d->delayedLoading = enable;
00286 }
00287 
00288 bool KIconLoader::isDelayedIconSetLoadingEnabled() const
00289 {
00290     return d->delayedLoading;
00291 }
00292 
00293 void KIconLoader::addAppDir(const QString& appname)
00294 {
00295     d->mpDirs->addResourceType("appicon", KStandardDirs::kde_default("data") +
00296         appname + "/pics/");
00297     // ################## KDE4: consider removing the toolbar directory
00298     d->mpDirs->addResourceType("appicon", KStandardDirs::kde_default("data") +
00299         appname + "/toolbar/");
00300     addAppThemes(appname);
00301 }
00302 
00303 void KIconLoader::addAppThemes(const QString& appname)
00304 {
00305     if ( KIconTheme::current() != KIconTheme::defaultThemeName() )
00306     {
00307         KIconTheme *def = new KIconTheme(KIconTheme::current(), appname);
00308         if (def->isValid())
00309         {
00310             KIconThemeNode* node = new KIconThemeNode(def);
00311             d->links.append(node);
00312             addBaseThemes(node, appname);
00313         }
00314         else
00315             delete def;
00316     }
00317 
00318     KIconTheme *def = new KIconTheme(KIconTheme::defaultThemeName(), appname);
00319     KIconThemeNode* node = new KIconThemeNode(def);
00320     d->links.append(node);
00321     addBaseThemes(node, appname);
00322 }
00323 
00324 void KIconLoader::addBaseThemes(KIconThemeNode *node, const QString &appname)
00325 {
00326     QStringList lst = node->theme->inherits();
00327     QStringList::ConstIterator it;
00328 
00329     for (it=lst.begin(); it!=lst.end(); ++it)
00330     {
00331     if( d->mThemesInTree.contains(*it) && (*it) != "hicolor")
00332         continue;
00333     KIconTheme *theme = new KIconTheme(*it,appname);
00334     if (!theme->isValid()) {
00335         delete theme;
00336         continue;
00337     }
00338         KIconThemeNode *n = new KIconThemeNode(theme);
00339     d->mThemesInTree.append(*it);
00340     d->links.append(n);
00341     addBaseThemes(n, appname);
00342     }
00343 }
00344 
00345 void KIconLoader::addExtraDesktopThemes()
00346 {
00347     if ( d->extraDesktopIconsLoaded ) return;
00348 
00349     QStringList list;
00350     QStringList icnlibs = KGlobal::dirs()->resourceDirs("icon");
00351     QStringList::ConstIterator it;
00352     char buf[1000];
00353     int r;
00354     for (it=icnlibs.begin(); it!=icnlibs.end(); ++it)
00355     {
00356     QDir dir(*it);
00357     if (!dir.exists())
00358         continue;
00359     QStringList lst = dir.entryList("default.*", QDir::Dirs);
00360     QStringList::ConstIterator it2;
00361     for (it2=lst.begin(); it2!=lst.end(); ++it2)
00362     {
00363         if (!KStandardDirs::exists(*it + *it2 + "/index.desktop")
00364         && !KStandardDirs::exists(*it + *it2 + "/index.theme"))
00365         continue;
00366         r=readlink( QFile::encodeName(*it + *it2) , buf, sizeof(buf)-1);
00367         if ( r>0 )
00368         {
00369           buf[r]=0;
00370           QDir dir2( buf );
00371           QString themeName=dir2.dirName();
00372 
00373           if (!list.contains(themeName))
00374         list.append(themeName);
00375         }
00376     }
00377     }
00378 
00379     for (it=list.begin(); it!=list.end(); ++it)
00380     {
00381     if ( d->mThemesInTree.contains(*it) )
00382         continue;
00383     if ( *it == QString("default.kde") ) continue;
00384 
00385     KIconTheme *def = new KIconTheme( *it, "" );
00386     KIconThemeNode* node = new KIconThemeNode(def);
00387     d->mThemesInTree.append(*it);
00388     d->links.append(node);
00389     addBaseThemes(node, "" );
00390     }
00391 
00392     d->extraDesktopIconsLoaded=true;
00393 
00394 }
00395 
00396 bool KIconLoader::extraDesktopThemesAdded() const
00397 {
00398     return d->extraDesktopIconsLoaded;
00399 }
00400 
00401 QString KIconLoader::removeIconExtension(const QString &name) const
00402 {
00403     int extensionLength=0;
00404 
00405     QString ext = name.right(4);
00406 
00407     static const QString &png_ext = KGlobal::staticQString(".png");
00408     static const QString &xpm_ext = KGlobal::staticQString(".xpm");
00409     if (ext == png_ext || ext == xpm_ext)
00410       extensionLength=4;
00411 #ifdef HAVE_LIBART
00412     else
00413     {
00414     static const QString &svgz_ext = KGlobal::staticQString(".svgz");
00415     static const QString &svg_ext = KGlobal::staticQString(".svg");
00416 
00417     if (name.right(5) == svgz_ext)
00418         extensionLength=5;
00419     else if (ext == svg_ext)
00420         extensionLength=4;
00421     }
00422 #endif
00423 
00424     if ( extensionLength > 0 )
00425     {
00426     return name.left(name.length() - extensionLength);
00427     }
00428     return name;
00429 }
00430 
00431 QString KIconLoader::removeIconExtensionInternal(const QString &name) const
00432 {
00433     QString name_noext = removeIconExtension(name);
00434 
00435 #ifndef NDEBUG
00436     if (name != name_noext)
00437     {
00438     kdDebug(264) << "Application " << KGlobal::instance()->instanceName()
00439              << " loads icon " << name << " with extension." << endl;
00440     }
00441 #endif
00442 
00443     return name_noext;
00444 }
00445 
00446 KIcon KIconLoader::findMatchingIcon(const QString& name, int size) const
00447 {
00448     KIcon icon;
00449 
00450     const QString *ext[4];
00451     int count=0;
00452     static const QString &png_ext = KGlobal::staticQString(".png");
00453     ext[count++]=&png_ext;
00454 #ifdef HAVE_LIBART
00455     static const QString &svgz_ext = KGlobal::staticQString(".svgz");
00456     ext[count++]=&svgz_ext;
00457     static const QString &svg_ext = KGlobal::staticQString(".svg");
00458     ext[count++]=&svg_ext;
00459 #endif
00460     static const QString &xpm_ext = KGlobal::staticQString(".xpm");
00461     ext[count++]=&xpm_ext;
00462 
00463     /* antlarr: Multiple inheritance is a broken concept on icon themes, so
00464        the next code doesn't support it on purpose because in fact, it was
00465        never supported at all. This makes the order in which we look for an
00466        icon as:
00467 
00468        png, svgz, svg, xpm exact match
00469        next theme in inheritance tree : png, svgz, svg, xpm exact match
00470        next theme in inheritance tree : png, svgz, svg, xpm exact match
00471        and so on
00472 
00473        And if the icon couldn't be found then it tries best match in the same
00474        order.
00475 
00476        */
00477     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
00478     themeNode = d->links.next() )
00479     {
00480     for (int i = 0 ; i < count ; i++)
00481     {
00482         icon = themeNode->theme->iconPath(name + *ext[i], size, KIcon::MatchExact);
00483         if (icon.isValid())
00484         return icon;
00485     }
00486 
00487     }
00488 
00489     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
00490     themeNode = d->links.next() )
00491     {
00492     for (int i = 0 ; i < count ; i++)
00493     {
00494         icon = themeNode->theme->iconPath(name + *ext[i], size, KIcon::MatchBest);
00495         if (icon.isValid())
00496         return icon;
00497     }
00498 
00499     }
00500 
00501     return icon;
00502 }
00503 
00504 inline QString KIconLoader::unknownIconPath( int size ) const
00505 {
00506     static const QString &str_unknown = KGlobal::staticQString("unknown");
00507 
00508     KIcon icon = findMatchingIcon(str_unknown, size);
00509     if (!icon.isValid())
00510     {
00511         kdDebug(264) << "Warning: could not find \"Unknown\" icon for size = "
00512                      << size << endl;
00513         return QString::null;
00514     }
00515     return icon.path;
00516 }
00517 
00518 // Finds the absolute path to an icon.
00519 
00520 QString KIconLoader::iconPath(const QString& _name, int group_or_size,
00521                   bool canReturnNull) const
00522 {
00523     if (d->mpThemeRoot == 0L)
00524     return QString::null;
00525 
00526     if (!QDir::isRelativePath(_name))
00527     return _name;
00528 
00529     QString name = removeIconExtensionInternal( _name );
00530 
00531     QString path;
00532     if (group_or_size == KIcon::User)
00533     {
00534     static const QString &png_ext = KGlobal::staticQString(".png");
00535     static const QString &xpm_ext = KGlobal::staticQString(".xpm");
00536     path = d->mpDirs->findResource("appicon", name + png_ext);
00537 
00538 #ifdef HAVE_LIBART
00539     static const QString &svgz_ext = KGlobal::staticQString(".svgz");
00540     static const QString &svg_ext = KGlobal::staticQString(".svg");
00541     if (path.isEmpty())
00542         path = d->mpDirs->findResource("appicon", name + svgz_ext);
00543     if (path.isEmpty())
00544        path = d->mpDirs->findResource("appicon", name + svg_ext);
00545 #endif
00546     if (path.isEmpty())
00547          path = d->mpDirs->findResource("appicon", name + xpm_ext);
00548     return path;
00549     }
00550 
00551     if (group_or_size >= KIcon::LastGroup)
00552     {
00553     kdDebug(264) << "Illegal icon group: " << group_or_size << endl;
00554     return path;
00555     }
00556 
00557     int size;
00558     if (group_or_size >= 0)
00559     size = d->mpGroups[group_or_size].size;
00560     else
00561     size = -group_or_size;
00562 
00563     if (_name.isEmpty()) {
00564         if (canReturnNull)
00565             return QString::null;
00566         else
00567             return unknownIconPath(size);
00568     }
00569 
00570     KIcon icon = findMatchingIcon(name, size);
00571 
00572     if (!icon.isValid())
00573     {
00574     // Try "User" group too.
00575     path = iconPath(name, KIcon::User, true);
00576     if (!path.isEmpty() || canReturnNull)
00577         return path;
00578 
00579     if (canReturnNull)
00580         return QString::null;
00581         else
00582             return unknownIconPath(size);
00583     }
00584     return icon.path;
00585 }
00586 
00587 QPixmap KIconLoader::loadIcon(const QString& _name, KIcon::Group group, int size,
00588                               int state, QString *path_store, bool canReturnNull) const
00589 {
00590     QString name = _name;
00591     QPixmap pix;
00592     QString key;
00593     bool absolutePath=false, favIconOverlay=false;
00594 
00595     if (d->mpThemeRoot == 0L)
00596     return pix;
00597 
00598     // Special case for absolute path icons.
00599     if (name.startsWith("favicons/"))
00600     {
00601        favIconOverlay = true;
00602        name = locateLocal("cache", name+".png");
00603     }
00604     if (!QDir::isRelativePath(name)) absolutePath=true;
00605 
00606     static const QString &str_unknown = KGlobal::staticQString("unknown");
00607 
00608     // Special case for "User" icons.
00609     if (group == KIcon::User)
00610     {
00611     key = "$kicou_";
00612         key += QString::number(size); key += '_';
00613     key += name;
00614     bool inCache = QPixmapCache::find(key, pix);
00615     if (inCache && (path_store == 0L))
00616         return pix;
00617 
00618     QString path = (absolutePath) ? name :
00619             iconPath(name, KIcon::User, canReturnNull);
00620     if (path.isEmpty())
00621     {
00622         if (canReturnNull)
00623         return pix;
00624         // We don't know the desired size: use small
00625         path = iconPath(str_unknown, KIcon::Small, true);
00626         if (path.isEmpty())
00627         {
00628         kdDebug(264) << "Warning: Cannot find \"unknown\" icon." << endl;
00629         return pix;
00630         }
00631     }
00632 
00633     if (path_store != 0L)
00634         *path_store = path;
00635     if (inCache)
00636         return pix;
00637     QImage img(path);
00638     if (size != 0)
00639         img=img.smoothScale(size,size);
00640 
00641     pix.convertFromImage(img);
00642     QPixmapCache::insert(key, pix);
00643     return pix;
00644     }
00645 
00646     // Regular case: Check parameters
00647 
00648     if ((group < -1) || (group >= KIcon::LastGroup))
00649     {
00650     kdDebug(264) << "Illegal icon group: " << group << endl;
00651     group = KIcon::Desktop;
00652     }
00653 
00654     int overlay = (state & KIcon::OverlayMask);
00655     state &= ~KIcon::OverlayMask;
00656     if ((state < 0) || (state >= KIcon::LastState))
00657     {
00658     kdDebug(264) << "Illegal icon state: " << state << endl;
00659     state = KIcon::DefaultState;
00660     }
00661 
00662     if (size == 0 && group < 0)
00663     {
00664     kdDebug(264) << "Neither size nor group specified!" << endl;
00665     group = KIcon::Desktop;
00666     }
00667 
00668     if (!absolutePath)
00669     {
00670         if (!canReturnNull && name.isEmpty())
00671             name = str_unknown;
00672         else
00673         name = removeIconExtensionInternal(name);
00674     }
00675 
00676     // If size == 0, use default size for the specified group.
00677     if (size == 0)
00678     {
00679     size = d->mpGroups[group].size;
00680     }
00681     favIconOverlay = favIconOverlay && size > 22;
00682 
00683     // Generate a unique cache key for the icon.
00684 
00685     key = "$kico_";
00686     key += name; key += '_';
00687     key += QString::number(size); key += '_';
00688 
00689     QString overlayStr = QString::number( overlay );
00690 
00691     QString noEffectKey = key + '_' + overlayStr;
00692 
00693     if (group >= 0)
00694     {
00695     key += d->mpEffect.fingerprint(group, state);
00696     if (d->mpGroups[group].dblPixels)
00697         key += QString::fromLatin1(":dblsize");
00698     } else
00699     key += QString::fromLatin1("noeffect");
00700     key += '_';
00701     key += overlayStr;
00702 
00703     // Is the icon in the cache?
00704     bool inCache = QPixmapCache::find(key, pix);
00705     if (inCache && (path_store == 0L))
00706     return pix;
00707 
00708     QImage *img = 0;
00709     int iconType;
00710     int iconThreshold;
00711 
00712     if ( ( path_store != 0L ) ||
00713          noEffectKey != d->lastImageKey )
00714     {
00715         // No? load it.
00716         KIcon icon;
00717         if (absolutePath && !favIconOverlay)
00718         {
00719             icon.context=KIcon::Any;
00720             icon.type=KIcon::Scalable;
00721             icon.path=name;
00722         }
00723         else
00724         {
00725             if (!name.isEmpty())
00726                 icon = findMatchingIcon(favIconOverlay ? QString("www") : name, size);
00727 
00728             if (!icon.isValid())
00729             {
00730                 // Try "User" icon too. Some apps expect this.
00731                 if (!name.isEmpty())
00732                     pix = loadIcon(name, KIcon::User, size, state, path_store, true);
00733                 if (!pix.isNull() || canReturnNull) {
00734                     QPixmapCache::insert(key, pix);
00735                     return pix;
00736                 }
00737 
00738                 icon = findMatchingIcon(str_unknown, size);
00739                 if (!icon.isValid())
00740                 {
00741                     kdDebug(264)
00742                         << "Warning: could not find \"Unknown\" icon for size = "
00743                         << size << endl;
00744                     return pix;
00745                 }
00746             }
00747         }
00748 
00749         if (path_store != 0L)
00750             *path_store = icon.path;
00751         if (inCache)
00752             return pix;
00753 
00754     // Use the extension as the format. Works for XPM and PNG, but not for SVG
00755     QString ext = icon.path.right(3).upper();
00756     if(ext != "SVG" && ext != "VGZ")
00757     {
00758         img = new QImage(icon.path, ext.latin1());
00759         if (img->isNull()) {
00760                 delete img;
00761         return pix;
00762             }
00763     }
00764 #ifdef HAVE_LIBART
00765     else
00766     {
00767         // Special stuff for SVG icons
00768         KSVGIconEngine *svgEngine = new KSVGIconEngine();
00769 
00770         if(svgEngine->load(size, size, icon.path))
00771         img = svgEngine->painter()->image();
00772         else
00773         img = new QImage();
00774 
00775         delete svgEngine;
00776     }
00777 #endif
00778 
00779         iconType = icon.type;
00780         iconThreshold = icon.threshold;
00781 
00782         d->lastImage = img->copy();
00783         d->lastImageKey = noEffectKey;
00784         d->lastIconType = iconType;
00785         d->lastIconThreshold = iconThreshold;
00786     }
00787     else
00788     {
00789         img = new QImage( d->lastImage.copy() );
00790         iconType = d->lastIconType;
00791         iconThreshold = d->lastIconThreshold;
00792     }
00793 
00794     // Blend in all overlays
00795     if (overlay)
00796     {
00797     QImage *ovl;
00798     KIconTheme *theme = d->mpThemeRoot->theme;
00799     if ((overlay & KIcon::LockOverlay) &&
00800         ((ovl = loadOverlay(theme->lockOverlay(), size)) != 0L))
00801         KIconEffect::overlay(*img, *ovl);
00802     if ((overlay & KIcon::LinkOverlay) &&
00803         ((ovl = loadOverlay(theme->linkOverlay(), size)) != 0L))
00804         KIconEffect::overlay(*img, *ovl);
00805     if ((overlay & KIcon::ZipOverlay) &&
00806         ((ovl = loadOverlay(theme->zipOverlay(), size)) != 0L))
00807         KIconEffect::overlay(*img, *ovl);
00808     if ((overlay & KIcon::ShareOverlay) &&
00809         ((ovl = loadOverlay(theme->shareOverlay(), size)) != 0L))
00810       KIconEffect::overlay(*img, *ovl);
00811         if (overlay & KIcon::HiddenOverlay)
00812         {
00813         if (img->depth() != 32)
00814             *img = img->convertDepth(32);
00815             for (int y = 0; y < img->height(); y++)
00816             {
00817         QRgb *line = reinterpret_cast<QRgb *>(img->scanLine(y));
00818                 for (int x = 0; x < img->width();  x++)
00819                     line[x] = (line[x] & 0x00ffffff) | (QMIN(0x80, qAlpha(line[x])) << 24);
00820         }
00821     }
00822     }
00823 
00824     // Scale the icon and apply effects if necessary
00825     if (iconType == KIcon::Scalable && size != img->width())
00826     {
00827         *img = img->smoothScale(size, size);
00828     }
00829     if (iconType == KIcon::Threshold && size != img->width())
00830     {
00831     if ( abs(size-img->width())>iconThreshold )
00832         *img = img->smoothScale(size, size);
00833     }
00834     if (group >= 0 && d->mpGroups[group].dblPixels)
00835     {
00836     *img = d->mpEffect.doublePixels(*img);
00837     }
00838     if (group >= 0)
00839     {
00840     *img = d->mpEffect.apply(*img, group, state);
00841     }
00842 
00843     if (favIconOverlay)
00844     {
00845         QImage favIcon(name, "PNG");
00846         int x = img->width() - favIcon.width() - 1,
00847             y = img->height() - favIcon.height() - 1;
00848         if( favIcon.depth() != 32 )
00849             favIcon = favIcon.convertDepth( 32 );
00850         if( img->depth() != 32 )
00851             *img = img->convertDepth( 32 );
00852         for( int line = 0;
00853              line < favIcon.height();
00854              ++line )
00855         {
00856             QRgb* fpos = reinterpret_cast< QRgb* >( favIcon.scanLine( line ));
00857             QRgb* ipos = reinterpret_cast< QRgb* >( img->scanLine( line + y )) + x;
00858             for( int i = 0;
00859                  i < favIcon.width();
00860                  ++i, ++fpos, ++ipos )
00861                 *ipos = qRgba( ( qRed( *ipos ) * ( 255 - qAlpha( *fpos )) + qRed( *fpos ) * qAlpha( *fpos )) / 255,
00862                                ( qGreen( *ipos ) * ( 255 - qAlpha( *fpos )) + qGreen( *fpos ) * qAlpha( *fpos )) / 255,
00863                                ( qBlue( *ipos ) * ( 255 - qAlpha( *fpos )) + qBlue( *fpos ) * qAlpha( *fpos )) / 255,
00864                                ( qAlpha( *ipos ) * ( 255 - qAlpha( *fpos )) + qAlpha( *fpos ) * qAlpha( *fpos )) / 255 );
00865         }
00866     }
00867 
00868     pix.convertFromImage(*img);
00869 
00870     delete img;
00871 
00872     QPixmapCache::insert(key, pix);
00873     return pix;
00874 }
00875 
00876 QImage *KIconLoader::loadOverlay(const QString &name, int size) const
00877 {
00878     QString key = name + '_' + QString::number(size);
00879     QImage *image = d->imgDict.find(key);
00880     if (image != 0L)
00881     return image;
00882 
00883     KIcon icon = findMatchingIcon(name, size);
00884     if (!icon.isValid())
00885     {
00886     kdDebug(264) << "Overlay " << name << "not found." << endl;
00887     return 0L;
00888     }
00889     image = new QImage(icon.path);
00890     // In some cases (since size in findMatchingIcon() is more a hint than a
00891     // constraint) image->size can be != size. If so perform rescaling.
00892     if ( size != image->width() )
00893         *image = image->smoothScale( size, size );
00894     d->imgDict.insert(key, image);
00895     return image;
00896 }
00897 
00898 
00899 
00900 QMovie KIconLoader::loadMovie(const QString& name, KIcon::Group group, int size) const
00901 {
00902     QString file = moviePath( name, group, size );
00903     if (file.isEmpty())
00904     return QMovie();
00905     int dirLen = file.findRev('/');
00906     QString icon = iconPath(name, size ? -size : group, true);
00907     if (!icon.isEmpty() && file.left(dirLen) != icon.left(dirLen))
00908     return QMovie();
00909     return QMovie(file);
00910 }
00911 
00912 QString KIconLoader::moviePath(const QString& name, KIcon::Group group, int size) const
00913 {
00914     if (!d->mpGroups) return QString::null;
00915 
00916     if ( (group < -1 || group >= KIcon::LastGroup) && group != KIcon::User )
00917     {
00918     kdDebug(264) << "Illegal icon group: " << group << endl;
00919     group = KIcon::Desktop;
00920     }
00921     if (size == 0 && group < 0)
00922     {
00923     kdDebug(264) << "Neither size nor group specified!" << endl;
00924     group = KIcon::Desktop;
00925     }
00926 
00927     QString file = name + ".mng";
00928     if (group == KIcon::User)
00929     {
00930     file = d->mpDirs->findResource("appicon", file);
00931     }
00932     else
00933     {
00934     if (size == 0)
00935         size = d->mpGroups[group].size;
00936 
00937         KIcon icon;
00938 
00939     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
00940         themeNode = d->links.next() )
00941     {
00942         icon = themeNode->theme->iconPath(file, size, KIcon::MatchExact);
00943         if (icon.isValid())
00944         break;
00945     }
00946 
00947     if ( !icon.isValid() )
00948     {
00949         for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
00950             themeNode = d->links.next() )
00951         {
00952         icon = themeNode->theme->iconPath(file, size, KIcon::MatchBest);
00953         if (icon.isValid())
00954             break;
00955         }
00956     }
00957 
00958     file = icon.isValid() ? icon.path : QString::null;
00959     }
00960     return file;
00961 }
00962 
00963 
00964 QStringList KIconLoader::loadAnimated(const QString& name, KIcon::Group group, int size) const
00965 {
00966     QStringList lst;
00967 
00968     if (!d->mpGroups) return lst;
00969 
00970     if ((group < -1) || (group >= KIcon::LastGroup))
00971     {
00972     kdDebug(264) << "Illegal icon group: " << group << endl;
00973     group = KIcon::Desktop;
00974     }
00975     if ((size == 0) && (group < 0))
00976     {
00977     kdDebug(264) << "Neither size nor group specified!" << endl;
00978     group = KIcon::Desktop;
00979     }
00980 
00981     QString file = name + "/0001";
00982     if (group == KIcon::User)
00983     {
00984     file = d->mpDirs->findResource("appicon", file + ".png");
00985     } else
00986     {
00987     if (size == 0)
00988         size = d->mpGroups[group].size;
00989     KIcon icon = findMatchingIcon(file, size);
00990     file = icon.isValid() ? icon.path : QString::null;
00991 
00992     }
00993     if (file.isEmpty())
00994     return lst;
00995 
00996     QString path = file.left(file.length()-8);
00997     DIR* dp = opendir( QFile::encodeName(path) );
00998     if(!dp)
00999         return lst;
01000 
01001     struct dirent* ep;
01002     while( ( ep = readdir( dp ) ) != 0L )
01003     {
01004         QString fn(QFile::decodeName(ep->d_name));
01005         if(!(fn.left(4)).toUInt())
01006             continue;
01007 
01008         lst += path + fn;
01009     }
01010     closedir ( dp );
01011     lst.sort();
01012     return lst;
01013 }
01014 
01015 KIconTheme *KIconLoader::theme() const
01016 {
01017     if (d->mpThemeRoot) return d->mpThemeRoot->theme;
01018     return 0L;
01019 }
01020 
01021 int KIconLoader::currentSize(KIcon::Group group) const
01022 {
01023     if (!d->mpGroups) return -1;
01024 
01025     if (group < 0 || group >= KIcon::LastGroup)
01026     {
01027     kdDebug(264) << "Illegal icon group: " << group << endl;
01028     return -1;
01029     }
01030     return d->mpGroups[group].size;
01031 }
01032 
01033 QStringList KIconLoader::queryIconsByDir( const QString& iconsDir ) const
01034 {
01035   QDir dir(iconsDir);
01036   QStringList lst = dir.entryList("*.png;*.xpm", QDir::Files);
01037   QStringList result;
01038   QStringList::ConstIterator it;
01039   for (it=lst.begin(); it!=lst.end(); ++it)
01040     result += iconsDir + "/" + *it;
01041   return result;
01042 }
01043 
01044 QStringList KIconLoader::queryIconsByContext(int group_or_size,
01045                         KIcon::Context context) const
01046 {
01047     QStringList result;
01048     if (group_or_size >= KIcon::LastGroup)
01049     {
01050     kdDebug(264) << "Illegal icon group: " << group_or_size << endl;
01051     return result;
01052     }
01053     int size;
01054     if (group_or_size >= 0)
01055     size = d->mpGroups[group_or_size].size;
01056     else
01057     size = -group_or_size;
01058 
01059     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
01060             themeNode = d->links.next() )
01061        themeNode->queryIconsByContext(&result, size, context);
01062 
01063     // Eliminate duplicate entries (same icon in different directories)
01064     QString name;
01065     QStringList res2, entries;
01066     QStringList::ConstIterator it;
01067     for (it=result.begin(); it!=result.end(); ++it)
01068     {
01069     int n = (*it).findRev('/');
01070     if (n == -1)
01071         name = *it;
01072     else
01073         name = (*it).mid(n+1);
01074     name = removeIconExtension(name);
01075     if (!entries.contains(name))
01076     {
01077         entries += name;
01078         res2 += *it;
01079     }
01080     }
01081     return res2;
01082 
01083 }
01084 
01085 QStringList KIconLoader::queryIcons(int group_or_size, KIcon::Context context) const
01086 {
01087     QStringList result;
01088     if (group_or_size >= KIcon::LastGroup)
01089     {
01090     kdDebug(264) << "Illegal icon group: " << group_or_size << endl;
01091     return result;
01092     }
01093     int size;
01094     if (group_or_size >= 0)
01095     size = d->mpGroups[group_or_size].size;
01096     else
01097     size = -group_or_size;
01098 
01099     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
01100             themeNode = d->links.next() )
01101        themeNode->queryIcons(&result, size, context);
01102 
01103     // Eliminate duplicate entries (same icon in different directories)
01104     QString name;
01105     QStringList res2, entries;
01106     QStringList::ConstIterator it;
01107     for (it=result.begin(); it!=result.end(); ++it)
01108     {
01109     int n = (*it).findRev('/');
01110     if (n == -1)
01111         name = *it;
01112     else
01113         name = (*it).mid(n+1);
01114     name = removeIconExtension(name);
01115     if (!entries.contains(name))
01116     {
01117         entries += name;
01118         res2 += *it;
01119     }
01120     }
01121     return res2;
01122 }
01123 
01124 // used by KIconDialog to find out which contexts to offer in a combobox
01125 bool KIconLoader::hasContext(KIcon::Context context) const
01126 {
01127     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
01128             themeNode = d->links.next() )
01129        if( themeNode->theme->hasContext( context ))
01130            return true;
01131     return false;
01132 }
01133 
01134 KIconEffect * KIconLoader::iconEffect() const
01135 {
01136     return &d->mpEffect;
01137 }
01138 
01139 bool KIconLoader::alphaBlending(KIcon::Group group) const
01140 {
01141     if (!d->mpGroups) return false;
01142 
01143     if (group < 0 || group >= KIcon::LastGroup)
01144     {
01145     kdDebug(264) << "Illegal icon group: " << group << endl;
01146     return false;
01147     }
01148     return d->mpGroups[group].alphaBlending;
01149 }
01150 
01151 QIconSet KIconLoader::loadIconSet(const QString& name, KIcon::Group group, int size, bool canReturnNull)
01152 {
01153     return loadIconSet( name, group, size, canReturnNull, true );
01154 }
01155 
01156 QIconSet KIconLoader::loadIconSet(const QString& name, KIcon::Group group, int size)
01157 {
01158     return loadIconSet( name, group, size, false );
01159 }
01160 
01161 /*** class for delayed icon loading for QIconSet ***/
01162 
01163 class KIconFactory
01164     : public QIconFactory
01165     {
01166     public:
01167         KIconFactory( const QString& iconName_P, KIcon::Group group_P,
01168             int size_P, KIconLoader* loader_P );
01169         KIconFactory( const QString& iconName_P, KIcon::Group group_P,
01170             int size_P, KIconLoader* loader_P, bool canReturnNull );
01171         virtual QPixmap* createPixmap( const QIconSet&, QIconSet::Size, QIconSet::Mode, QIconSet::State );
01172     private:
01173         QString iconName;
01174         KIcon::Group group;
01175         int size;
01176         KIconLoader* loader;
01177         bool canReturnNull;
01178     };
01179 
01180 
01181 QIconSet KIconLoader::loadIconSet( const QString& name, KIcon::Group g, int s,
01182     bool canReturnNull, bool immediateExistenceCheck)
01183 {
01184     if ( !d->delayedLoading )
01185         return loadIconSetNonDelayed( name, g, s, canReturnNull );
01186 
01187     if (g < -1 || g > 6) {
01188         kdDebug() << "KIconLoader::loadIconSet " << name << " " << (int)g << " " << s << endl;
01189         qDebug("%s", kdBacktrace().latin1());
01190         abort();
01191     }
01192 
01193     if(canReturnNull && immediateExistenceCheck)
01194     { // we need to find out if the icon actually exists
01195         QPixmap pm = loadIcon( name, g, s, KIcon::DefaultState, NULL, true );
01196         if( pm.isNull())
01197             return QIconSet();
01198 
01199         QIconSet ret( pm );
01200         ret.installIconFactory( new KIconFactory( name, g, s, this ));
01201         return ret;
01202     }
01203 
01204     QIconSet ret;
01205     ret.installIconFactory( new KIconFactory( name, g, s, this, canReturnNull ));
01206     return ret;
01207 }
01208 
01209 QIconSet KIconLoader::loadIconSetNonDelayed( const QString& name,
01210                                              KIcon::Group g,
01211                                              int s, bool canReturnNull )
01212 {
01213     QIconSet iconset;
01214     QPixmap tmp = loadIcon(name, g, s, KIcon::ActiveState, NULL, canReturnNull);
01215     iconset.setPixmap( tmp, QIconSet::Small, QIconSet::Active );
01216     // we don't use QIconSet's resizing anyway
01217     iconset.setPixmap( tmp, QIconSet::Large, QIconSet::Active );
01218     tmp = loadIcon(name, g, s, KIcon::DisabledState, NULL, canReturnNull);
01219     iconset.setPixmap( tmp, QIconSet::Small, QIconSet::Disabled );
01220     iconset.setPixmap( tmp, QIconSet::Large, QIconSet::Disabled );
01221     tmp = loadIcon(name, g, s, KIcon::DefaultState, NULL, canReturnNull);
01222     iconset.setPixmap( tmp, QIconSet::Small, QIconSet::Normal );
01223     iconset.setPixmap( tmp, QIconSet::Large, QIconSet::Normal );
01224     return iconset;
01225 }
01226 
01227 KIconFactory::KIconFactory( const QString& iconName_P, KIcon::Group group_P,
01228     int size_P, KIconLoader* loader_P )
01229     : iconName( iconName_P ), group( group_P ), size( size_P ), loader( loader_P )
01230 {
01231     canReturnNull = false;
01232     setAutoDelete( true );
01233 }
01234 
01235 KIconFactory::KIconFactory( const QString& iconName_P, KIcon::Group group_P,
01236     int size_P, KIconLoader* loader_P, bool canReturnNull_P )
01237     : iconName( iconName_P ), group( group_P ), size( size_P ),
01238       loader( loader_P ), canReturnNull( canReturnNull_P)
01239 {
01240     setAutoDelete( true );
01241 }
01242 
01243 QPixmap* KIconFactory::createPixmap( const QIconSet&, QIconSet::Size, QIconSet::Mode mode_P, QIconSet::State )
01244     {
01245 #ifdef KICONLOADER_CHECKS
01246     bool found = false;
01247     for( QValueList< KIconLoaderDebug >::Iterator it = kiconloaders->begin();
01248          it != kiconloaders->end();
01249          ++it )
01250         {
01251         if( (*it).loader == loader )
01252             {
01253             found = true;
01254             if( !(*it).valid )
01255                 {
01256 #ifdef NDEBUG
01257                 loader = KGlobal::iconLoader();
01258                 iconName = "no_way_man_you_will_get_broken_icon";
01259 #else
01260                 kdWarning() << "Using already destroyed KIconLoader for loading an icon!" << endl;
01261                 kdWarning() << "Appname:" << (*it).appname << ", icon:" << iconName << endl;
01262                 kdWarning() << "Deleted at:" << endl;
01263                 kdWarning() << (*it).delete_bt << endl;
01264                 kdWarning() << "Current:" << endl;
01265                 kdWarning() << kdBacktrace() << endl;
01266                 abort();
01267                 return NULL;
01268 #endif
01269                 }
01270             break;
01271             }
01272         }
01273     if( !found )
01274         {
01275 #ifdef NDEBUG
01276         loader = KGlobal::iconLoader();
01277         iconName = "no_way_man_you_will_get_broken_icon";
01278 #else
01279         kdWarning() << "Using unknown KIconLoader for loading an icon!" << endl;
01280         kdWarning() << "Icon:" << iconName << endl;
01281         kdWarning() << kdBacktrace() << endl;
01282         abort();
01283         return NULL;
01284 #endif
01285         }
01286 #endif
01287     // QIconSet::Mode to KIcon::State conversion
01288     static const KIcon::States tbl[] = { KIcon::DefaultState, KIcon::DisabledState, KIcon::ActiveState };
01289     int state = KIcon::DefaultState;
01290     if( mode_P <= QIconSet::Active )
01291         state = tbl[ mode_P ];
01292     if( group >= 0 && state == KIcon::ActiveState )
01293     { // active and normal icon are usually the same
01294     if( loader->iconEffect()->fingerprint(group, KIcon::ActiveState )
01295             == loader->iconEffect()->fingerprint(group, KIcon::DefaultState ))
01296             return 0; // so let QIconSet simply duplicate it
01297     }
01298     // ignore passed size
01299     // ignore passed state (i.e. on/off)
01300     QPixmap pm = loader->loadIcon( iconName, group, size, state, 0, canReturnNull );
01301     return new QPixmap( pm );
01302     }
01303 
01304 // Easy access functions
01305 
01306 QPixmap DesktopIcon(const QString& name, int force_size, int state,
01307     KInstance *instance)
01308 {
01309     KIconLoader *loader = instance->iconLoader();
01310     return loader->loadIcon(name, KIcon::Desktop, force_size, state);
01311 }
01312 
01313 QPixmap DesktopIcon(const QString& name, KInstance *instance)
01314 {
01315     return DesktopIcon(name, 0, KIcon::DefaultState, instance);
01316 }
01317 
01318 QIconSet DesktopIconSet(const QString& name, int force_size, KInstance *instance)
01319 {
01320     KIconLoader *loader = instance->iconLoader();
01321     return loader->loadIconSet( name, KIcon::Desktop, force_size );
01322 }
01323 
01324 QPixmap BarIcon(const QString& name, int force_size, int state,
01325     KInstance *instance)
01326 {
01327     KIconLoader *loader = instance->iconLoader();
01328     return loader->loadIcon(name, KIcon::Toolbar, force_size, state);
01329 }
01330 
01331 QPixmap BarIcon(const QString& name, KInstance *instance)
01332 {
01333     return BarIcon(name, 0, KIcon::DefaultState, instance);
01334 }
01335 
01336 QIconSet BarIconSet(const QString& name, int force_size, KInstance *instance)
01337 {
01338     KIconLoader *loader = instance->iconLoader();
01339     return loader->loadIconSet( name, KIcon::Toolbar, force_size );
01340 }
01341 
01342 QPixmap SmallIcon(const QString& name, int force_size, int state,
01343     KInstance *instance)
01344 {
01345     KIconLoader *loader = instance->iconLoader();
01346     return loader->loadIcon(name, KIcon::Small, force_size, state);
01347 }
01348 
01349 QPixmap SmallIcon(const QString& name, KInstance *instance)
01350 {
01351     return SmallIcon(name, 0, KIcon::DefaultState, instance);
01352 }
01353 
01354 QIconSet SmallIconSet(const QString& name, int force_size, KInstance *instance)
01355 {
01356     KIconLoader *loader = instance->iconLoader();
01357     return loader->loadIconSet( name, KIcon::Small, force_size );
01358 }
01359 
01360 QPixmap MainBarIcon(const QString& name, int force_size, int state,
01361     KInstance *instance)
01362 {
01363     KIconLoader *loader = instance->iconLoader();
01364     return loader->loadIcon(name, KIcon::MainToolbar, force_size, state);
01365 }
01366 
01367 QPixmap MainBarIcon(const QString& name, KInstance *instance)
01368 {
01369     return MainBarIcon(name, 0, KIcon::DefaultState, instance);
01370 }
01371 
01372 QIconSet MainBarIconSet(const QString& name, int force_size, KInstance *instance)
01373 {
01374     KIconLoader *loader = instance->iconLoader();
01375     return loader->loadIconSet( name, KIcon::MainToolbar, force_size );
01376 }
01377 
01378 QPixmap UserIcon(const QString& name, int state, KInstance *instance)
01379 {
01380     KIconLoader *loader = instance->iconLoader();
01381     return loader->loadIcon(name, KIcon::User, 0, state);
01382 }
01383 
01384 QPixmap UserIcon(const QString& name, KInstance *instance)
01385 {
01386     return UserIcon(name, KIcon::DefaultState, instance);
01387 }
01388 
01389 QIconSet UserIconSet(const QString& name, KInstance *instance)
01390 {
01391     KIconLoader *loader = instance->iconLoader();
01392     return loader->loadIconSet( name, KIcon::User );
01393 }
01394 
01395 int IconSize(KIcon::Group group, KInstance *instance)
01396 {
01397     KIconLoader *loader = instance->iconLoader();
01398     return loader->currentSize(group);
01399 }
01400 
01401 QPixmap KIconLoader::unknown()
01402 {
01403     QPixmap pix;
01404     if ( QPixmapCache::find("unknown", pix) )
01405             return pix;
01406 
01407     QString path = KGlobal::iconLoader()->iconPath("unknown", KIcon::Small, true);
01408     if (path.isEmpty())
01409     {
01410     kdDebug(264) << "Warning: Cannot find \"unknown\" icon." << endl;
01411     pix.resize(32,32);
01412     } else
01413     {
01414         pix.load(path);
01415         QPixmapCache::insert("unknown", pix);
01416     }
01417 
01418     return pix;
01419 }
01420 
01421 void KIconLoaderPrivate::reconfigure()
01422 {
01423   q->reconfigure(appname, mpDirs);
01424 }
01425 
01426 #include "kiconloader_p.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys