kiconloader.cpp

00001 /* vi: ts=8 sts=4 sw=4
00002  *
00003  * $Id: kiconloader.cpp 693955 2007-07-29 16:28:09Z tyrerj $
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     /* JRT: To follow the XDG spec, the order in which we look for an
00464        icon 1s:
00465 
00466        png, svgz, svg, xpm exact match
00467        png, svgz, svg, xpm best match
00468        next theme in inheritance tree : png, svgz, svg, xpm exact match
00469                                         png, svgz, svg, xpm best match
00470        next theme in inheritance tree : png, svgz, svg, xpm exact match
00471                                         png, svgz, svg, xpm best match
00472        and so on
00473 
00474        */
00475     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
00476     themeNode = d->links.next() )
00477     {
00478     for (int i = 0 ; i < count ; i++)
00479     {
00480         icon = themeNode->theme->iconPath(name + *ext[i], size, KIcon::MatchExact);
00481         if (icon.isValid()) goto icon_found ;
00482     }
00483 
00484     for (int i = 0 ; i < count ; i++)
00485     {
00486         icon = themeNode->theme->iconPath(name + *ext[i], size, KIcon::MatchBest);
00487         if (icon.isValid()) goto icon_found;    
00488     }
00489     }
00490     icon_found:
00491     return icon;
00492 }
00493 
00494 inline QString KIconLoader::unknownIconPath( int size ) const
00495 {
00496     static const QString &str_unknown = KGlobal::staticQString("unknown");
00497 
00498     KIcon icon = findMatchingIcon(str_unknown, size);
00499     if (!icon.isValid())
00500     {
00501         kdDebug(264) << "Warning: could not find \"Unknown\" icon for size = "
00502                      << size << endl;
00503         return QString::null;
00504     }
00505     return icon.path;
00506 }
00507 
00508 // Finds the absolute path to an icon.
00509 
00510 QString KIconLoader::iconPath(const QString& _name, int group_or_size,
00511                   bool canReturnNull) const
00512 {
00513     if (d->mpThemeRoot == 0L)
00514     return QString::null;
00515 
00516     if (!QDir::isRelativePath(_name))
00517     return _name;
00518 
00519     QString name = removeIconExtensionInternal( _name );
00520 
00521     QString path;
00522     if (group_or_size == KIcon::User)
00523     {
00524     static const QString &png_ext = KGlobal::staticQString(".png");
00525     static const QString &xpm_ext = KGlobal::staticQString(".xpm");
00526     path = d->mpDirs->findResource("appicon", name + png_ext);
00527 
00528 #ifdef HAVE_LIBART
00529     static const QString &svgz_ext = KGlobal::staticQString(".svgz");
00530     static const QString &svg_ext = KGlobal::staticQString(".svg");
00531     if (path.isEmpty())
00532         path = d->mpDirs->findResource("appicon", name + svgz_ext);
00533     if (path.isEmpty())
00534        path = d->mpDirs->findResource("appicon", name + svg_ext);
00535 #endif
00536     if (path.isEmpty())
00537          path = d->mpDirs->findResource("appicon", name + xpm_ext);
00538     return path;
00539     }
00540 
00541     if (group_or_size >= KIcon::LastGroup)
00542     {
00543     kdDebug(264) << "Illegal icon group: " << group_or_size << endl;
00544     return path;
00545     }
00546 
00547     int size;
00548     if (group_or_size >= 0)
00549     size = d->mpGroups[group_or_size].size;
00550     else
00551     size = -group_or_size;
00552 
00553     if (_name.isEmpty()) {
00554         if (canReturnNull)
00555             return QString::null;
00556         else
00557             return unknownIconPath(size);
00558     }
00559 
00560     KIcon icon = findMatchingIcon(name, size);
00561 
00562     if (!icon.isValid())
00563     {
00564     // Try "User" group too.
00565     path = iconPath(name, KIcon::User, true);
00566     if (!path.isEmpty() || canReturnNull)
00567         return path;
00568 
00569     if (canReturnNull)
00570         return QString::null;
00571         else
00572             return unknownIconPath(size);
00573     }
00574     return icon.path;
00575 }
00576 
00577 QPixmap KIconLoader::loadIcon(const QString& _name, KIcon::Group group, int size,
00578                               int state, QString *path_store, bool canReturnNull) const
00579 {
00580     QString name = _name;
00581     QPixmap pix;
00582     QString key;
00583     bool absolutePath=false, favIconOverlay=false;
00584 
00585     if (d->mpThemeRoot == 0L)
00586     return pix;
00587 
00588     // Special case for absolute path icons.
00589     if (name.startsWith("favicons/"))
00590     {
00591        favIconOverlay = true;
00592        name = locateLocal("cache", name+".png");
00593     }
00594     if (!QDir::isRelativePath(name)) absolutePath=true;
00595 
00596     static const QString &str_unknown = KGlobal::staticQString("unknown");
00597 
00598     // Special case for "User" icons.
00599     if (group == KIcon::User)
00600     {
00601     key = "$kicou_";
00602         key += QString::number(size); key += '_';
00603     key += name;
00604     bool inCache = QPixmapCache::find(key, pix);
00605     if (inCache && (path_store == 0L))
00606         return pix;
00607 
00608     QString path = (absolutePath) ? name :
00609             iconPath(name, KIcon::User, canReturnNull);
00610     if (path.isEmpty())
00611     {
00612         if (canReturnNull)
00613         return pix;
00614         // We don't know the desired size: use small
00615         path = iconPath(str_unknown, KIcon::Small, true);
00616         if (path.isEmpty())
00617         {
00618         kdDebug(264) << "Warning: Cannot find \"unknown\" icon." << endl;
00619         return pix;
00620         }
00621     }
00622 
00623     if (path_store != 0L)
00624         *path_store = path;
00625     if (inCache)
00626         return pix;
00627     QImage img(path);
00628     if (size != 0)
00629         img=img.smoothScale(size,size);
00630 
00631     pix.convertFromImage(img);
00632     QPixmapCache::insert(key, pix);
00633     return pix;
00634     }
00635 
00636     // Regular case: Check parameters
00637 
00638     if ((group < -1) || (group >= KIcon::LastGroup))
00639     {
00640     kdDebug(264) << "Illegal icon group: " << group << endl;
00641     group = KIcon::Desktop;
00642     }
00643 
00644     int overlay = (state & KIcon::OverlayMask);
00645     state &= ~KIcon::OverlayMask;
00646     if ((state < 0) || (state >= KIcon::LastState))
00647     {
00648     kdDebug(264) << "Illegal icon state: " << state << endl;
00649     state = KIcon::DefaultState;
00650     }
00651 
00652     if (size == 0 && group < 0)
00653     {
00654     kdDebug(264) << "Neither size nor group specified!" << endl;
00655     group = KIcon::Desktop;
00656     }
00657 
00658     if (!absolutePath)
00659     {
00660         if (!canReturnNull && name.isEmpty())
00661             name = str_unknown;
00662         else
00663         name = removeIconExtensionInternal(name);
00664     }
00665 
00666     // If size == 0, use default size for the specified group.
00667     if (size == 0)
00668     {
00669     size = d->mpGroups[group].size;
00670     }
00671     favIconOverlay = favIconOverlay && size > 22;
00672 
00673     // Generate a unique cache key for the icon.
00674 
00675     key = "$kico_";
00676     key += name; key += '_';
00677     key += QString::number(size); key += '_';
00678 
00679     QString overlayStr = QString::number( overlay );
00680 
00681     QString noEffectKey = key + '_' + overlayStr;
00682 
00683     if (group >= 0)
00684     {
00685     key += d->mpEffect.fingerprint(group, state);
00686     if (d->mpGroups[group].dblPixels)
00687         key += QString::fromLatin1(":dblsize");
00688     } else
00689     key += QString::fromLatin1("noeffect");
00690     key += '_';
00691     key += overlayStr;
00692 
00693     // Is the icon in the cache?
00694     bool inCache = QPixmapCache::find(key, pix);
00695     if (inCache && (path_store == 0L))
00696     return pix;
00697 
00698     QImage *img = 0;
00699     int iconType;
00700     int iconThreshold;
00701 
00702     if ( ( path_store != 0L ) ||
00703          noEffectKey != d->lastImageKey )
00704     {
00705         // No? load it.
00706         KIcon icon;
00707         if (absolutePath && !favIconOverlay)
00708         {
00709             icon.context=KIcon::Any;
00710             icon.type=KIcon::Scalable;
00711             icon.path=name;
00712         }
00713         else
00714         {
00715             if (!name.isEmpty())
00716                 icon = findMatchingIcon(favIconOverlay ? QString("www") : name, size);
00717 
00718             if (!icon.isValid())
00719             {
00720                 // Try "User" icon too. Some apps expect this.
00721                 if (!name.isEmpty())
00722                     pix = loadIcon(name, KIcon::User, size, state, path_store, true);
00723                 if (!pix.isNull() || canReturnNull) {
00724                     if ((group == KIcon::Small) && (pix.width() > 20 || pix.height() > 20)) {
00725                         QImage tmp = pix.convertToImage();
00726                         tmp = tmp.smoothScale(20, 20);
00727                         pix.convertFromImage(tmp);
00728                     }
00729                     return pix;
00730                 }
00731 
00732                 icon = findMatchingIcon(str_unknown, size);
00733                 if (!icon.isValid())
00734                 {
00735                     kdDebug(264)
00736                         << "Warning: could not find \"Unknown\" icon for size = "
00737                         << size << endl;
00738                     return pix;
00739                 }
00740             }
00741         }
00742 
00743         if (path_store != 0L)
00744             *path_store = icon.path;
00745         if (inCache)
00746             return pix;
00747 
00748     // Use the extension as the format. Works for XPM and PNG, but not for SVG
00749     QString ext = icon.path.right(3).upper();
00750     if(ext != "SVG" && ext != "VGZ")
00751     {
00752         img = new QImage(icon.path, ext.latin1());
00753         if (img->isNull()) {
00754                 delete img;
00755         return pix;
00756             }
00757     }
00758 #ifdef HAVE_LIBART
00759     else
00760     {
00761         // Special stuff for SVG icons
00762         KSVGIconEngine *svgEngine = new KSVGIconEngine();
00763 
00764         if(svgEngine->load(size, size, icon.path))
00765         img = svgEngine->painter()->image();
00766         else
00767         img = new QImage();
00768 
00769         delete svgEngine;
00770     }
00771 #endif
00772 
00773         iconType = icon.type;
00774         iconThreshold = icon.threshold;
00775 
00776         d->lastImage = img->copy();
00777         d->lastImageKey = noEffectKey;
00778         d->lastIconType = iconType;
00779         d->lastIconThreshold = iconThreshold;
00780     }
00781     else
00782     {
00783         img = new QImage( d->lastImage.copy() );
00784         iconType = d->lastIconType;
00785         iconThreshold = d->lastIconThreshold;
00786     }
00787 
00788     // Blend in all overlays
00789     if (overlay)
00790     {
00791     QImage *ovl;
00792     KIconTheme *theme = d->mpThemeRoot->theme;
00793     if ((overlay & KIcon::LockOverlay) &&
00794         ((ovl = loadOverlay(theme->lockOverlay(), size)) != 0L))
00795         KIconEffect::overlay(*img, *ovl);
00796     if ((overlay & KIcon::LinkOverlay) &&
00797         ((ovl = loadOverlay(theme->linkOverlay(), size)) != 0L))
00798         KIconEffect::overlay(*img, *ovl);
00799     if ((overlay & KIcon::ZipOverlay) &&
00800         ((ovl = loadOverlay(theme->zipOverlay(), size)) != 0L))
00801         KIconEffect::overlay(*img, *ovl);
00802     if ((overlay & KIcon::ShareOverlay) &&
00803         ((ovl = loadOverlay(theme->shareOverlay(), size)) != 0L))
00804       KIconEffect::overlay(*img, *ovl);
00805         if (overlay & KIcon::HiddenOverlay)
00806         {
00807         if (img->depth() != 32)
00808             *img = img->convertDepth(32);
00809             for (int y = 0; y < img->height(); y++)
00810             {
00811         QRgb *line = reinterpret_cast<QRgb *>(img->scanLine(y));
00812                 for (int x = 0; x < img->width();  x++)
00813                     line[x] = (line[x] & 0x00ffffff) | (QMIN(0x80, qAlpha(line[x])) << 24);
00814         }
00815     }
00816     }
00817 
00818     // Scale the icon and apply effects if necessary
00819     if (iconType == KIcon::Scalable && size != img->width())
00820     {
00821         *img = img->smoothScale(size, size);
00822     }
00823     if (iconType == KIcon::Threshold && size != img->width())
00824     {
00825     if ( abs(size-img->width())>iconThreshold )
00826         *img = img->smoothScale(size, size);
00827     }
00828     if (group >= 0 && d->mpGroups[group].dblPixels)
00829     {
00830     *img = d->mpEffect.doublePixels(*img);
00831     }
00832     if (group >= 0)
00833     {
00834     *img = d->mpEffect.apply(*img, group, state);
00835     }
00836 
00837     if (favIconOverlay)
00838     {
00839         QImage favIcon(name, "PNG");
00840         int x = img->width() - favIcon.width() - 1,
00841             y = img->height() - favIcon.height() - 1;
00842         if( favIcon.depth() != 32 )
00843             favIcon = favIcon.convertDepth( 32 );
00844         if( img->depth() != 32 )
00845             *img = img->convertDepth( 32 );
00846         for( int line = 0;
00847              line < favIcon.height();
00848              ++line )
00849         {
00850             QRgb* fpos = reinterpret_cast< QRgb* >( favIcon.scanLine( line ));
00851             QRgb* ipos = reinterpret_cast< QRgb* >( img->scanLine( line + y )) + x;
00852             for( int i = 0;
00853                  i < favIcon.width();
00854                  ++i, ++fpos, ++ipos )
00855                 *ipos = qRgba( ( qRed( *ipos ) * ( 255 - qAlpha( *fpos )) + qRed( *fpos ) * qAlpha( *fpos )) / 255,
00856                                ( qGreen( *ipos ) * ( 255 - qAlpha( *fpos )) + qGreen( *fpos ) * qAlpha( *fpos )) / 255,
00857                                ( qBlue( *ipos ) * ( 255 - qAlpha( *fpos )) + qBlue( *fpos ) * qAlpha( *fpos )) / 255,
00858                                ( qAlpha( *ipos ) * ( 255 - qAlpha( *fpos )) + qAlpha( *fpos ) * qAlpha( *fpos )) / 255 );
00859         }
00860     }
00861 
00862     pix.convertFromImage(*img);
00863 
00864     delete img;
00865 
00866     QPixmapCache::insert(key, pix);
00867     return pix;
00868 }
00869 
00870 QImage *KIconLoader::loadOverlay(const QString &name, int size) const
00871 {
00872     QString key = name + '_' + QString::number(size);
00873     QImage *image = d->imgDict.find(key);
00874     if (image != 0L)
00875     return image;
00876 
00877     KIcon icon = findMatchingIcon(name, size);
00878     if (!icon.isValid())
00879     {
00880     kdDebug(264) << "Overlay " << name << "not found." << endl;
00881     return 0L;
00882     }
00883     image = new QImage(icon.path);
00884     // In some cases (since size in findMatchingIcon() is more a hint than a
00885     // constraint) image->size can be != size. If so perform rescaling.
00886     if ( size != image->width() )
00887         *image = image->smoothScale( size, size );
00888     d->imgDict.insert(key, image);
00889     return image;
00890 }
00891 
00892 
00893 
00894 QMovie KIconLoader::loadMovie(const QString& name, KIcon::Group group, int size) const
00895 {
00896     QString file = moviePath( name, group, size );
00897     if (file.isEmpty())
00898     return QMovie();
00899     int dirLen = file.findRev('/');
00900     QString icon = iconPath(name, size ? -size : group, true);
00901     if (!icon.isEmpty() && file.left(dirLen) != icon.left(dirLen))
00902     return QMovie();
00903     return QMovie(file);
00904 }
00905 
00906 QString KIconLoader::moviePath(const QString& name, KIcon::Group group, int size) const
00907 {
00908     if (!d->mpGroups) return QString::null;
00909 
00910     if ( (group < -1 || group >= KIcon::LastGroup) && group != KIcon::User )
00911     {
00912     kdDebug(264) << "Illegal icon group: " << group << endl;
00913     group = KIcon::Desktop;
00914     }
00915     if (size == 0 && group < 0)
00916     {
00917     kdDebug(264) << "Neither size nor group specified!" << endl;
00918     group = KIcon::Desktop;
00919     }
00920 
00921     QString file = name + ".mng";
00922     if (group == KIcon::User)
00923     {
00924     file = d->mpDirs->findResource("appicon", file);
00925     }
00926     else
00927     {
00928     if (size == 0)
00929         size = d->mpGroups[group].size;
00930 
00931         KIcon icon;
00932 
00933     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
00934         themeNode = d->links.next() )
00935     {
00936         icon = themeNode->theme->iconPath(file, size, KIcon::MatchExact);
00937         if (icon.isValid()) goto icon_found ;
00938 
00939         icon = themeNode->theme->iconPath(file, size, KIcon::MatchBest);
00940         if (icon.isValid()) goto icon_found ;
00941     }
00942 
00943     icon_found:
00944     file = icon.isValid() ? icon.path : QString::null;
00945     }
00946     return file;
00947 }
00948 
00949 
00950 QStringList KIconLoader::loadAnimated(const QString& name, KIcon::Group group, int size) const
00951 {
00952     QStringList lst;
00953 
00954     if (!d->mpGroups) return lst;
00955 
00956     if ((group < -1) || (group >= KIcon::LastGroup))
00957     {
00958     kdDebug(264) << "Illegal icon group: " << group << endl;
00959     group = KIcon::Desktop;
00960     }
00961     if ((size == 0) && (group < 0))
00962     {
00963     kdDebug(264) << "Neither size nor group specified!" << endl;
00964     group = KIcon::Desktop;
00965     }
00966 
00967     QString file = name + "/0001";
00968     if (group == KIcon::User)
00969     {
00970     file = d->mpDirs->findResource("appicon", file + ".png");
00971     } else
00972     {
00973     if (size == 0)
00974         size = d->mpGroups[group].size;
00975     KIcon icon = findMatchingIcon(file, size);
00976     file = icon.isValid() ? icon.path : QString::null;
00977 
00978     }
00979     if (file.isEmpty())
00980     return lst;
00981 
00982     QString path = file.left(file.length()-8);
00983     DIR* dp = opendir( QFile::encodeName(path) );
00984     if(!dp)
00985         return lst;
00986 
00987     struct dirent* ep;
00988     while( ( ep = readdir( dp ) ) != 0L )
00989     {
00990         QString fn(QFile::decodeName(ep->d_name));
00991         if(!(fn.left(4)).toUInt())
00992             continue;
00993 
00994         lst += path + fn;
00995     }
00996     closedir ( dp );
00997     lst.sort();
00998     return lst;
00999 }
01000 
01001 KIconTheme *KIconLoader::theme() const
01002 {
01003     if (d->mpThemeRoot) return d->mpThemeRoot->theme;
01004     return 0L;
01005 }
01006 
01007 int KIconLoader::currentSize(KIcon::Group group) const
01008 {
01009     if (!d->mpGroups) return -1;
01010 
01011     if (group < 0 || group >= KIcon::LastGroup)
01012     {
01013     kdDebug(264) << "Illegal icon group: " << group << endl;
01014     return -1;
01015     }
01016     return d->mpGroups[group].size;
01017 }
01018 
01019 QStringList KIconLoader::queryIconsByDir( const QString& iconsDir ) const
01020 {
01021   QDir dir(iconsDir);
01022   QStringList lst = dir.entryList("*.png;*.xpm", QDir::Files);
01023   QStringList result;
01024   QStringList::ConstIterator it;
01025   for (it=lst.begin(); it!=lst.end(); ++it)
01026     result += iconsDir + "/" + *it;
01027   return result;
01028 }
01029 
01030 QStringList KIconLoader::queryIconsByContext(int group_or_size,
01031                         KIcon::Context context) const
01032 {
01033     QStringList result;
01034     if (group_or_size >= KIcon::LastGroup)
01035     {
01036     kdDebug(264) << "Illegal icon group: " << group_or_size << endl;
01037     return result;
01038     }
01039     int size;
01040     if (group_or_size >= 0)
01041     size = d->mpGroups[group_or_size].size;
01042     else
01043     size = -group_or_size;
01044 
01045     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
01046             themeNode = d->links.next() )
01047        themeNode->queryIconsByContext(&result, size, context);
01048 
01049     // Eliminate duplicate entries (same icon in different directories)
01050     QString name;
01051     QStringList res2, entries;
01052     QStringList::ConstIterator it;
01053     for (it=result.begin(); it!=result.end(); ++it)
01054     {
01055     int n = (*it).findRev('/');
01056     if (n == -1)
01057         name = *it;
01058     else
01059         name = (*it).mid(n+1);
01060     name = removeIconExtension(name);
01061     if (!entries.contains(name))
01062     {
01063         entries += name;
01064         res2 += *it;
01065     }
01066     }
01067     return res2;
01068 
01069 }
01070 
01071 QStringList KIconLoader::queryIcons(int group_or_size, KIcon::Context context) const
01072 {
01073     QStringList result;
01074     if (group_or_size >= KIcon::LastGroup)
01075     {
01076     kdDebug(264) << "Illegal icon group: " << group_or_size << endl;
01077     return result;
01078     }
01079     int size;
01080     if (group_or_size >= 0)
01081     size = d->mpGroups[group_or_size].size;
01082     else
01083     size = -group_or_size;
01084 
01085     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
01086             themeNode = d->links.next() )
01087        themeNode->queryIcons(&result, size, context);
01088 
01089     // Eliminate duplicate entries (same icon in different directories)
01090     QString name;
01091     QStringList res2, entries;
01092     QStringList::ConstIterator it;
01093     for (it=result.begin(); it!=result.end(); ++it)
01094     {
01095     int n = (*it).findRev('/');
01096     if (n == -1)
01097         name = *it;
01098     else
01099         name = (*it).mid(n+1);
01100     name = removeIconExtension(name);
01101     if (!entries.contains(name))
01102     {
01103         entries += name;
01104         res2 += *it;
01105     }
01106     }
01107     return res2;
01108 }
01109 
01110 // used by KIconDialog to find out which contexts to offer in a combobox
01111 bool KIconLoader::hasContext(KIcon::Context context) const
01112 {
01113     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
01114             themeNode = d->links.next() )
01115        if( themeNode->theme->hasContext( context ))
01116            return true;
01117     return false;
01118 }
01119 
01120 KIconEffect * KIconLoader::iconEffect() const
01121 {
01122     return &d->mpEffect;
01123 }
01124 
01125 bool KIconLoader::alphaBlending(KIcon::Group group) const
01126 {
01127     if (!d->mpGroups) return false;
01128 
01129     if (group < 0 || group >= KIcon::LastGroup)
01130     {
01131     kdDebug(264) << "Illegal icon group: " << group << endl;
01132     return false;
01133     }
01134     return d->mpGroups[group].alphaBlending;
01135 }
01136 
01137 QIconSet KIconLoader::loadIconSet(const QString& name, KIcon::Group group, int size, bool canReturnNull)
01138 {
01139     return loadIconSet( name, group, size, canReturnNull, true );
01140 }
01141 
01142 QIconSet KIconLoader::loadIconSet(const QString& name, KIcon::Group group, int size)
01143 {
01144     return loadIconSet( name, group, size, false );
01145 }
01146 
01147 /*** class for delayed icon loading for QIconSet ***/
01148 
01149 class KIconFactory
01150     : public QIconFactory
01151     {
01152     public:
01153         KIconFactory( const QString& iconName_P, KIcon::Group group_P,
01154             int size_P, KIconLoader* loader_P );
01155         KIconFactory( const QString& iconName_P, KIcon::Group group_P,
01156             int size_P, KIconLoader* loader_P, bool canReturnNull );
01157         virtual QPixmap* createPixmap( const QIconSet&, QIconSet::Size, QIconSet::Mode, QIconSet::State );
01158     private:
01159         QString iconName;
01160         KIcon::Group group;
01161         int size;
01162         KIconLoader* loader;
01163         bool canReturnNull;
01164     };
01165 
01166 
01167 QIconSet KIconLoader::loadIconSet( const QString& name, KIcon::Group g, int s,
01168     bool canReturnNull, bool immediateExistenceCheck)
01169 {
01170     if ( !d->delayedLoading )
01171         return loadIconSetNonDelayed( name, g, s, canReturnNull );
01172 
01173     if (g < -1 || g > 6) {
01174         kdDebug() << "KIconLoader::loadIconSet " << name << " " << (int)g << " " << s << endl;
01175         qDebug("%s", kdBacktrace().latin1());
01176         abort();
01177     }
01178 
01179     if(canReturnNull && immediateExistenceCheck)
01180     { // we need to find out if the icon actually exists
01181         QPixmap pm = loadIcon( name, g, s, KIcon::DefaultState, NULL, true );
01182         if( pm.isNull())
01183             return QIconSet();
01184 
01185         QIconSet ret( pm );
01186         ret.installIconFactory( new KIconFactory( name, g, s, this ));
01187         return ret;
01188     }
01189 
01190     QIconSet ret;
01191     ret.installIconFactory( new KIconFactory( name, g, s, this, canReturnNull ));
01192     return ret;
01193 }
01194 
01195 QIconSet KIconLoader::loadIconSetNonDelayed( const QString& name,
01196                                              KIcon::Group g,
01197                                              int s, bool canReturnNull )
01198 {
01199     QIconSet iconset;
01200     QPixmap tmp = loadIcon(name, g, s, KIcon::ActiveState, NULL, canReturnNull);
01201     iconset.setPixmap( tmp, QIconSet::Small, QIconSet::Active );
01202     // we don't use QIconSet's resizing anyway
01203     iconset.setPixmap( tmp, QIconSet::Large, QIconSet::Active );
01204     tmp = loadIcon(name, g, s, KIcon::DisabledState, NULL, canReturnNull);
01205     iconset.setPixmap( tmp, QIconSet::Small, QIconSet::Disabled );
01206     iconset.setPixmap( tmp, QIconSet::Large, QIconSet::Disabled );
01207     tmp = loadIcon(name, g, s, KIcon::DefaultState, NULL, canReturnNull);
01208     iconset.setPixmap( tmp, QIconSet::Small, QIconSet::Normal );
01209     iconset.setPixmap( tmp, QIconSet::Large, QIconSet::Normal );
01210     return iconset;
01211 }
01212 
01213 KIconFactory::KIconFactory( const QString& iconName_P, KIcon::Group group_P,
01214     int size_P, KIconLoader* loader_P )
01215     : iconName( iconName_P ), group( group_P ), size( size_P ), loader( loader_P )
01216 {
01217     canReturnNull = false;
01218     setAutoDelete( true );
01219 }
01220 
01221 KIconFactory::KIconFactory( const QString& iconName_P, KIcon::Group group_P,
01222     int size_P, KIconLoader* loader_P, bool canReturnNull_P )
01223     : iconName( iconName_P ), group( group_P ), size( size_P ),
01224       loader( loader_P ), canReturnNull( canReturnNull_P)
01225 {
01226     setAutoDelete( true );
01227 }
01228 
01229 QPixmap* KIconFactory::createPixmap( const QIconSet&, QIconSet::Size, QIconSet::Mode mode_P, QIconSet::State )
01230     {
01231 #ifdef KICONLOADER_CHECKS
01232     bool found = false;
01233     for( QValueList< KIconLoaderDebug >::Iterator it = kiconloaders->begin();
01234          it != kiconloaders->end();
01235          ++it )
01236         {
01237         if( (*it).loader == loader )
01238             {
01239             found = true;
01240             if( !(*it).valid )
01241                 {
01242 #ifdef NDEBUG
01243                 loader = KGlobal::iconLoader();
01244                 iconName = "no_way_man_you_will_get_broken_icon";
01245 #else
01246                 kdWarning() << "Using already destroyed KIconLoader for loading an icon!" << endl;
01247                 kdWarning() << "Appname:" << (*it).appname << ", icon:" << iconName << endl;
01248                 kdWarning() << "Deleted at:" << endl;
01249                 kdWarning() << (*it).delete_bt << endl;
01250                 kdWarning() << "Current:" << endl;
01251                 kdWarning() << kdBacktrace() << endl;
01252                 abort();
01253                 return NULL;
01254 #endif
01255                 }
01256             break;
01257             }
01258         }
01259     if( !found )
01260         {
01261 #ifdef NDEBUG
01262         loader = KGlobal::iconLoader();
01263         iconName = "no_way_man_you_will_get_broken_icon";
01264 #else
01265         kdWarning() << "Using unknown KIconLoader for loading an icon!" << endl;
01266         kdWarning() << "Icon:" << iconName << endl;
01267         kdWarning() << kdBacktrace() << endl;
01268         abort();
01269         return NULL;
01270 #endif
01271         }
01272 #endif
01273     // QIconSet::Mode to KIcon::State conversion
01274     static const KIcon::States tbl[] = { KIcon::DefaultState, KIcon::DisabledState, KIcon::ActiveState };
01275     int state = KIcon::DefaultState;
01276     if( mode_P <= QIconSet::Active )
01277         state = tbl[ mode_P ];
01278     if( group >= 0 && state == KIcon::ActiveState )
01279     { // active and normal icon are usually the same
01280     if( loader->iconEffect()->fingerprint(group, KIcon::ActiveState )
01281             == loader->iconEffect()->fingerprint(group, KIcon::DefaultState ))
01282             return 0; // so let QIconSet simply duplicate it
01283     }
01284     // ignore passed size
01285     // ignore passed state (i.e. on/off)
01286     QPixmap pm = loader->loadIcon( iconName, group, size, state, 0, canReturnNull );
01287     return new QPixmap( pm );
01288     }
01289 
01290 // Easy access functions
01291 
01292 QPixmap DesktopIcon(const QString& name, int force_size, int state,
01293     KInstance *instance)
01294 {
01295     KIconLoader *loader = instance->iconLoader();
01296     return loader->loadIcon(name, KIcon::Desktop, force_size, state);
01297 }
01298 
01299 QPixmap DesktopIcon(const QString& name, KInstance *instance)
01300 {
01301     return DesktopIcon(name, 0, KIcon::DefaultState, instance);
01302 }
01303 
01304 QIconSet DesktopIconSet(const QString& name, int force_size, KInstance *instance)
01305 {
01306     KIconLoader *loader = instance->iconLoader();
01307     return loader->loadIconSet( name, KIcon::Desktop, force_size );
01308 }
01309 
01310 QPixmap BarIcon(const QString& name, int force_size, int state,
01311     KInstance *instance)
01312 {
01313     KIconLoader *loader = instance->iconLoader();
01314     return loader->loadIcon(name, KIcon::Toolbar, force_size, state);
01315 }
01316 
01317 QPixmap BarIcon(const QString& name, KInstance *instance)
01318 {
01319     return BarIcon(name, 0, KIcon::DefaultState, instance);
01320 }
01321 
01322 QIconSet BarIconSet(const QString& name, int force_size, KInstance *instance)
01323 {
01324     KIconLoader *loader = instance->iconLoader();
01325     return loader->loadIconSet( name, KIcon::Toolbar, force_size );
01326 }
01327 
01328 QPixmap SmallIcon(const QString& name, int force_size, int state,
01329     KInstance *instance)
01330 {
01331     KIconLoader *loader = instance->iconLoader();
01332     return loader->loadIcon(name, KIcon::Small, force_size, state);
01333 }
01334 
01335 QPixmap SmallIcon(const QString& name, KInstance *instance)
01336 {
01337     return SmallIcon(name, 0, KIcon::DefaultState, instance);
01338 }
01339 
01340 QIconSet SmallIconSet(const QString& name, int force_size, KInstance *instance)
01341 {
01342     KIconLoader *loader = instance->iconLoader();
01343     return loader->loadIconSet( name, KIcon::Small, force_size );
01344 }
01345 
01346 QPixmap MainBarIcon(const QString& name, int force_size, int state,
01347     KInstance *instance)
01348 {
01349     KIconLoader *loader = instance->iconLoader();
01350     return loader->loadIcon(name, KIcon::MainToolbar, force_size, state);
01351 }
01352 
01353 QPixmap MainBarIcon(const QString& name, KInstance *instance)
01354 {
01355     return MainBarIcon(name, 0, KIcon::DefaultState, instance);
01356 }
01357 
01358 QIconSet MainBarIconSet(const QString& name, int force_size, KInstance *instance)
01359 {
01360     KIconLoader *loader = instance->iconLoader();
01361     return loader->loadIconSet( name, KIcon::MainToolbar, force_size );
01362 }
01363 
01364 QPixmap UserIcon(const QString& name, int state, KInstance *instance)
01365 {
01366     KIconLoader *loader = instance->iconLoader();
01367     return loader->loadIcon(name, KIcon::User, 0, state);
01368 }
01369 
01370 QPixmap UserIcon(const QString& name, KInstance *instance)
01371 {
01372     return UserIcon(name, KIcon::DefaultState, instance);
01373 }
01374 
01375 QIconSet UserIconSet(const QString& name, KInstance *instance)
01376 {
01377     KIconLoader *loader = instance->iconLoader();
01378     return loader->loadIconSet( name, KIcon::User );
01379 }
01380 
01381 int IconSize(KIcon::Group group, KInstance *instance)
01382 {
01383     KIconLoader *loader = instance->iconLoader();
01384     return loader->currentSize(group);
01385 }
01386 
01387 QPixmap KIconLoader::unknown()
01388 {
01389     QPixmap pix;
01390     if ( QPixmapCache::find("unknown", pix) )
01391             return pix;
01392 
01393     QString path = KGlobal::iconLoader()->iconPath("unknown", KIcon::Small, true);
01394     if (path.isEmpty())
01395     {
01396     kdDebug(264) << "Warning: Cannot find \"unknown\" icon." << endl;
01397     pix.resize(32,32);
01398     } else
01399     {
01400         pix.load(path);
01401         QPixmapCache::insert("unknown", pix);
01402     }
01403 
01404     return pix;
01405 }
01406 
01407 void KIconLoaderPrivate::reconfigure()
01408 {
01409   q->reconfigure(appname, mpDirs);
01410 }
01411 
01412 #include "kiconloader_p.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys