• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kdecore
 

kdecore

  • kdecore
kiconloader.cpp
1 /* vi: ts=8 sts=4 sw=4
2  *
3  * $Id$
4  *
5  * This file is part of the KDE project, module kdecore.
6  * Copyright (C) 2000 Geert Jansen <jansen@kde.org>
7  * Antonio Larrosa <larrosa@kde.org>
8  *
9  * This is free software; it comes under the GNU Library General
10  * Public License, version 2. See the file "COPYING.LIB" for the
11  * exact licensing terms.
12  *
13  * kiconloader.cpp: An icon loader for KDE with theming functionality.
14  */
15 
16 #include <tqstring.h>
17 #include <tqstringlist.h>
18 #include <tqptrlist.h>
19 #include <tqintdict.h>
20 #include <tqpixmap.h>
21 #include <tqpixmapcache.h>
22 #include <tqimage.h>
23 #include <tqfileinfo.h>
24 #include <tqdir.h>
25 #include <tqiconset.h>
26 #include <tqmovie.h>
27 #include <tqbitmap.h>
28 
29 #include <kapplication.h>
30 #include <kipc.h>
31 #include <kdebug.h>
32 #include <kstandarddirs.h>
33 #include <kglobal.h>
34 #include <kconfig.h>
35 #include <ksimpleconfig.h>
36 #include <kinstance.h>
37 
38 #include <kicontheme.h>
39 #include <kiconloader.h>
40 #include <kiconeffect.h>
41 
42 #include <sys/types.h>
43 #include <stdlib.h> //for abs
44 #include <unistd.h> //for readlink
45 #include <dirent.h>
46 #include <config.h>
47 #include <assert.h>
48 
49 #ifdef HAVE_LIBART
50 #include "svgicons/ksvgiconengine.h"
51 #include "svgicons/ksvgiconpainter.h"
52 #endif
53 
54 #include <kimageeffect.h>
55 
56 #include "kiconloader_p.h"
57 
58 /*** KIconThemeNode: A node in the icon theme dependancy tree. ***/
59 
60 KIconThemeNode::KIconThemeNode(KIconTheme *_theme)
61 {
62  theme = _theme;
63 }
64 
65 KIconThemeNode::~KIconThemeNode()
66 {
67  delete theme;
68 }
69 
70 void KIconThemeNode::printTree(TQString& dbgString) const
71 {
72  /* This method doesn't have much sense anymore, so maybe it should
73  be removed in the (near?) future */
74  dbgString += "(";
75  dbgString += theme->name();
76  dbgString += ")";
77 }
78 
79 void KIconThemeNode::queryIcons(TQStringList *result,
80  int size, KIcon::Context context) const
81 {
82  // add the icons of this theme to it
83  *result += theme->queryIcons(size, context);
84 }
85 
86 void KIconThemeNode::queryIconsByContext(TQStringList *result,
87  int size, KIcon::Context context) const
88 {
89  // add the icons of this theme to it
90  *result += theme->queryIconsByContext(size, context);
91 }
92 
93 KIcon KIconThemeNode::findIcon(const TQString& name, int size,
94  KIcon::MatchType match) const
95 {
96  return theme->iconPath(name, size, match);
97 }
98 
99 
100 /*** KIconGroup: Icon type description. ***/
101 
102 struct KIconGroup
103 {
104  int size;
105  bool dblPixels;
106  bool alphaBlending;
107 };
108 
109 #define KICONLOADER_CHECKS
110 #ifdef KICONLOADER_CHECKS
111 // Keep a list of recently created and destroyed KIconLoader instances in order
112 // to detect bugs like #68528.
113 struct KIconLoaderDebug
114  {
115  KIconLoaderDebug( KIconLoader* l, const TQString& a )
116  : loader( l ), appname( a ), valid( true )
117  {}
118  KIconLoaderDebug() {}; // this TQValueList feature annoys me
119  KIconLoader* loader;
120  TQString appname;
121  bool valid;
122  TQString delete_bt;
123  };
124 
125 static TQValueList< KIconLoaderDebug > *kiconloaders;
126 #endif
127 
128 /*** KIconLoader: the icon loader ***/
129 
130 KIconLoader::KIconLoader(const TQString& _appname, KStandardDirs *_dirs)
131 {
132 #ifdef KICONLOADER_CHECKS
133  if( kiconloaders == NULL )
134  kiconloaders = new TQValueList< KIconLoaderDebug>();
135  // check for the (very unlikely case) that new KIconLoader gets allocated
136  // at exactly same address like some previous one
137  for( TQValueList< KIconLoaderDebug >::Iterator it = kiconloaders->begin();
138  it != kiconloaders->end();
139  )
140  {
141  if( (*it).loader == this )
142  it = kiconloaders->remove( it );
143  else
144  ++it;
145  }
146  kiconloaders->append( KIconLoaderDebug( this, _appname ));
147 #endif
148  d = new KIconLoaderPrivate;
149  d->q = this;
150  d->mpGroups = 0L;
151  d->imgDict.setAutoDelete(true);
152  d->links.setAutoDelete(true);
153 
154  if (kapp) {
155  kapp->addKipcEventMask(KIPC::IconChanged);
156  TQObject::connect(kapp, TQT_SIGNAL(updateIconLoaders()), d, TQT_SLOT(reconfigure()));
157  }
158 
159  init( _appname, _dirs );
160 }
161 
162 void KIconLoader::reconfigure( const TQString& _appname, KStandardDirs *_dirs )
163 {
164  d->links.clear();
165  d->imgDict.clear();
166  d->mThemesInTree.clear();
167  d->lastImage.reset();
168  d->lastImageKey = TQString::null;
169  delete [] d->mpGroups;
170 
171  init( _appname, _dirs );
172 }
173 
174 void KIconLoader::init( const TQString& _appname, KStandardDirs *_dirs )
175 {
176  // If this is unequal to 0, the iconloader is initialized
177  // successfully.
178  d->mpThemeRoot = 0L;
179 
180  d->appname = _appname;
181  d->extraDesktopIconsLoaded = false;
182  d->delayedLoading = false;
183 
184  if (_dirs)
185  d->mpDirs = _dirs;
186  else
187  d->mpDirs = KGlobal::dirs();
188 
189  TQString appname = _appname;
190  if (appname.isEmpty())
191  appname = KGlobal::instance()->instanceName();
192 
193  // Add the default theme and its base themes to the theme tree
194  KIconTheme *def = new KIconTheme(KIconTheme::current(), appname);
195  if (!def->isValid())
196  {
197  delete def;
198  // warn, as this is actually a small penalty hit
199  kdDebug(264) << "Couldn't find current icon theme, falling back to default." << endl;
200  def = new KIconTheme(KIconTheme::defaultThemeName(), appname);
201  if (!def->isValid())
202  {
203  kdError(264) << "Error: standard icon theme"
204  << " \"" << KIconTheme::defaultThemeName() << "\" "
205  << " not found!" << endl;
206  d->mpGroups=0L;
207  return;
208  }
209  }
210  d->mpThemeRoot = new KIconThemeNode(def);
211  d->links.append(d->mpThemeRoot);
212  d->mThemesInTree += KIconTheme::current();
213  addBaseThemes(d->mpThemeRoot, appname);
214 
215  // These have to match the order in kicontheme.h
216  static const char * const groups[] = { "Desktop", "Toolbar", "MainToolbar", "Small", "Panel", 0L };
217  KConfig *config = KGlobal::config();
218  KConfigGroupSaver cs(config, "dummy");
219 
220  // loading config and default sizes
221  d->mpGroups = new KIconGroup[(int) KIcon::LastGroup];
222  for (KIcon::Group i=KIcon::FirstGroup; i<KIcon::LastGroup; i++)
223  {
224  if (groups[i] == 0L)
225  break;
226  config->setGroup(TQString::fromLatin1(groups[i]) + "Icons");
227  d->mpGroups[i].size = config->readNumEntry("Size", 0);
228  d->mpGroups[i].dblPixels = config->readBoolEntry("DoublePixels", false);
229  if (TQPixmap::defaultDepth()>8)
230  d->mpGroups[i].alphaBlending = config->readBoolEntry("AlphaBlending", true);
231  else
232  d->mpGroups[i].alphaBlending = false;
233 
234  if (!d->mpGroups[i].size)
235  d->mpGroups[i].size = d->mpThemeRoot->theme->defaultSize(i);
236  }
237 
238  // Insert application specific themes at the top.
239  d->mpDirs->addResourceType("appicon", KStandardDirs::kde_default("data") +
240  appname + "/pics/");
241  // ################## KDE4: consider removing the toolbar directory
242  d->mpDirs->addResourceType("appicon", KStandardDirs::kde_default("data") +
243  appname + "/toolbar/");
244 
245  // Add legacy icon dirs.
246  TQStringList dirs;
247  dirs += d->mpDirs->resourceDirs("icon");
248  dirs += d->mpDirs->resourceDirs("pixmap");
249  dirs += d->mpDirs->resourceDirs("xdgdata-icon");
250  dirs += "/usr/share/pixmaps";
251  // These are not in the icon spec, but e.g. GNOME puts some icons there anyway.
252  dirs += d->mpDirs->resourceDirs("xdgdata-pixmap");
253  for (TQStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it)
254  d->mpDirs->addResourceDir("appicon", *it);
255 
256 #ifndef NDEBUG
257  TQString dbgString = "Theme tree: ";
258  d->mpThemeRoot->printTree(dbgString);
259  kdDebug(264) << dbgString << endl;
260 #endif
261 }
262 
263 KIconLoader::~KIconLoader()
264 {
265 #ifdef KICONLOADER_CHECKS
266  for( TQValueList< KIconLoaderDebug >::Iterator it = kiconloaders->begin();
267  it != kiconloaders->end();
268  ++it )
269  {
270  if( (*it).loader == this )
271  {
272  (*it).valid = false;
273  (*it).delete_bt = kdBacktrace();
274  break;
275  }
276  }
277 #endif
278  /* antlarr: There's no need to delete d->mpThemeRoot as it's already
279  deleted when the elements of d->links are deleted */
280  d->mpThemeRoot=0;
281  delete[] d->mpGroups;
282  delete d;
283 }
284 
285 void KIconLoader::enableDelayedIconSetLoading( bool enable )
286 {
287  d->delayedLoading = enable;
288 }
289 
290 bool KIconLoader::isDelayedIconSetLoadingEnabled() const
291 {
292  return d->delayedLoading;
293 }
294 
295 void KIconLoader::addAppDir(const TQString& appname)
296 {
297  d->mpDirs->addResourceType("appicon", KStandardDirs::kde_default("data") +
298  appname + "/pics/");
299  // ################## KDE4: consider removing the toolbar directory
300  d->mpDirs->addResourceType("appicon", KStandardDirs::kde_default("data") +
301  appname + "/toolbar/");
302  addAppThemes(appname);
303 }
304 
305 void KIconLoader::addAppThemes(const TQString& appname)
306 {
307  if ( KIconTheme::current() != KIconTheme::defaultThemeName() )
308  {
309  KIconTheme *def = new KIconTheme(KIconTheme::current(), appname);
310  if (def->isValid())
311  {
312  KIconThemeNode* node = new KIconThemeNode(def);
313  d->links.append(node);
314  addBaseThemes(node, appname);
315  }
316  else
317  delete def;
318  }
319 
320  KIconTheme *def = new KIconTheme(KIconTheme::defaultThemeName(), appname);
321  KIconThemeNode* node = new KIconThemeNode(def);
322  d->links.append(node);
323  addBaseThemes(node, appname);
324 }
325 
326 void KIconLoader::addBaseThemes(KIconThemeNode *node, const TQString &appname)
327 {
328  TQStringList lst = node->theme->inherits();
329  TQStringList::ConstIterator it;
330 
331  for (it=lst.begin(); it!=lst.end(); ++it)
332  {
333  if( d->mThemesInTree.contains(*it) && (*it) != "hicolor")
334  continue;
335  KIconTheme *theme = new KIconTheme(*it,appname);
336  if (!theme->isValid()) {
337  delete theme;
338  continue;
339  }
340  KIconThemeNode *n = new KIconThemeNode(theme);
341  d->mThemesInTree.append(*it);
342  d->links.append(n);
343  addBaseThemes(n, appname);
344  }
345 }
346 
347 void KIconLoader::addExtraDesktopThemes()
348 {
349  if ( d->extraDesktopIconsLoaded ) return;
350 
351  TQStringList list;
352  TQStringList icnlibs = KGlobal::dirs()->resourceDirs("icon");
353  TQStringList::ConstIterator it;
354  char buf[1000];
355  int r;
356  for (it=icnlibs.begin(); it!=icnlibs.end(); ++it)
357  {
358  TQDir dir(*it);
359  if (!dir.exists())
360  continue;
361  TQStringList lst = dir.entryList("default.*", TQDir::Dirs);
362  TQStringList::ConstIterator it2;
363  for (it2=lst.begin(); it2!=lst.end(); ++it2)
364  {
365  if (!KStandardDirs::exists(*it + *it2 + "/index.desktop")
366  && !KStandardDirs::exists(*it + *it2 + "/index.theme"))
367  continue;
368  r=readlink( TQFile::encodeName(*it + *it2) , buf, sizeof(buf)-1);
369  if ( r>0 )
370  {
371  buf[r]=0;
372  TQDir dir2( buf );
373  TQString themeName=dir2.dirName();
374 
375  if (!list.contains(themeName))
376  list.append(themeName);
377  }
378  }
379  }
380 
381  for (it=list.begin(); it!=list.end(); ++it)
382  {
383  if ( d->mThemesInTree.contains(*it) )
384  continue;
385  if ( *it == TQString("default.kde") ) continue;
386 
387  KIconTheme *def = new KIconTheme( *it, "" );
388  KIconThemeNode* node = new KIconThemeNode(def);
389  d->mThemesInTree.append(*it);
390  d->links.append(node);
391  addBaseThemes(node, "" );
392  }
393 
394  d->extraDesktopIconsLoaded=true;
395 
396 }
397 
398 bool KIconLoader::extraDesktopThemesAdded() const
399 {
400  return d->extraDesktopIconsLoaded;
401 }
402 
403 TQString KIconLoader::removeIconExtension(const TQString &name) const
404 {
405  int extensionLength=0;
406 
407  TQString ext = name.right(4);
408 
409  static const TQString &png_ext = KGlobal::staticQString(".png");
410  static const TQString &xpm_ext = KGlobal::staticQString(".xpm");
411  if (ext == png_ext || ext == xpm_ext)
412  extensionLength=4;
413 #ifdef HAVE_LIBART
414  else
415  {
416  static const TQString &svgz_ext = KGlobal::staticQString(".svgz");
417  static const TQString &svg_ext = KGlobal::staticQString(".svg");
418 
419  if (name.right(5) == svgz_ext)
420  extensionLength=5;
421  else if (ext == svg_ext)
422  extensionLength=4;
423  }
424 #endif
425 
426  if ( extensionLength > 0 )
427  {
428  return name.left(name.length() - extensionLength);
429  }
430  return name;
431 }
432 
433 TQString KIconLoader::removeIconExtensionInternal(const TQString &name) const
434 {
435  TQString name_noext = removeIconExtension(name);
436 
437 #ifndef NDEBUG
438  if (name != name_noext)
439  {
440  kdDebug(264) << "Application " << KGlobal::instance()->instanceName()
441  << " loads icon " << name << " with extension." << endl;
442  }
443 #endif
444 
445  return name_noext;
446 }
447 
448 KIcon KIconLoader::findMatchingIcon(const TQString& name, int size) const
449 {
450  KIcon icon;
451 
452  const TQString *ext[4];
453  int count=0;
454  static const TQString &png_ext = KGlobal::staticQString(".png");
455  ext[count++]=&png_ext;
456 #ifdef HAVE_LIBART
457  static const TQString &svgz_ext = KGlobal::staticQString(".svgz");
458  ext[count++]=&svgz_ext;
459  static const TQString &svg_ext = KGlobal::staticQString(".svg");
460  ext[count++]=&svg_ext;
461 #endif
462  static const TQString &xpm_ext = KGlobal::staticQString(".xpm");
463  ext[count++]=&xpm_ext;
464 
465  /* JRT: To follow the XDG spec, the order in which we look for an
466  icon 1s:
467 
468  png, svgz, svg, xpm exact match
469  png, svgz, svg, xpm best match
470  next theme in inheritance tree : png, svgz, svg, xpm exact match
471  png, svgz, svg, xpm best match
472  next theme in inheritance tree : png, svgz, svg, xpm exact match
473  png, svgz, svg, xpm best match
474  and so on
475 
476  */
477  for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
478  themeNode = d->links.next() )
479  {
480  for (int i = 0 ; i < count ; i++)
481  {
482  icon = themeNode->theme->iconPath(name + *ext[i], size, KIcon::MatchExact);
483  if (icon.isValid()) goto icon_found ;
484  }
485 
486  for (int i = 0 ; i < count ; i++)
487  {
488  icon = themeNode->theme->iconPath(name + *ext[i], size, KIcon::MatchBest);
489  if (icon.isValid()) goto icon_found;
490  }
491  }
492  icon_found:
493  return icon;
494 }
495 
496 inline TQString KIconLoader::unknownIconPath( int size ) const
497 {
498  static const TQString &str_unknown = KGlobal::staticQString("unknown");
499 
500  KIcon icon = findMatchingIcon(str_unknown, size);
501  if (!icon.isValid())
502  {
503  kdDebug(264) << "Warning: could not find \"Unknown\" icon for size = "
504  << size << endl;
505  return TQString::null;
506  }
507  return icon.path;
508 }
509 
510 // Finds the absolute path to an icon.
511 
512 TQString KIconLoader::iconPath(const TQString& _name, int group_or_size,
513  bool canReturnNull) const
514 {
515  if (d->mpThemeRoot == 0L)
516  return TQString::null;
517 
518  if (!TQDir::isRelativePath(_name))
519  return _name;
520 
521  TQString name = removeIconExtensionInternal( _name );
522 
523  TQString path;
524  if (group_or_size == KIcon::User)
525  {
526  static const TQString &png_ext = KGlobal::staticQString(".png");
527  static const TQString &xpm_ext = KGlobal::staticQString(".xpm");
528  path = d->mpDirs->findResource("appicon", name + png_ext);
529 
530 #ifdef HAVE_LIBART
531  static const TQString &svgz_ext = KGlobal::staticQString(".svgz");
532  static const TQString &svg_ext = KGlobal::staticQString(".svg");
533  if (path.isEmpty())
534  path = d->mpDirs->findResource("appicon", name + svgz_ext);
535  if (path.isEmpty())
536  path = d->mpDirs->findResource("appicon", name + svg_ext);
537 #endif
538  if (path.isEmpty())
539  path = d->mpDirs->findResource("appicon", name + xpm_ext);
540  return path;
541  }
542 
543  if (group_or_size >= KIcon::LastGroup)
544  {
545  kdDebug(264) << "Illegal icon group: " << group_or_size << endl;
546  return path;
547  }
548 
549  int size;
550  if (group_or_size >= 0)
551  size = d->mpGroups[group_or_size].size;
552  else
553  size = -group_or_size;
554 
555  if (_name.isEmpty()) {
556  if (canReturnNull)
557  return TQString::null;
558  else
559  return unknownIconPath(size);
560  }
561 
562  KIcon icon = findMatchingIcon(name, size);
563 
564  if (!icon.isValid())
565  {
566  // Try "User" group too.
567  path = iconPath(name, KIcon::User, true);
568  if (!path.isEmpty() || canReturnNull)
569  return path;
570 
571  if (canReturnNull)
572  return TQString::null;
573  else
574  return unknownIconPath(size);
575  }
576  return icon.path;
577 }
578 
579 TQPixmap KIconLoader::loadIcon(const TQString& _name, KIcon::Group group, int size,
580  int state, TQString *path_store, bool canReturnNull) const
581 {
582  TQString name = _name;
583  TQPixmap pix;
584  TQString key;
585  bool absolutePath=false, favIconOverlay=false;
586 
587  if (d->mpThemeRoot == 0L)
588  return pix;
589 
590  // Special case for absolute path icons.
591  if (name.startsWith("favicons/"))
592  {
593  favIconOverlay = true;
594  name = locateLocal("cache", name+".png");
595  }
596  if (!TQDir::isRelativePath(name)) absolutePath=true;
597 
598  static const TQString &str_unknown = KGlobal::staticQString("unknown");
599 
600  // Special case for "User" icons.
601  if (group == KIcon::User)
602  {
603  key = "$kicou_";
604  key += TQString::number(size); key += '_';
605  key += name;
606  bool inCache = TQPixmapCache::find(key, pix);
607  if (inCache && (path_store == 0L))
608  return pix;
609 
610  TQString path = (absolutePath) ? name :
611  iconPath(name, KIcon::User, canReturnNull);
612  if (path.isEmpty())
613  {
614  if (canReturnNull)
615  return pix;
616  // We don't know the desired size: use small
617  path = iconPath(str_unknown, KIcon::Small, true);
618  if (path.isEmpty())
619  {
620  kdDebug(264) << "Warning: Cannot find \"unknown\" icon." << endl;
621  return pix;
622  }
623  }
624 
625  if (path_store != 0L)
626  *path_store = path;
627  if (inCache)
628  return pix;
629  TQImage img(path);
630  if (size != 0)
631  img=img.smoothScale(size,size);
632 
633  pix.convertFromImage(img);
634  TQPixmapCache::insert(key, pix);
635  return pix;
636  }
637 
638  // Regular case: Check parameters
639 
640  if ((group < -1) || (group >= KIcon::LastGroup))
641  {
642  kdDebug(264) << "Illegal icon group: " << group << endl;
643  group = KIcon::Desktop;
644  }
645 
646  int overlay = (state & KIcon::OverlayMask);
647  state &= ~KIcon::OverlayMask;
648  if ((state < 0) || (state >= KIcon::LastState))
649  {
650  kdDebug(264) << "Illegal icon state: " << state << endl;
651  state = KIcon::DefaultState;
652  }
653 
654  if (size == 0 && group < 0)
655  {
656  kdDebug(264) << "Neither size nor group specified!" << endl;
657  group = KIcon::Desktop;
658  }
659 
660  if (!absolutePath)
661  {
662  if (!canReturnNull && name.isEmpty())
663  name = str_unknown;
664  else
665  name = removeIconExtensionInternal(name);
666  }
667 
668  // If size == 0, use default size for the specified group.
669  if (size == 0)
670  {
671  size = d->mpGroups[group].size;
672  }
673  favIconOverlay = favIconOverlay && size > 22;
674 
675  // Generate a unique cache key for the icon.
676 
677  key = "$kico_";
678  key += name; key += '_';
679  key += TQString::number(size); key += '_';
680 
681  TQString overlayStr = TQString::number( overlay );
682 
683  TQString noEffectKey = key + '_' + overlayStr;
684 
685  if (group >= 0)
686  {
687  key += d->mpEffect.fingerprint(group, state);
688  if (d->mpGroups[group].dblPixels)
689  key += TQString::fromLatin1(":dblsize");
690  } else
691  key += TQString::fromLatin1("noeffect");
692  key += '_';
693  key += overlayStr;
694 
695  // Is the icon in the cache?
696  bool inCache = TQPixmapCache::find(key, pix);
697  if (inCache && (path_store == 0L))
698  return pix;
699 
700  TQImage *img = 0;
701  int iconType;
702  int iconThreshold;
703 
704  if ( ( path_store != 0L ) ||
705  noEffectKey != d->lastImageKey )
706  {
707  // No? load it.
708  KIcon icon;
709  if (absolutePath && !favIconOverlay)
710  {
711  icon.context=KIcon::Any;
712  icon.type=KIcon::Scalable;
713  icon.path=name;
714  }
715  else
716  {
717  if (!name.isEmpty())
718  icon = findMatchingIcon(favIconOverlay ? TQString("www") : name, size);
719 
720  if (!icon.isValid())
721  {
722  // Try "User" icon too. Some apps expect this.
723  if (!name.isEmpty())
724  pix = loadIcon(name, KIcon::User, size, state, path_store, true);
725  if (!pix.isNull() || canReturnNull) {
726  TQPixmapCache::insert(key, pix);
727  return pix;
728  }
729 
730  icon = findMatchingIcon(str_unknown, size);
731  if (!icon.isValid())
732  {
733  kdDebug(264)
734  << "Warning: could not find \"Unknown\" icon for size = "
735  << size << endl;
736  return pix;
737  }
738  }
739  }
740 
741  if (path_store != 0L)
742  *path_store = icon.path;
743  if (inCache)
744  return pix;
745 
746  // Use the extension as the format. Works for XPM and PNG, but not for SVG
747  TQString ext = icon.path.right(3).upper();
748  if(ext != "SVG" && ext != "VGZ")
749  {
750  img = new TQImage(icon.path, ext.latin1());
751  if (img->isNull()) {
752  delete img;
753  return pix;
754  }
755  }
756  else
757  {
758 #ifdef HAVE_LIBART
759  // Special stuff for SVG icons
760  KSVGIconEngine *svgEngine = new KSVGIconEngine();
761 
762  if(svgEngine->load(size, size, icon.path))
763  img = svgEngine->painter()->image();
764  else
765  img = new TQImage();
766 
767  delete svgEngine;
768 #else
769  img = new TQImage();
770 #endif
771  }
772 
773  iconType = icon.type;
774  iconThreshold = icon.threshold;
775 
776  d->lastImage = img->copy();
777  d->lastImageKey = noEffectKey;
778  d->lastIconType = iconType;
779  d->lastIconThreshold = iconThreshold;
780  }
781  else
782  {
783  img = new TQImage( d->lastImage.copy() );
784  iconType = d->lastIconType;
785  iconThreshold = d->lastIconThreshold;
786  }
787 
788  // Blend in all overlays
789  if (overlay)
790  {
791  TQImage *ovl;
792  KIconTheme *theme = d->mpThemeRoot->theme;
793  if ((overlay & KIcon::LockOverlay) &&
794  ((ovl = loadOverlay(theme->lockOverlay(), size)) != 0L))
795  KIconEffect::overlay(*img, *ovl);
796  if ((overlay & KIcon::LinkOverlay) &&
797  ((ovl = loadOverlay(theme->linkOverlay(), size)) != 0L))
798  KIconEffect::overlay(*img, *ovl);
799  if ((overlay & KIcon::ZipOverlay) &&
800  ((ovl = loadOverlay(theme->zipOverlay(), size)) != 0L))
801  KIconEffect::overlay(*img, *ovl);
802  if ((overlay & KIcon::ShareOverlay) &&
803  ((ovl = loadOverlay(theme->shareOverlay(), size)) != 0L))
804  KIconEffect::overlay(*img, *ovl);
805  if (overlay & KIcon::HiddenOverlay)
806  {
807  if (img->depth() != 32)
808  *img = img->convertDepth(32);
809  for (int y = 0; y < img->height(); y++)
810  {
811  QRgb *line = reinterpret_cast<QRgb *>(img->scanLine(y));
812  for (int x = 0; x < img->width(); x++)
813  line[x] = (line[x] & 0x00ffffff) | (QMIN(0x80, tqAlpha(line[x])) << 24);
814  }
815  }
816  }
817 
818  // Scale the icon and apply effects if necessary
819  if (iconType == KIcon::Scalable && size != img->width())
820  {
821  *img = img->smoothScale(size, size);
822  }
823  if (iconType == KIcon::Threshold && size != img->width())
824  {
825  if ( abs(size-img->width())>iconThreshold )
826  *img = img->smoothScale(size, size);
827  }
828  if (group >= 0 && d->mpGroups[group].dblPixels)
829  {
830  *img = d->mpEffect.doublePixels(*img);
831  }
832  if (group >= 0)
833  {
834  *img = d->mpEffect.apply(*img, group, state);
835  }
836 
837  if (favIconOverlay)
838  {
839  TQImage favIcon(name, "PNG");
840  int x = img->width() - favIcon.width() - 1,
841  y = img->height() - favIcon.height() - 1;
842  if( favIcon.depth() != 32 )
843  favIcon = favIcon.convertDepth( 32 );
844  if( img->depth() != 32 )
845  *img = img->convertDepth( 32 );
846  for( int line = 0;
847  line < favIcon.height();
848  ++line )
849  {
850  QRgb* fpos = reinterpret_cast< QRgb* >( favIcon.scanLine( line ));
851  QRgb* ipos = reinterpret_cast< QRgb* >( img->scanLine( line + y )) + x;
852  for( int i = 0;
853  i < favIcon.width();
854  ++i, ++fpos, ++ipos )
855  *ipos = tqRgba( ( tqRed( *ipos ) * ( 255 - tqAlpha( *fpos )) + tqRed( *fpos ) * tqAlpha( *fpos )) / 255,
856  ( tqGreen( *ipos ) * ( 255 - tqAlpha( *fpos )) + tqGreen( *fpos ) * tqAlpha( *fpos )) / 255,
857  ( tqBlue( *ipos ) * ( 255 - tqAlpha( *fpos )) + tqBlue( *fpos ) * tqAlpha( *fpos )) / 255,
858  ( tqAlpha( *ipos ) * ( 255 - tqAlpha( *fpos )) + tqAlpha( *fpos ) * tqAlpha( *fpos )) / 255 );
859  }
860  }
861 
862  if (TQPaintDevice::x11AppDepth() == 32) pix.convertFromImage(KImageEffect::convertToPremultipliedAlpha( *img ));
863  else pix.convertFromImage(*img);
864 
865  delete img;
866 
867  TQPixmapCache::insert(key, pix);
868  return pix;
869 }
870 
871 TQImage *KIconLoader::loadOverlay(const TQString &name, int size) const
872 {
873  TQString key = name + '_' + TQString::number(size);
874  TQImage *image = d->imgDict.find(key);
875  if (image != 0L)
876  return image;
877 
878  KIcon icon = findMatchingIcon(name, size);
879  if (!icon.isValid())
880  {
881  kdDebug(264) << "Overlay " << name << "not found." << endl;
882  return 0L;
883  }
884  image = new TQImage(icon.path);
885  // In some cases (since size in findMatchingIcon() is more a hint than a
886  // constraint) image->size can be != size. If so perform rescaling.
887  if ( size != image->width() )
888  *image = image->smoothScale( size, size );
889  d->imgDict.insert(key, image);
890  return image;
891 }
892 
893 
894 
895 TQMovie KIconLoader::loadMovie(const TQString& name, KIcon::Group group, int size) const
896 {
897  TQString file = moviePath( name, group, size );
898  if (file.isEmpty())
899  return TQMovie();
900  int dirLen = file.findRev('/');
901  TQString icon = iconPath(name, size ? -size : group, true);
902  if (!icon.isEmpty() && file.left(dirLen) != icon.left(dirLen))
903  return TQMovie();
904  return TQMovie(file);
905 }
906 
907 TQString KIconLoader::moviePath(const TQString& name, KIcon::Group group, int size) const
908 {
909  if (!d->mpGroups) return TQString::null;
910 
911  if ( (group < -1 || group >= KIcon::LastGroup) && group != KIcon::User )
912  {
913  kdDebug(264) << "Illegal icon group: " << group << endl;
914  group = KIcon::Desktop;
915  }
916  if (size == 0 && group < 0)
917  {
918  kdDebug(264) << "Neither size nor group specified!" << endl;
919  group = KIcon::Desktop;
920  }
921 
922  TQString file = name + ".mng";
923  if (group == KIcon::User)
924  {
925  file = d->mpDirs->findResource("appicon", file);
926  }
927  else
928  {
929  if (size == 0)
930  size = d->mpGroups[group].size;
931 
932  KIcon icon;
933 
934  for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
935  themeNode = d->links.next() )
936  {
937  icon = themeNode->theme->iconPath(file, size, KIcon::MatchExact);
938  if (icon.isValid()) goto icon_found ;
939 
940  icon = themeNode->theme->iconPath(file, size, KIcon::MatchBest);
941  if (icon.isValid()) goto icon_found ;
942  }
943 
944  icon_found:
945  file = icon.isValid() ? icon.path : TQString::null;
946  }
947  return file;
948 }
949 
950 
951 TQStringList KIconLoader::loadAnimated(const TQString& name, KIcon::Group group, int size) const
952 {
953  TQStringList lst;
954 
955  if (!d->mpGroups) return lst;
956 
957  if ((group < -1) || (group >= KIcon::LastGroup))
958  {
959  kdDebug(264) << "Illegal icon group: " << group << endl;
960  group = KIcon::Desktop;
961  }
962  if ((size == 0) && (group < 0))
963  {
964  kdDebug(264) << "Neither size nor group specified!" << endl;
965  group = KIcon::Desktop;
966  }
967 
968  TQString file = name + "/0001";
969  if (group == KIcon::User)
970  {
971  file = d->mpDirs->findResource("appicon", file + ".png");
972  } else
973  {
974  if (size == 0)
975  size = d->mpGroups[group].size;
976  KIcon icon = findMatchingIcon(file, size);
977  file = icon.isValid() ? icon.path : TQString::null;
978 
979  }
980  if (file.isEmpty())
981  return lst;
982 
983  TQString path = file.left(file.length()-8);
984  DIR* dp = opendir( TQFile::encodeName(path) );
985  if(!dp)
986  return lst;
987 
988  struct dirent* ep;
989  while( ( ep = readdir( dp ) ) != 0L )
990  {
991  TQString fn(TQFile::decodeName(ep->d_name));
992  if(!(fn.left(4)).toUInt())
993  continue;
994 
995  lst += path + fn;
996  }
997  closedir ( dp );
998  lst.sort();
999  return lst;
1000 }
1001 
1002 KIconTheme *KIconLoader::theme() const
1003 {
1004  if (d->mpThemeRoot) return d->mpThemeRoot->theme;
1005  return 0L;
1006 }
1007 
1008 int KIconLoader::currentSize(KIcon::Group group) const
1009 {
1010  if (!d->mpGroups) return -1;
1011 
1012  if (group < 0 || group >= KIcon::LastGroup)
1013  {
1014  kdDebug(264) << "Illegal icon group: " << group << endl;
1015  return -1;
1016  }
1017  return d->mpGroups[group].size;
1018 }
1019 
1020 TQStringList KIconLoader::queryIconsByDir( const TQString& iconsDir ) const
1021 {
1022  TQDir dir(iconsDir);
1023  TQStringList lst = dir.entryList("*.png;*.xpm", TQDir::Files);
1024  TQStringList result;
1025  TQStringList::ConstIterator it;
1026  for (it=lst.begin(); it!=lst.end(); ++it)
1027  result += iconsDir + "/" + *it;
1028  return result;
1029 }
1030 
1031 TQStringList KIconLoader::queryIconsByContext(int group_or_size,
1032  KIcon::Context context) const
1033 {
1034  TQStringList result;
1035  if (group_or_size >= KIcon::LastGroup)
1036  {
1037  kdDebug(264) << "Illegal icon group: " << group_or_size << endl;
1038  return result;
1039  }
1040  int size;
1041  if (group_or_size >= 0)
1042  size = d->mpGroups[group_or_size].size;
1043  else
1044  size = -group_or_size;
1045 
1046  for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
1047  themeNode = d->links.next() )
1048  themeNode->queryIconsByContext(&result, size, context);
1049 
1050  // Eliminate duplicate entries (same icon in different directories)
1051  TQString name;
1052  TQStringList res2, entries;
1053  TQStringList::ConstIterator it;
1054  for (it=result.begin(); it!=result.end(); ++it)
1055  {
1056  int n = (*it).findRev('/');
1057  if (n == -1)
1058  name = *it;
1059  else
1060  name = (*it).mid(n+1);
1061  name = removeIconExtension(name);
1062  if (!entries.contains(name))
1063  {
1064  entries += name;
1065  res2 += *it;
1066  }
1067  }
1068  return res2;
1069 
1070 }
1071 
1072 TQStringList KIconLoader::queryIcons(int group_or_size, KIcon::Context context) const
1073 {
1074  TQStringList result;
1075  if (group_or_size >= KIcon::LastGroup)
1076  {
1077  kdDebug(264) << "Illegal icon group: " << group_or_size << endl;
1078  return result;
1079  }
1080  int size;
1081  if (group_or_size >= 0)
1082  size = d->mpGroups[group_or_size].size;
1083  else
1084  size = -group_or_size;
1085 
1086  for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
1087  themeNode = d->links.next() )
1088  themeNode->queryIcons(&result, size, context);
1089 
1090  // Eliminate duplicate entries (same icon in different directories)
1091  TQString name;
1092  TQStringList res2, entries;
1093  TQStringList::ConstIterator it;
1094  for (it=result.begin(); it!=result.end(); ++it)
1095  {
1096  int n = (*it).findRev('/');
1097  if (n == -1)
1098  name = *it;
1099  else
1100  name = (*it).mid(n+1);
1101  name = removeIconExtension(name);
1102  if (!entries.contains(name))
1103  {
1104  entries += name;
1105  res2 += *it;
1106  }
1107  }
1108  return res2;
1109 }
1110 
1111 // used by KIconDialog to find out which contexts to offer in a combobox
1112 bool KIconLoader::hasContext(KIcon::Context context) const
1113 {
1114  for ( KIconThemeNode *themeNode = d->links.first() ; themeNode ;
1115  themeNode = d->links.next() )
1116  if( themeNode->theme->hasContext( context ))
1117  return true;
1118  return false;
1119 }
1120 
1121 KIconEffect * KIconLoader::iconEffect() const
1122 {
1123  return &d->mpEffect;
1124 }
1125 
1126 bool KIconLoader::alphaBlending(KIcon::Group group) const
1127 {
1128  if (!d->mpGroups) return false;
1129 
1130  if (group < 0 || group >= KIcon::LastGroup)
1131  {
1132  kdDebug(264) << "Illegal icon group: " << group << endl;
1133  return false;
1134  }
1135  return d->mpGroups[group].alphaBlending;
1136 }
1137 
1138 TQIconSet KIconLoader::loadIconSet(const TQString& name, KIcon::Group group, int size, bool canReturnNull)
1139 {
1140  return loadIconSet( name, group, size, canReturnNull, true );
1141 }
1142 
1143 TQIconSet KIconLoader::loadIconSet(const TQString& name, KIcon::Group group, int size)
1144 {
1145  return loadIconSet( name, group, size, false );
1146 }
1147 
1148 /*** class for delayed icon loading for TQIconSet ***/
1149 
1150 class KIconFactory
1151  : public TQIconFactory
1152  {
1153  public:
1154  KIconFactory( const TQString& iconName_P, KIcon::Group group_P,
1155  int size_P, KIconLoader* loader_P );
1156  KIconFactory( const TQString& iconName_P, KIcon::Group group_P,
1157  int size_P, KIconLoader* loader_P, bool canReturnNull );
1158  virtual TQPixmap* createPixmap( const TQIconSet&, TQIconSet::Size, TQIconSet::Mode, TQIconSet::State );
1159  private:
1160  TQString iconName;
1161  KIcon::Group group;
1162  int size;
1163  KIconLoader* loader;
1164  bool canReturnNull;
1165  };
1166 
1167 
1168 TQIconSet KIconLoader::loadIconSet( const TQString& name, KIcon::Group g, int s,
1169  bool canReturnNull, bool immediateExistenceCheck)
1170 {
1171  if ( !d->delayedLoading )
1172  return loadIconSetNonDelayed( name, g, s, canReturnNull );
1173 
1174  if (g < -1 || g > 6) {
1175  kdDebug() << "KIconLoader::loadIconSet " << name << " " << (int)g << " " << s << endl;
1176  qDebug("%s", kdBacktrace().latin1());
1177  abort();
1178  }
1179 
1180  if(canReturnNull && immediateExistenceCheck)
1181  { // we need to find out if the icon actually exists
1182  TQPixmap pm = loadIcon( name, g, s, KIcon::DefaultState, NULL, true );
1183  if( pm.isNull())
1184  return TQIconSet();
1185 
1186  TQIconSet ret( pm );
1187  ret.installIconFactory( new KIconFactory( name, g, s, this ));
1188  return ret;
1189  }
1190 
1191  TQIconSet ret;
1192  ret.installIconFactory( new KIconFactory( name, g, s, this, canReturnNull ));
1193  return ret;
1194 }
1195 
1196 TQIconSet KIconLoader::loadIconSetNonDelayed( const TQString& name,
1197  KIcon::Group g,
1198  int s, bool canReturnNull )
1199 {
1200  TQIconSet iconset;
1201  TQPixmap tmp = loadIcon(name, g, s, KIcon::ActiveState, NULL, canReturnNull);
1202  iconset.setPixmap( tmp, TQIconSet::Small, TQIconSet::Active );
1203  // we don't use QIconSet's resizing anyway
1204  iconset.setPixmap( tmp, TQIconSet::Large, TQIconSet::Active );
1205  tmp = loadIcon(name, g, s, KIcon::DisabledState, NULL, canReturnNull);
1206  iconset.setPixmap( tmp, TQIconSet::Small, TQIconSet::Disabled );
1207  iconset.setPixmap( tmp, TQIconSet::Large, TQIconSet::Disabled );
1208  tmp = loadIcon(name, g, s, KIcon::DefaultState, NULL, canReturnNull);
1209  iconset.setPixmap( tmp, TQIconSet::Small, TQIconSet::Normal );
1210  iconset.setPixmap( tmp, TQIconSet::Large, TQIconSet::Normal );
1211  return iconset;
1212 }
1213 
1214 KIconFactory::KIconFactory( const TQString& iconName_P, KIcon::Group group_P,
1215  int size_P, KIconLoader* loader_P )
1216  : iconName( iconName_P ), group( group_P ), size( size_P ), loader( loader_P )
1217 {
1218  canReturnNull = false;
1219  setAutoDelete( true );
1220 }
1221 
1222 KIconFactory::KIconFactory( const TQString& iconName_P, KIcon::Group group_P,
1223  int size_P, KIconLoader* loader_P, bool canReturnNull_P )
1224  : iconName( iconName_P ), group( group_P ), size( size_P ),
1225  loader( loader_P ), canReturnNull( canReturnNull_P)
1226 {
1227  setAutoDelete( true );
1228 }
1229 
1230 TQPixmap* KIconFactory::createPixmap( const TQIconSet&, TQIconSet::Size, TQIconSet::Mode mode_P, TQIconSet::State )
1231  {
1232 #ifdef KICONLOADER_CHECKS
1233  bool found = false;
1234  for( TQValueList< KIconLoaderDebug >::Iterator it = kiconloaders->begin();
1235  it != kiconloaders->end();
1236  ++it )
1237  {
1238  if( (*it).loader == loader )
1239  {
1240  found = true;
1241  if( !(*it).valid )
1242  {
1243 #ifdef NDEBUG
1244  loader = KGlobal::iconLoader();
1245  iconName = "no_way_man_you_will_get_broken_icon";
1246 #else
1247  kdWarning() << "Using already destroyed KIconLoader for loading an icon!" << endl;
1248  kdWarning() << "Appname:" << (*it).appname << ", icon:" << iconName << endl;
1249  kdWarning() << "Deleted at:" << endl;
1250  kdWarning() << (*it).delete_bt << endl;
1251  kdWarning() << "Current:" << endl;
1252  kdWarning() << kdBacktrace() << endl;
1253  abort();
1254  return NULL;
1255 #endif
1256  }
1257  break;
1258  }
1259  }
1260  if( !found )
1261  {
1262 #ifdef NDEBUG
1263  loader = KGlobal::iconLoader();
1264  iconName = "no_way_man_you_will_get_broken_icon";
1265 #else
1266  kdWarning() << "Using unknown KIconLoader for loading an icon!" << endl;
1267  kdWarning() << "Icon:" << iconName << endl;
1268  kdWarning() << kdBacktrace() << endl;
1269  abort();
1270  return NULL;
1271 #endif
1272  }
1273 #endif
1274  // TQIconSet::Mode to KIcon::State conversion
1275  static const KIcon::States tbl[] = { KIcon::DefaultState, KIcon::DisabledState, KIcon::ActiveState };
1276  int state = KIcon::DefaultState;
1277  if( mode_P <= TQIconSet::Active )
1278  state = tbl[ mode_P ];
1279  if( group >= 0 && state == KIcon::ActiveState )
1280  { // active and normal icon are usually the same
1281  if( loader->iconEffect()->fingerprint(group, KIcon::ActiveState )
1282  == loader->iconEffect()->fingerprint(group, KIcon::DefaultState ))
1283  return 0; // so let TQIconSet simply duplicate it
1284  }
1285  // ignore passed size
1286  // ignore passed state (i.e. on/off)
1287  TQPixmap pm = loader->loadIcon( iconName, group, size, state, 0, canReturnNull );
1288  return new TQPixmap( pm );
1289  }
1290 
1291 // Easy access functions
1292 
1293 TQPixmap DesktopIcon(const TQString& name, int force_size, int state,
1294  KInstance *instance)
1295 {
1296  KIconLoader *loader = instance->iconLoader();
1297  return loader->loadIcon(name, KIcon::Desktop, force_size, state);
1298 }
1299 
1300 TQPixmap DesktopIcon(const TQString& name, KInstance *instance)
1301 {
1302  return DesktopIcon(name, 0, KIcon::DefaultState, instance);
1303 }
1304 
1305 TQIconSet DesktopIconSet(const TQString& name, int force_size, KInstance *instance)
1306 {
1307  KIconLoader *loader = instance->iconLoader();
1308  return loader->loadIconSet( name, KIcon::Desktop, force_size );
1309 }
1310 
1311 TQPixmap BarIcon(const TQString& name, int force_size, int state,
1312  KInstance *instance)
1313 {
1314  KIconLoader *loader = instance->iconLoader();
1315  return loader->loadIcon(name, KIcon::Toolbar, force_size, state);
1316 }
1317 
1318 TQPixmap BarIcon(const TQString& name, KInstance *instance)
1319 {
1320  return BarIcon(name, 0, KIcon::DefaultState, instance);
1321 }
1322 
1323 TQIconSet BarIconSet(const TQString& name, int force_size, KInstance *instance)
1324 {
1325  KIconLoader *loader = instance->iconLoader();
1326  return loader->loadIconSet( name, KIcon::Toolbar, force_size );
1327 }
1328 
1329 TQPixmap SmallIcon(const TQString& name, int force_size, int state,
1330  KInstance *instance)
1331 {
1332  KIconLoader *loader = instance->iconLoader();
1333  return loader->loadIcon(name, KIcon::Small, force_size, state);
1334 }
1335 
1336 TQPixmap SmallIcon(const TQString& name, KInstance *instance)
1337 {
1338  return SmallIcon(name, 0, KIcon::DefaultState, instance);
1339 }
1340 
1341 TQIconSet SmallIconSet(const TQString& name, int force_size, KInstance *instance)
1342 {
1343  KIconLoader *loader = instance->iconLoader();
1344  return loader->loadIconSet( name, KIcon::Small, force_size );
1345 }
1346 
1347 TQPixmap MainBarIcon(const TQString& name, int force_size, int state,
1348  KInstance *instance)
1349 {
1350  KIconLoader *loader = instance->iconLoader();
1351  return loader->loadIcon(name, KIcon::MainToolbar, force_size, state);
1352 }
1353 
1354 TQPixmap MainBarIcon(const TQString& name, KInstance *instance)
1355 {
1356  return MainBarIcon(name, 0, KIcon::DefaultState, instance);
1357 }
1358 
1359 TQIconSet MainBarIconSet(const TQString& name, int force_size, KInstance *instance)
1360 {
1361  KIconLoader *loader = instance->iconLoader();
1362  return loader->loadIconSet( name, KIcon::MainToolbar, force_size );
1363 }
1364 
1365 TQPixmap UserIcon(const TQString& name, int state, KInstance *instance)
1366 {
1367  KIconLoader *loader = instance->iconLoader();
1368  return loader->loadIcon(name, KIcon::User, 0, state);
1369 }
1370 
1371 TQPixmap UserIcon(const TQString& name, KInstance *instance)
1372 {
1373  return UserIcon(name, KIcon::DefaultState, instance);
1374 }
1375 
1376 TQIconSet UserIconSet(const TQString& name, KInstance *instance)
1377 {
1378  KIconLoader *loader = instance->iconLoader();
1379  return loader->loadIconSet( name, KIcon::User );
1380 }
1381 
1382 int IconSize(KIcon::Group group, KInstance *instance)
1383 {
1384  KIconLoader *loader = instance->iconLoader();
1385  return loader->currentSize(group);
1386 }
1387 
1388 TQPixmap KIconLoader::unknown()
1389 {
1390  TQPixmap pix;
1391  if ( TQPixmapCache::find("unknown", pix) )
1392  return pix;
1393 
1394  TQString path = KGlobal::iconLoader()->iconPath("unknown", KIcon::Small, true);
1395  if (path.isEmpty())
1396  {
1397  kdDebug(264) << "Warning: Cannot find \"unknown\" icon." << endl;
1398  pix.resize(32,32);
1399  } else
1400  {
1401  pix.load(path);
1402  TQPixmapCache::insert("unknown", pix);
1403  }
1404 
1405  return pix;
1406 }
1407 
1408 void KIconLoaderPrivate::reconfigure()
1409 {
1410  q->reconfigure(appname, mpDirs);
1411 }
1412 
1413 #include "kiconloader_p.moc"

kdecore

Skip menu "kdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdecore

Skip menu "kdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kdecore by doxygen 1.8.3.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |