kiconloader.cpp

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