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                     if ((group == KIcon::Small) && (pix.width() > 20 || pix.height() > 20)) {
00735                         QImage tmp = pix.convertToImage();
00736                         tmp = tmp.smoothScale(20, 20);
00737                         pix.convertFromImage(tmp);
00738                     }
00739                     return pix;
00740                 }
00741 
00742                 icon = findMatchingIcon(str_unknown, size);
00743                 if (!icon.isValid())
00744                 {
00745                     kdDebug(264)
00746                         << "Warning: could not find \"Unknown\" icon for size = "
00747                         << size << endl;
00748                     return pix;
00749                 }
00750             }
00751         }
00752 
00753         if (path_store != 0L)
00754             *path_store = icon.path;
00755         if (inCache)
00756             return pix;
00757 
00758     // Use the extension as the format. Works for XPM and PNG, but not for SVG
00759     QString ext = icon.path.right(3).upper();
00760     if(ext != "SVG" && ext != "VGZ")
00761     {
00762         img = new QImage(icon.path, ext.latin1());
00763         if (img->isNull()) {
00764                 delete img;
00765         return pix;
00766             }
00767     }
00768 #ifdef HAVE_LIBART
00769     else
00770     {
00771         // Special stuff for SVG icons
00772         KSVGIconEngine *svgEngine = new KSVGIconEngine();
00773 
00774         if(svgEngine->load(size, size, icon.path))
00775         img = svgEngine->painter()->image();
00776         else
00777         img = new QImage();
00778 
00779         delete svgEngine;
00780     }
00781 #endif
00782 
00783         iconType = icon.type;
00784         iconThreshold = icon.threshold;
00785 
00786         d->lastImage = img->copy();
00787         d->lastImageKey = noEffectKey;
00788         d->lastIconType = iconType;
00789         d->lastIconThreshold = iconThreshold;
00790     }
00791     else
00792     {
00793         img = new QImage( d->lastImage.copy() );
00794         iconType = d->lastIconType;
00795         iconThreshold = d->lastIconThreshold;
00796     }
00797 
00798     // Blend in all overlays
00799     if (overlay)
00800     {
00801     QImage *ovl;
00802     KIconTheme *theme = d->mpThemeRoot->theme;
00803     if ((overlay & KIcon::LockOverlay) &&
00804         ((ovl = loadOverlay(theme->lockOverlay(), size)) != 0L))
00805         KIconEffect::overlay(*img, *ovl);
00806     if ((overlay & KIcon::LinkOverlay) &&
00807         ((ovl = loadOverlay(theme->linkOverlay(), size)) != 0L))
00808         KIconEffect::overlay(*img, *ovl);
00809     if ((overlay & KIcon::ZipOverlay) &&
00810         ((ovl = loadOverlay(theme->zipOverlay(), size)) != 0L))
00811         KIconEffect::overlay(*img, *ovl);
00812     if ((overlay & KIcon::ShareOverlay) &&
00813         ((ovl = loadOverlay(theme->shareOverlay(), size)) != 0L))
00814       KIconEffect::overlay(*img, *ovl);
00815         if (overlay & KIcon::HiddenOverlay)
00816         {
00817         if (img->depth() != 32)
00818             *img = img->convertDepth(32);
00819             for (int y = 0; y < img->height(); y++)
00820             {
00821         QRgb *line = reinterpret_cast<QRgb *>(img->scanLine(y));
00822                 for (int x = 0; x < img->width();  x++)
00823                     line[x] = (line[x] & 0x00ffffff) | (QMIN(0x80, qAlpha(line[x])) << 24);
00824         }
00825     }
00826     }
00827 
00828     // Scale the icon and apply effects if necessary
00829     if (iconType == KIcon::Scalable && size != img->width())
00830     {
00831         *img = img->smoothScale(size, size);
00832     }
00833     if (iconType == KIcon::Threshold && size != img->width())
00834     {
00835     if ( abs(size-img->width())>iconThreshold )
00836         *img = img->smoothScale(size, size);
00837     }
00838     if (group >= 0 && d->mpGroups[group].dblPixels)
00839     {
00840     *img = d->mpEffect.doublePixels(*img);
00841     }
00842     if (group >= 0)
00843     {
00844     *img = d->mpEffect.apply(*img, group, state);
00845     }
00846 
00847     if (favIconOverlay)
00848     {
00849         QImage favIcon(name, "PNG");
00850         int x = img->width() - favIcon.width() - 1,
00851             y = img->height() - favIcon.height() - 1;
00852         if( favIcon.depth() != 32 )
00853             favIcon = favIcon.convertDepth( 32 );
00854         if( img->depth() != 32 )
00855             *img = img->convertDepth( 32 );
00856         for( int line = 0;
00857              line < favIcon.height();
00858              ++line )
00859         {
00860             QRgb* fpos = reinterpret_cast< QRgb* >( favIcon.scanLine( line ));
00861             QRgb* ipos = reinterpret_cast< QRgb* >( img->scanLine( line + y )) + x;
00862             for( int i = 0;
00863                  i < favIcon.width();
00864                  ++i, ++fpos, ++ipos )
00865                 *ipos = qRgba( ( qRed( *ipos ) * ( 255 - qAlpha( *fpos )) + qRed( *fpos ) * qAlpha( *fpos )) / 255,
00866                                ( qGreen( *ipos ) * ( 255 - qAlpha( *fpos )) + qGreen( *fpos ) * qAlpha( *fpos )) / 255,
00867                                ( qBlue( *ipos ) * ( 255 - qAlpha( *fpos )) + qBlue( *fpos ) * qAlpha( *fpos )) / 255,
00868                                ( qAlpha( *ipos ) * ( 255 - qAlpha( *fpos )) + qAlpha( *fpos ) * qAlpha( *fpos )) / 255 );
00869         }
00870     }
00871 
00872     pix.convertFromImage(*img);
00873 
00874     delete img;
00875 
00876     QPixmapCache::insert(key, pix);
00877     return pix;
00878 }
00879 
00880 QImage *KIconLoader::loadOverlay(const QString &name, int size) const
00881 {
00882     QString key = name + '_' + QString::number(size);
00883     QImage *image = d->imgDict.find(key);
00884     if (image != 0L)
00885     return image;
00886 
00887     KIcon icon = findMatchingIcon(name, size);
00888     if (!icon.isValid())
00889     {
00890     kdDebug(264) << "Overlay " << name << "not found." << endl;
00891     return 0L;
00892     }
00893     image = new QImage(icon.path);
00894     // In some cases (since size in findMatchingIcon() is more a hint than a
00895     // constraint) image->size can be != size. If so perform rescaling.
00896     if ( size != image->width() )
00897         *image = image->smoothScale( size, size );
00898     d->imgDict.insert(key, image);
00899     return image;
00900 }
00901 
00902 
00903 
00904 QMovie KIconLoader::loadMovie(const QString& name, KIcon::Group group, int size) const
00905 {
00906     QString file = moviePath( name, group, size );
00907     if (file.isEmpty())
00908     return QMovie();
00909     int dirLen = file.findRev('/');
00910     QString icon = iconPath(name, size ? -size : group, true);
00911     if (!icon.isEmpty() && file.left(dirLen) != icon.left(dirLen))
00912     return QMovie();
00913     return QMovie(file);
00914 }
00915 
00916 QString KIconLoader::moviePath(const QString& name, KIcon::Group group, int size) const
00917 {
00918     if (!d->mpGroups) return QString::null;
00919 
00920     if ( (group < -1 || group >= KIcon::LastGroup) && group != KIcon::User )
00921     {
00922     kdDebug(264) << "Illegal icon group: " << group << endl;
00923     group = KIcon::Desktop;
00924     }
00925     if (size == 0 && group < 0)
00926     {
00927     kdDebug(264) << "Neither size nor group specified!" << endl;
00928     group = KIcon::Desktop;
00929     }
00930 
00931     QString file = name + ".mng";
00932     if (group == KIcon::User)
00933     {
00934     file = d->mpDirs->findResource("appicon", file);
00935     }
00936     else
00937     {
00938     if (size == 0)
00939         size = d->mpGroups[group].size;
00940 
00941         KIcon icon;
00942 
00943     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
00944         themeNode = d->links.next() )
00945     {
00946         icon = themeNode->theme->iconPath(file, size, KIcon::MatchExact);
00947         if (icon.isValid())
00948         break;
00949     }
00950 
00951     if ( !icon.isValid() )
00952     {
00953         for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
00954             themeNode = d->links.next() )
00955         {
00956         icon = themeNode->theme->iconPath(file, size, KIcon::MatchBest);
00957         if (icon.isValid())
00958             break;
00959         }
00960     }
00961 
00962     file = icon.isValid() ? icon.path : QString::null;
00963     }
00964     return file;
00965 }
00966 
00967 
00968 QStringList KIconLoader::loadAnimated(const QString& name, KIcon::Group group, int size) const
00969 {
00970     QStringList lst;
00971 
00972     if (!d->mpGroups) return lst;
00973 
00974     if ((group < -1) || (group >= KIcon::LastGroup))
00975     {
00976     kdDebug(264) << "Illegal icon group: " << group << endl;
00977     group = KIcon::Desktop;
00978     }
00979     if ((size == 0) && (group < 0))
00980     {
00981     kdDebug(264) << "Neither size nor group specified!" << endl;
00982     group = KIcon::Desktop;
00983     }
00984 
00985     QString file = name + "/0001";
00986     if (group == KIcon::User)
00987     {
00988     file = d->mpDirs->findResource("appicon", file + ".png");
00989     } else
00990     {
00991     if (size == 0)
00992         size = d->mpGroups[group].size;
00993     KIcon icon = findMatchingIcon(file, size);
00994     file = icon.isValid() ? icon.path : QString::null;
00995 
00996     }
00997     if (file.isEmpty())
00998     return lst;
00999 
01000     QString path = file.left(file.length()-8);
01001     DIR* dp = opendir( QFile::encodeName(path) );
01002     if(!dp)
01003         return lst;
01004 
01005     struct dirent* ep;
01006     while( ( ep = readdir( dp ) ) != 0L )
01007     {
01008         QString fn(QFile::decodeName(ep->d_name));
01009         if(!(fn.left(4)).toUInt())
01010             continue;
01011 
01012         lst += path + fn;
01013     }
01014     closedir ( dp );
01015     lst.sort();
01016     return lst;
01017 }
01018 
01019 KIconTheme *KIconLoader::theme() const
01020 {
01021     if (d->mpThemeRoot) return d->mpThemeRoot->theme;
01022     return 0L;
01023 }
01024 
01025 int KIconLoader::currentSize(KIcon::Group group) const
01026 {
01027     if (!d->mpGroups) return -1;
01028 
01029     if (group < 0 || group >= KIcon::LastGroup)
01030     {
01031     kdDebug(264) << "Illegal icon group: " << group << endl;
01032     return -1;
01033     }
01034     return d->mpGroups[group].size;
01035 }
01036 
01037 QStringList KIconLoader::queryIconsByDir( const QString& iconsDir ) const
01038 {
01039   QDir dir(iconsDir);
01040   QStringList lst = dir.entryList("*.png;*.xpm", QDir::Files);
01041   QStringList result;
01042   QStringList::ConstIterator it;
01043   for (it=lst.begin(); it!=lst.end(); ++it)
01044     result += iconsDir + "/" + *it;
01045   return result;
01046 }
01047 
01048 QStringList KIconLoader::queryIconsByContext(int group_or_size,
01049                         KIcon::Context context) const
01050 {
01051     QStringList result;
01052     if (group_or_size >= KIcon::LastGroup)
01053     {
01054     kdDebug(264) << "Illegal icon group: " << group_or_size << endl;
01055     return result;
01056     }
01057     int size;
01058     if (group_or_size >= 0)
01059     size = d->mpGroups[group_or_size].size;
01060     else
01061     size = -group_or_size;
01062 
01063     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
01064             themeNode = d->links.next() )
01065        themeNode->queryIconsByContext(&result, size, context);
01066 
01067     // Eliminate duplicate entries (same icon in different directories)
01068     QString name;
01069     QStringList res2, entries;
01070     QStringList::ConstIterator it;
01071     for (it=result.begin(); it!=result.end(); ++it)
01072     {
01073     int n = (*it).findRev('/');
01074     if (n == -1)
01075         name = *it;
01076     else
01077         name = (*it).mid(n+1);
01078     name = removeIconExtension(name);
01079     if (!entries.contains(name))
01080     {
01081         entries += name;
01082         res2 += *it;
01083     }
01084     }
01085     return res2;
01086 
01087 }
01088 
01089 QStringList KIconLoader::queryIcons(int group_or_size, KIcon::Context context) const
01090 {
01091     QStringList result;
01092     if (group_or_size >= KIcon::LastGroup)
01093     {
01094     kdDebug(264) << "Illegal icon group: " << group_or_size << endl;
01095     return result;
01096     }
01097     int size;
01098     if (group_or_size >= 0)
01099     size = d->mpGroups[group_or_size].size;
01100     else
01101     size = -group_or_size;
01102 
01103     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
01104             themeNode = d->links.next() )
01105        themeNode->queryIcons(&result, size, context);
01106 
01107     // Eliminate duplicate entries (same icon in different directories)
01108     QString name;
01109     QStringList res2, entries;
01110     QStringList::ConstIterator it;
01111     for (it=result.begin(); it!=result.end(); ++it)
01112     {
01113     int n = (*it).findRev('/');
01114     if (n == -1)
01115         name = *it;
01116     else
01117         name = (*it).mid(n+1);
01118     name = removeIconExtension(name);
01119     if (!entries.contains(name))
01120     {
01121         entries += name;
01122         res2 += *it;
01123     }
01124     }
01125     return res2;
01126 }
01127 
01128 // used by KIconDialog to find out which contexts to offer in a combobox
01129 bool KIconLoader::hasContext(KIcon::Context context) const
01130 {
01131     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
01132             themeNode = d->links.next() )
01133        if( themeNode->theme->hasContext( context ))
01134            return true;
01135     return false;
01136 }
01137 
01138 KIconEffect * KIconLoader::iconEffect() const
01139 {
01140     return &d->mpEffect;
01141 }
01142 
01143 bool KIconLoader::alphaBlending(KIcon::Group group) const
01144 {
01145     if (!d->mpGroups) return false;
01146 
01147     if (group < 0 || group >= KIcon::LastGroup)
01148     {
01149     kdDebug(264) << "Illegal icon group: " << group << endl;
01150     return false;
01151     }
01152     return d->mpGroups[group].alphaBlending;
01153 }
01154 
01155 QIconSet KIconLoader::loadIconSet(const QString& name, KIcon::Group group, int size, bool canReturnNull)
01156 {
01157     return loadIconSet( name, group, size, canReturnNull, true );
01158 }
01159 
01160 QIconSet KIconLoader::loadIconSet(const QString& name, KIcon::Group group, int size)
01161 {
01162     return loadIconSet( name, group, size, false );
01163 }
01164 
01165 /*** class for delayed icon loading for QIconSet ***/
01166 
01167 class KIconFactory
01168     : public QIconFactory
01169     {
01170     public:
01171         KIconFactory( const QString& iconName_P, KIcon::Group group_P,
01172             int size_P, KIconLoader* loader_P );
01173         KIconFactory( const QString& iconName_P, KIcon::Group group_P,
01174             int size_P, KIconLoader* loader_P, bool canReturnNull );
01175         virtual QPixmap* createPixmap( const QIconSet&, QIconSet::Size, QIconSet::Mode, QIconSet::State );
01176     private:
01177         QString iconName;
01178         KIcon::Group group;
01179         int size;
01180         KIconLoader* loader;
01181         bool canReturnNull;
01182     };
01183 
01184 
01185 QIconSet KIconLoader::loadIconSet( const QString& name, KIcon::Group g, int s,
01186     bool canReturnNull, bool immediateExistenceCheck)
01187 {
01188     if ( !d->delayedLoading )
01189         return loadIconSetNonDelayed( name, g, s, canReturnNull );
01190 
01191     if (g < -1 || g > 6) {
01192         kdDebug() << "KIconLoader::loadIconSet " << name << " " << (int)g << " " << s << endl;
01193         qDebug("%s", kdBacktrace().latin1());
01194         abort();
01195     }
01196 
01197     if(canReturnNull && immediateExistenceCheck)
01198     { // we need to find out if the icon actually exists
01199         QPixmap pm = loadIcon( name, g, s, KIcon::DefaultState, NULL, true );
01200         if( pm.isNull())
01201             return QIconSet();
01202 
01203         QIconSet ret( pm );
01204         ret.installIconFactory( new KIconFactory( name, g, s, this ));
01205         return ret;
01206     }
01207 
01208     QIconSet ret;
01209     ret.installIconFactory( new KIconFactory( name, g, s, this, canReturnNull ));
01210     return ret;
01211 }
01212 
01213 QIconSet KIconLoader::loadIconSetNonDelayed( const QString& name,
01214                                              KIcon::Group g,
01215                                              int s, bool canReturnNull )
01216 {
01217     QIconSet iconset;
01218     QPixmap tmp = loadIcon(name, g, s, KIcon::ActiveState, NULL, canReturnNull);
01219     iconset.setPixmap( tmp, QIconSet::Small, QIconSet::Active );
01220     // we don't use QIconSet's resizing anyway
01221     iconset.setPixmap( tmp, QIconSet::Large, QIconSet::Active );
01222     tmp = loadIcon(name, g, s, KIcon::DisabledState, NULL, canReturnNull);
01223     iconset.setPixmap( tmp, QIconSet::Small, QIconSet::Disabled );
01224     iconset.setPixmap( tmp, QIconSet::Large, QIconSet::Disabled );
01225     tmp = loadIcon(name, g, s, KIcon::DefaultState, NULL, canReturnNull);
01226     iconset.setPixmap( tmp, QIconSet::Small, QIconSet::Normal );
01227     iconset.setPixmap( tmp, QIconSet::Large, QIconSet::Normal );
01228     return iconset;
01229 }
01230 
01231 KIconFactory::KIconFactory( const QString& iconName_P, KIcon::Group group_P,
01232     int size_P, KIconLoader* loader_P )
01233     : iconName( iconName_P ), group( group_P ), size( size_P ), loader( loader_P )
01234 {
01235     canReturnNull = false;
01236     setAutoDelete( true );
01237 }
01238 
01239 KIconFactory::KIconFactory( const QString& iconName_P, KIcon::Group group_P,
01240     int size_P, KIconLoader* loader_P, bool canReturnNull_P )
01241     : iconName( iconName_P ), group( group_P ), size( size_P ),
01242       loader( loader_P ), canReturnNull( canReturnNull_P)
01243 {
01244     setAutoDelete( true );
01245 }
01246 
01247 QPixmap* KIconFactory::createPixmap( const QIconSet&, QIconSet::Size, QIconSet::Mode mode_P, QIconSet::State )
01248     {
01249 #ifdef KICONLOADER_CHECKS
01250     bool found = false;
01251     for( QValueList< KIconLoaderDebug >::Iterator it = kiconloaders->begin();
01252          it != kiconloaders->end();
01253          ++it )
01254         {
01255         if( (*it).loader == loader )
01256             {
01257             found = true;
01258             if( !(*it).valid )
01259                 {
01260 #ifdef NDEBUG
01261                 loader = KGlobal::iconLoader();
01262                 iconName = "no_way_man_you_will_get_broken_icon";
01263 #else
01264                 kdWarning() << "Using already destroyed KIconLoader for loading an icon!" << endl;
01265                 kdWarning() << "Appname:" << (*it).appname << ", icon:" << iconName << endl;
01266                 kdWarning() << "Deleted at:" << endl;
01267                 kdWarning() << (*it).delete_bt << endl;
01268                 kdWarning() << "Current:" << endl;
01269                 kdWarning() << kdBacktrace() << endl;
01270                 abort();
01271                 return NULL;
01272 #endif
01273                 }
01274             break;
01275             }
01276         }
01277     if( !found )
01278         {
01279 #ifdef NDEBUG
01280         loader = KGlobal::iconLoader();
01281         iconName = "no_way_man_you_will_get_broken_icon";
01282 #else
01283         kdWarning() << "Using unknown KIconLoader for loading an icon!" << endl;
01284         kdWarning() << "Icon:" << iconName << endl;
01285         kdWarning() << kdBacktrace() << endl;
01286         abort();
01287         return NULL;
01288 #endif
01289         }
01290 #endif
01291     // QIconSet::Mode to KIcon::State conversion
01292     static const KIcon::States tbl[] = { KIcon::DefaultState, KIcon::DisabledState, KIcon::ActiveState };
01293     int state = KIcon::DefaultState;
01294     if( mode_P <= QIconSet::Active )
01295         state = tbl[ mode_P ];
01296     if( group >= 0 && state == KIcon::ActiveState )
01297     { // active and normal icon are usually the same
01298     if( loader->iconEffect()->fingerprint(group, KIcon::ActiveState )
01299             == loader->iconEffect()->fingerprint(group, KIcon::DefaultState ))
01300             return 0; // so let QIconSet simply duplicate it
01301     }
01302     // ignore passed size
01303     // ignore passed state (i.e. on/off)
01304     QPixmap pm = loader->loadIcon( iconName, group, size, state, 0, canReturnNull );
01305     return new QPixmap( pm );
01306     }
01307 
01308 // Easy access functions
01309 
01310 QPixmap DesktopIcon(const QString& name, int force_size, int state,
01311     KInstance *instance)
01312 {
01313     KIconLoader *loader = instance->iconLoader();
01314     return loader->loadIcon(name, KIcon::Desktop, force_size, state);
01315 }
01316 
01317 QPixmap DesktopIcon(const QString& name, KInstance *instance)
01318 {
01319     return DesktopIcon(name, 0, KIcon::DefaultState, instance);
01320 }
01321 
01322 QIconSet DesktopIconSet(const QString& name, int force_size, KInstance *instance)
01323 {
01324     KIconLoader *loader = instance->iconLoader();
01325     return loader->loadIconSet( name, KIcon::Desktop, force_size );
01326 }
01327 
01328 QPixmap BarIcon(const QString& name, int force_size, int state,
01329     KInstance *instance)
01330 {
01331     KIconLoader *loader = instance->iconLoader();
01332     return loader->loadIcon(name, KIcon::Toolbar, force_size, state);
01333 }
01334 
01335 QPixmap BarIcon(const QString& name, KInstance *instance)
01336 {
01337     return BarIcon(name, 0, KIcon::DefaultState, instance);
01338 }
01339 
01340 QIconSet BarIconSet(const QString& name, int force_size, KInstance *instance)
01341 {
01342     KIconLoader *loader = instance->iconLoader();
01343     return loader->loadIconSet( name, KIcon::Toolbar, force_size );
01344 }
01345 
01346 QPixmap SmallIcon(const QString& name, int force_size, int state,
01347     KInstance *instance)
01348 {
01349     KIconLoader *loader = instance->iconLoader();
01350     return loader->loadIcon(name, KIcon::Small, force_size, state);
01351 }
01352 
01353 QPixmap SmallIcon(const QString& name, KInstance *instance)
01354 {
01355     return SmallIcon(name, 0, KIcon::DefaultState, instance);
01356 }
01357 
01358 QIconSet SmallIconSet(const QString& name, int force_size, KInstance *instance)
01359 {
01360     KIconLoader *loader = instance->iconLoader();
01361     return loader->loadIconSet( name, KIcon::Small, force_size );
01362 }
01363 
01364 QPixmap MainBarIcon(const QString& name, int force_size, int state,
01365     KInstance *instance)
01366 {
01367     KIconLoader *loader = instance->iconLoader();
01368     return loader->loadIcon(name, KIcon::MainToolbar, force_size, state);
01369 }
01370 
01371 QPixmap MainBarIcon(const QString& name, KInstance *instance)
01372 {
01373     return MainBarIcon(name, 0, KIcon::DefaultState, instance);
01374 }
01375 
01376 QIconSet MainBarIconSet(const QString& name, int force_size, KInstance *instance)
01377 {
01378     KIconLoader *loader = instance->iconLoader();
01379     return loader->loadIconSet( name, KIcon::MainToolbar, force_size );
01380 }
01381 
01382 QPixmap UserIcon(const QString& name, int state, KInstance *instance)
01383 {
01384     KIconLoader *loader = instance->iconLoader();
01385     return loader->loadIcon(name, KIcon::User, 0, state);
01386 }
01387 
01388 QPixmap UserIcon(const QString& name, KInstance *instance)
01389 {
01390     return UserIcon(name, KIcon::DefaultState, instance);
01391 }
01392 
01393 QIconSet UserIconSet(const QString& name, KInstance *instance)
01394 {
01395     KIconLoader *loader = instance->iconLoader();
01396     return loader->loadIconSet( name, KIcon::User );
01397 }
01398 
01399 int IconSize(KIcon::Group group, KInstance *instance)
01400 {
01401     KIconLoader *loader = instance->iconLoader();
01402     return loader->currentSize(group);
01403 }
01404 
01405 QPixmap KIconLoader::unknown()
01406 {
01407     QPixmap pix;
01408     if ( QPixmapCache::find("unknown", pix) )
01409             return pix;
01410 
01411     QString path = KGlobal::iconLoader()->iconPath("unknown", KIcon::Small, true);
01412     if (path.isEmpty())
01413     {
01414     kdDebug(264) << "Warning: Cannot find \"unknown\" icon." << endl;
01415     pix.resize(32,32);
01416     } else
01417     {
01418         pix.load(path);
01419         QPixmapCache::insert("unknown", pix);
01420     }
01421 
01422     return pix;
01423 }
01424 
01425 void KIconLoaderPrivate::reconfigure()
01426 {
01427   q->reconfigure(appname, mpDirs);
01428 }
01429 
01430 #include "kiconloader_p.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys