kiconloader.cpp

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