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     // Make the app icons themable!!!
00236     d->mpDirs->addResourceType("appicon", KStandardDirs::kde_default("icon") +
00237         KIconTheme::current() + appname + "/pics/");
00238     d->mpDirs->addResourceType("appicon", KStandardDirs::kde_default("icon") +
00239         KIconTheme::current() + appname + "/toolbar/");
00240     // Insert application specific themes at the top.
00241     d->mpDirs->addResourceType("appicon", KStandardDirs::kde_default("data") +
00242         appname + "/pics/");
00243     // ################## KDE4: consider removing the toolbar directory
00244     d->mpDirs->addResourceType("appicon", KStandardDirs::kde_default("data") +
00245         appname + "/toolbar/");
00246 
00247     // Add legacy icon dirs.
00248     QStringList dirs;
00249     dirs += d->mpDirs->resourceDirs("icon");
00250     dirs += d->mpDirs->resourceDirs("pixmap");
00251     dirs += d->mpDirs->resourceDirs("xdgdata-icon");
00252     dirs += "/usr/share/pixmaps";
00253     // These are not in the icon spec, but e.g. GNOME puts some icons there anyway.
00254     dirs += d->mpDirs->resourceDirs("xdgdata-pixmap");
00255     for (QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it)
00256     d->mpDirs->addResourceDir("appicon", *it);
00257 
00258 #ifndef NDEBUG
00259     QString dbgString = "Theme tree: ";
00260     d->mpThemeRoot->printTree(dbgString);
00261     kdDebug(264) << dbgString << endl;
00262 #endif
00263 }
00264 
00265 KIconLoader::~KIconLoader()
00266 {
00267 #ifdef KICONLOADER_CHECKS
00268     for( QValueList< KIconLoaderDebug >::Iterator it = kiconloaders->begin();
00269          it != kiconloaders->end();
00270          ++it )
00271         {
00272         if( (*it).loader == this )
00273             {
00274             (*it).valid = false;
00275             (*it).delete_bt = kdBacktrace();
00276             break;
00277             }
00278         }
00279 #endif
00280     /* antlarr: There's no need to delete d->mpThemeRoot as it's already
00281        deleted when the elements of d->links are deleted */
00282     d->mpThemeRoot=0;
00283     delete[] d->mpGroups;
00284     delete d;
00285 }
00286 
00287 void KIconLoader::enableDelayedIconSetLoading( bool enable )
00288 {
00289     d->delayedLoading = enable;
00290 }
00291 
00292 bool KIconLoader::isDelayedIconSetLoadingEnabled() const
00293 {
00294     return d->delayedLoading;
00295 }
00296 
00297 void KIconLoader::addAppDir(const QString& appname)
00298 {
00299     d->mpDirs->addResourceType("appicon", KStandardDirs::kde_default("data") +
00300         appname + "/pics/");
00301     // ################## KDE4: consider removing the toolbar directory
00302     d->mpDirs->addResourceType("appicon", KStandardDirs::kde_default("data") +
00303         appname + "/toolbar/");
00304     addAppThemes(appname);
00305 }
00306 
00307 void KIconLoader::addAppThemes(const QString& appname)
00308 {
00309     if ( KIconTheme::current() != KIconTheme::defaultThemeName() )
00310     {
00311         KIconTheme *def = new KIconTheme(KIconTheme::current(), appname);
00312         if (def->isValid())
00313         {
00314             KIconThemeNode* node = new KIconThemeNode(def);
00315             d->links.append(node);
00316             addBaseThemes(node, appname);
00317         }
00318         else
00319             delete def;
00320     }
00321 
00322     KIconTheme *def = new KIconTheme(KIconTheme::defaultThemeName(), appname);
00323     KIconThemeNode* node = new KIconThemeNode(def);
00324     d->links.append(node);
00325     addBaseThemes(node, appname);
00326 }
00327 
00328 void KIconLoader::addBaseThemes(KIconThemeNode *node, const QString &appname)
00329 {
00330     QStringList lst = node->theme->inherits();
00331     QStringList::ConstIterator it;
00332 
00333     for (it=lst.begin(); it!=lst.end(); ++it)
00334     {
00335     if( d->mThemesInTree.contains(*it) && (*it) != "hicolor")
00336         continue;
00337     KIconTheme *theme = new KIconTheme(*it,appname);
00338     if (!theme->isValid()) {
00339         delete theme;
00340         continue;
00341     }
00342         KIconThemeNode *n = new KIconThemeNode(theme);
00343     d->mThemesInTree.append(*it);
00344     d->links.append(n);
00345     addBaseThemes(n, appname);
00346     }
00347 }
00348 
00349 void KIconLoader::addExtraDesktopThemes()
00350 {
00351     if ( d->extraDesktopIconsLoaded ) return;
00352 
00353     QStringList list;
00354     QStringList icnlibs = KGlobal::dirs()->resourceDirs("icon");
00355     QStringList::ConstIterator it;
00356     char buf[1000];
00357     int r;
00358     for (it=icnlibs.begin(); it!=icnlibs.end(); ++it)
00359     {
00360     QDir dir(*it);
00361     if (!dir.exists())
00362         continue;
00363     QStringList lst = dir.entryList("default.*", QDir::Dirs);
00364     QStringList::ConstIterator it2;
00365     for (it2=lst.begin(); it2!=lst.end(); ++it2)
00366     {
00367         if (!KStandardDirs::exists(*it + *it2 + "/index.desktop")
00368         && !KStandardDirs::exists(*it + *it2 + "/index.theme"))
00369         continue;
00370         r=readlink( QFile::encodeName(*it + *it2) , buf, sizeof(buf)-1);
00371         if ( r>0 )
00372         {
00373           buf[r]=0;
00374           QDir dir2( buf );
00375           QString themeName=dir2.dirName();
00376 
00377           if (!list.contains(themeName))
00378         list.append(themeName);
00379         }
00380     }
00381     }
00382 
00383     for (it=list.begin(); it!=list.end(); ++it)
00384     {
00385     if ( d->mThemesInTree.contains(*it) )
00386         continue;
00387     if ( *it == QString("default.kde") ) continue;
00388 
00389     KIconTheme *def = new KIconTheme( *it, "" );
00390     KIconThemeNode* node = new KIconThemeNode(def);
00391     d->mThemesInTree.append(*it);
00392     d->links.append(node);
00393     addBaseThemes(node, "" );
00394     }
00395 
00396     d->extraDesktopIconsLoaded=true;
00397 
00398 }
00399 
00400 bool KIconLoader::extraDesktopThemesAdded() const
00401 {
00402     return d->extraDesktopIconsLoaded;
00403 }
00404 
00405 QString KIconLoader::removeIconExtension(const QString &name) const
00406 {
00407     int extensionLength=0;
00408 
00409     QString ext = name.right(4);
00410 
00411     static const QString &png_ext = KGlobal::staticQString(".png");
00412     static const QString &xpm_ext = KGlobal::staticQString(".xpm");
00413     if (ext == png_ext || ext == xpm_ext)
00414       extensionLength=4;
00415 #ifdef HAVE_LIBART
00416     else
00417     {
00418     static const QString &svgz_ext = KGlobal::staticQString(".svgz");
00419     static const QString &svg_ext = KGlobal::staticQString(".svg");
00420 
00421     if (name.right(5) == svgz_ext)
00422         extensionLength=5;
00423     else if (ext == svg_ext)
00424         extensionLength=4;
00425     }
00426 #endif
00427 
00428     if ( extensionLength > 0 )
00429     {
00430     return name.left(name.length() - extensionLength);
00431     }
00432     return name;
00433 }
00434 
00435 QString KIconLoader::removeIconExtensionInternal(const QString &name) const
00436 {
00437     QString name_noext = removeIconExtension(name);
00438 
00439 #ifndef NDEBUG
00440     if (name != name_noext)
00441     {
00442     kdDebug(264) << "Application " << KGlobal::instance()->instanceName()
00443              << " loads icon " << name << " with extension." << endl;
00444     }
00445 #endif
00446 
00447     return name_noext;
00448 }
00449 
00450 KIcon KIconLoader::findMatchingIcon(const QString& name, int size) const
00451 {
00452     KIcon icon;
00453 
00454     const QString *ext[4];
00455     int count=0;
00456     static const QString &png_ext = KGlobal::staticQString(".png");
00457     ext[count++]=&png_ext;
00458 #ifdef HAVE_LIBART
00459     static const QString &svgz_ext = KGlobal::staticQString(".svgz");
00460     ext[count++]=&svgz_ext;
00461     static const QString &svg_ext = KGlobal::staticQString(".svg");
00462     ext[count++]=&svg_ext;
00463 #endif
00464     static const QString &xpm_ext = KGlobal::staticQString(".xpm");
00465     ext[count++]=&xpm_ext;
00466 
00467     /* antlarr: Multiple inheritance is a broken concept on icon themes, so
00468        the next code doesn't support it on purpose because in fact, it was
00469        never supported at all. This makes the order in which we look for an
00470        icon as:
00471 
00472        png, svgz, svg, xpm exact match
00473        next theme in inheritance tree : png, svgz, svg, xpm exact match
00474        next theme in inheritance tree : png, svgz, svg, xpm exact match
00475        and so on
00476 
00477        And if the icon couldn't be found then it tries best match in the same
00478        order.
00479 
00480        */
00481     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
00482     themeNode = d->links.next() )
00483     {
00484     for (int i = 0 ; i < count ; i++)
00485     {
00486         icon = themeNode->theme->iconPath(name + *ext[i], size, KIcon::MatchExact);
00487         if (icon.isValid())
00488         return icon;
00489     }
00490 
00491     }
00492 
00493     for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
00494     themeNode = d->links.next() )
00495     {
00496     for (int i = 0 ; i < count ; i++)
00497     {
00498         icon = themeNode->theme->iconPath(name + *ext[i], size, KIcon::MatchBest);
00499         if (icon.isValid())
00500         return icon;
00501     }
00502 
00503     }
00504 
00505     return icon;
00506 }
00507 
00508 inline QString KIconLoader::unknownIconPath( int size ) const
00509 {
00510     static const QString &str_unknown = KGlobal::staticQString("unknown");
00511 
00512     KIcon icon = findMatchingIcon(str_unknown, size);
00513     if (!icon.isValid())
00514     {
00515         kdDebug(264) << "Warning: could not find \"Unknown\" icon for size = "
00516                      << size << endl;
00517         return QString::null;
00518     }
00519     return icon.path;
00520 }
00521 
00522 // Finds the absolute path to an icon.
00523 
00524 QString KIconLoader::iconPath(const QString& _name, int group_or_size,
00525                   bool canReturnNull) const
00526 {
00527     if (d->mpThemeRoot == 0L)
00528     return QString::null;
00529 
00530     if (!QDir::isRelativePath(_name))
00531     return _name;
00532 
00533     QString name = removeIconExtensionInternal( _name );
00534 
00535     QString path;
00536     if (group_or_size == KIcon::User)
00537     {
00538     static const QString &png_ext = KGlobal::staticQString(".png");
00539     static const QString &xpm_ext = KGlobal::staticQString(".xpm");
00540     path = d->mpDirs->findResource("appicon", name + png_ext);
00541 
00542 #ifdef HAVE_LIBART
00543     static const QString &svgz_ext = KGlobal::staticQString(".svgz");
00544     static const QString &svg_ext = KGlobal::staticQString(".svg");
00545     if (path.isEmpty())
00546         path = d->mpDirs->findResource("appicon", name + svgz_ext);
00547     if (path.isEmpty())
00548        path = d->mpDirs->findResource("appicon", name + svg_ext);
00549 #endif
00550     if (path.isEmpty())
00551          path = d->mpDirs->findResource("appicon", name + xpm_ext);
00552     return path;
00553     }
00554 
00555     if (group_or_size >= KIcon::LastGroup)
00556     {
00557     kdDebug(264) << "Illegal icon group: " << group_or_size << endl;
00558     return path;
00559     }
00560 
00561     int size;
00562     if (group_or_size >= 0)
00563     size = d->mpGroups[group_or_size].size;
00564     else
00565     size = -group_or_size;
00566 
00567     if (_name.isEmpty()) {
00568         if (canReturnNull)
00569             return QString::null;
00570         else
00571             return unknownIconPath(size);
00572     }
00573 
00574     KIcon icon = findMatchingIcon(name, size);
00575 
00576     if (!icon.isValid())
00577     {
00578     // Try "User" group too.
00579     path = iconPath(name, KIcon::User, true);
00580     if (!path.isEmpty() || canReturnNull)
00581         return path;
00582 
00583     if (canReturnNull)
00584         return QString::null;
00585         else
00586             return unknownIconPath(size);
00587     }
00588     return icon.path;
00589 }
00590 
00591 QPixmap KIconLoader::loadIcon(const QString& _name, KIcon::Group group, int size,
00592                               int state, QString *path_store, bool canReturnNull) const
00593 {
00594     QString name = _name;
00595     QPixmap pix;
00596     QString key;
00597     bool absolutePath=false, favIconOverlay=false;
00598 
00599     if (d->mpThemeRoot == 0L)
00600     return pix;
00601 
00602     // Special case for absolute path icons.
00603     if (name.startsWith("favicons/"))
00604     {
00605        favIconOverlay = true;
00606        name = locateLocal("cache", name+".png");
00607     }
00608     if (!QDir::isRelativePath(name)) absolutePath=true;
00609 
00610     static const QString &str_unknown = KGlobal::staticQString("unknown");
00611 
00612     // Special case for "User" icons.
00613     if (group == KIcon::User)
00614     {
00615     key = "$kicou_";
00616         key += QString::number(size); key += '_';
00617     key += name;
00618     bool inCache = QPixmapCache::find(key, pix);
00619     if (inCache && (path_store == 0L))
00620         return pix;
00621 
00622     QString path = (absolutePath) ? name :
00623             iconPath(name, KIcon::User, canReturnNull);
00624     if (path.isEmpty())
00625     {
00626         if (canReturnNull)
00627         return pix;
00628         // We don't know the desired size: use small
00629         path = iconPath(str_unknown, KIcon::Small, true);
00630         if (path.isEmpty())
00631         {
00632         kdDebug(264) << "Warning: Cannot find \"unknown\" icon." << endl;
00633         return pix;
00634         }
00635     }
00636 
00637     if (path_store != 0L)
00638         *path_store = path;
00639     if (inCache)
00640         return pix;
00641     QImage img(path);
00642     if (size != 0)
00643         img=img.smoothScale(size,size);
00644 
00645     pix.convertFromImage(img);
00646     QPixmapCache::insert(key, pix);
00647     return pix;
00648     }
00649 
00650     // Regular case: Check parameters
00651 
00652     if ((group < -1) || (group >= KIcon::LastGroup))
00653     {
00654     kdDebug(264) << "Illegal icon group: " << group << endl;
00655     group = KIcon::Desktop;
00656     }
00657 
00658     int overlay = (state & KIcon::OverlayMask);
00659     state &= ~KIcon::OverlayMask;
00660     if ((state < 0) || (state >= KIcon::LastState))
00661     {
00662     kdDebug(264) << "Illegal icon state: " << state << endl;
00663     state = KIcon::DefaultState;
00664     }
00665 
00666     if (size == 0 && group < 0)
00667     {
00668     kdDebug(264) << "Neither size nor group specified!" << endl;
00669     group = KIcon::Desktop;
00670     }
00671 
00672     if (!absolutePath)
00673     {
00674         if (!canReturnNull && name.isEmpty())
00675             name = str_unknown;
00676         else
00677         name = removeIconExtensionInternal(name);
00678     }
00679 
00680     // If size == 0, use default size for the specified group.
00681     if (size == 0)
00682     {
00683     size = d->mpGroups[group].size;
00684     }
00685     favIconOverlay = favIconOverlay && size > 22;
00686 
00687     // Generate a unique cache key for the icon.
00688 
00689     key = "$kico_";
00690     key += name; key += '_';
00691     key += QString::number(size); key += '_';
00692 
00693     QString overlayStr = QString::number( overlay );
00694 
00695     QString noEffectKey = key + '_' + overlayStr;
00696 
00697     if (group >= 0)
00698     {
00699     key += d->mpEffect.fingerprint(group, state);
00700     if (d->mpGroups[group].dblPixels)
00701         key += QString::fromLatin1(":dblsize");
00702     } else
00703     key += QString::fromLatin1("noeffect");
00704     key += '_';
00705     key += overlayStr;
00706 
00707     // Is the icon in the cache?
00708     bool inCache = QPixmapCache::find(key, pix);
00709     if (inCache && (path_store == 0L))
00710     return pix;
00711 
00712     QImage *img = 0;
00713     int iconType;
00714     int iconThreshold;
00715 
00716     if ( ( path_store != 0L ) ||
00717          noEffectKey != d->lastImageKey )
00718     {
00719         // No? load it.
00720         KIcon icon;
00721         if (absolutePath && !favIconOverlay)
00722         {
00723             icon.context=KIcon::Any;
00724             icon.type=KIcon::Scalable;
00725             icon.path=name;
00726         }
00727         else
00728         {
00729             if (!name.isEmpty())
00730                 icon = findMatchingIcon(favIconOverlay ? QString("www") : name, size);
00731 
00732             if (!icon.isValid())
00733             {
00734                 // Try "User" icon too. Some apps expect this.
00735                 if (!name.isEmpty())
00736                     pix = loadIcon(name, KIcon::User, size, state, path_store, true);
00737                 if (!pix.isNull() || canReturnNull) {
00738                     QPixmapCache::insert(key, pix);
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