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