kservicegroup.cpp
00001 /* This file is part of the KDE libraries 00002 * Copyright (C) 2000 Waldo Bastian <bastian@kde.org> 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Library General Public 00006 * License version 2 as published by the Free Software Foundation; 00007 * 00008 * This library is distributed in the hope that it will be useful, 00009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 * Library General Public License for more details. 00012 * 00013 * You should have received a copy of the GNU Library General Public License 00014 * along with this library; see the file COPYING.LIB. If not, write to 00015 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 * Boston, MA 02110-1301, USA. 00017 **/ 00018 00019 #include <kiconloader.h> 00020 #include <kglobal.h> 00021 #include <kstandarddirs.h> 00022 #include <klocale.h> 00023 #include <kdebug.h> 00024 #include <ksortablevaluelist.h> 00025 #include "kservicefactory.h" 00026 #include "kservicegroupfactory.h" 00027 #include "kservicegroup.h" 00028 #include "kservice.h" 00029 #include "ksycoca.h" 00030 00031 class KServiceGroup::Private 00032 { 00033 public: 00034 Private() { m_bNoDisplay = false; m_bShowEmptyMenu = false;m_bShowInlineHeader=false;m_bInlineAlias=false; m_bAllowInline = false;m_inlineValue = 4;} 00035 bool m_bNoDisplay; 00036 bool m_bShowEmptyMenu; 00037 bool m_bShowInlineHeader; 00038 bool m_bInlineAlias; 00039 bool m_bAllowInline; 00040 int m_inlineValue; 00041 QStringList suppressGenericNames; 00042 QString directoryEntryPath; 00043 QStringList sortOrder; 00044 }; 00045 00046 KServiceGroup::KServiceGroup( const QString & name ) 00047 : KSycocaEntry(name), m_childCount(-1) 00048 { 00049 d = new KServiceGroup::Private; 00050 m_bDeleted = false; 00051 m_bDeep = false; 00052 } 00053 00054 KServiceGroup::KServiceGroup( const QString &configFile, const QString & _relpath ) 00055 : KSycocaEntry(_relpath), m_childCount(-1) 00056 { 00057 d = new KServiceGroup::Private; 00058 m_bDeleted = false; 00059 m_bDeep = false; 00060 00061 QString cfg = configFile; 00062 if (cfg.isEmpty()) 00063 cfg = _relpath+".directory"; 00064 00065 d->directoryEntryPath = cfg; 00066 00067 KConfig config( cfg, true, false, "apps" ); 00068 00069 config.setDesktopGroup(); 00070 00071 m_strCaption = config.readEntry( "Name" ); 00072 m_strIcon = config.readEntry( "Icon" ); 00073 m_strComment = config.readEntry( "Comment" ); 00074 m_bDeleted = config.readBoolEntry( "Hidden", false ); 00075 d->m_bNoDisplay = config.readBoolEntry( "NoDisplay", false ); 00076 QStringList tmpList; 00077 if (config.hasKey("OnlyShowIn")) 00078 { 00079 QStringList onlyShowInList = config.readListEntry("OnlyShowIn", ';'); 00080 if (! (onlyShowInList.contains("KDE") || onlyShowInList.contains("KDE3"))) 00081 d->m_bNoDisplay = true; 00082 } 00083 if (config.hasKey("NotShowIn")) 00084 { 00085 QStringList notShowInList = config.readListEntry("NotShowIn", ';'); 00086 if (notShowInList.contains("KDE") || notShowInList.contains("KDE3")) 00087 d->m_bNoDisplay = true; 00088 } 00089 00090 m_strBaseGroupName = config.readEntry( "X-KDE-BaseGroup" ); 00091 d->suppressGenericNames = config.readListEntry( "X-KDE-SuppressGenericNames" ); 00092 d->sortOrder = config.readListEntry("SortOrder"); 00093 00094 // Fill in defaults. 00095 if (m_strCaption.isEmpty()) 00096 { 00097 m_strCaption = _relpath; 00098 if (m_strCaption.right(1) == "/") 00099 m_strCaption = m_strCaption.left(m_strCaption.length()-1); 00100 int i = m_strCaption.findRev('/'); 00101 if (i > 0) 00102 m_strCaption = m_strCaption.mid(i+1); 00103 } 00104 if (m_strIcon.isEmpty()) 00105 m_strIcon = "folder"; 00106 } 00107 00108 KServiceGroup::KServiceGroup( QDataStream& _str, int offset, bool deep ) : 00109 KSycocaEntry( _str, offset ) 00110 { 00111 d = new KServiceGroup::Private; 00112 m_bDeep = deep; 00113 load( _str ); 00114 } 00115 00116 KServiceGroup::~KServiceGroup() 00117 { 00118 delete d; 00119 } 00120 00121 int KServiceGroup::childCount() 00122 { 00123 if (m_childCount == -1) 00124 { 00125 m_childCount = 0; 00126 00127 for( List::ConstIterator it = m_serviceList.begin(); 00128 it != m_serviceList.end(); it++) 00129 { 00130 KSycocaEntry *p = (*it); 00131 if (p->isType(KST_KService)) 00132 { 00133 KService *service = static_cast<KService *>(p); 00134 if (!service->noDisplay()) 00135 m_childCount++; 00136 } 00137 else if (p->isType(KST_KServiceGroup)) 00138 { 00139 KServiceGroup *serviceGroup = static_cast<KServiceGroup *>(p); 00140 m_childCount += serviceGroup->childCount(); 00141 } 00142 } 00143 } 00144 return m_childCount; 00145 } 00146 00147 00148 bool KServiceGroup::showInlineHeader() const 00149 { 00150 return d->m_bShowInlineHeader; 00151 } 00152 00153 bool KServiceGroup::showEmptyMenu() const 00154 { 00155 return d->m_bShowEmptyMenu; 00156 } 00157 00158 bool KServiceGroup::inlineAlias() const 00159 { 00160 return d->m_bInlineAlias; 00161 } 00162 00163 void KServiceGroup::setInlineAlias(bool _b) 00164 { 00165 d->m_bInlineAlias = _b; 00166 } 00167 00168 void KServiceGroup::setShowEmptyMenu(bool _b) 00169 { 00170 d->m_bShowEmptyMenu=_b; 00171 } 00172 00173 void KServiceGroup::setShowInlineHeader(bool _b) 00174 { 00175 d->m_bShowInlineHeader=_b; 00176 } 00177 00178 int KServiceGroup::inlineValue() const 00179 { 00180 return d->m_inlineValue; 00181 } 00182 00183 void KServiceGroup::setInlineValue(int _val) 00184 { 00185 d->m_inlineValue = _val; 00186 } 00187 00188 bool KServiceGroup::allowInline() const 00189 { 00190 return d->m_bAllowInline; 00191 } 00192 00193 void KServiceGroup::setAllowInline(bool _b) 00194 { 00195 d->m_bAllowInline = _b; 00196 } 00197 00198 bool KServiceGroup::noDisplay() const 00199 { 00200 return d->m_bNoDisplay || m_strCaption.startsWith("."); 00201 } 00202 00203 QStringList KServiceGroup::suppressGenericNames() const 00204 { 00205 return d->suppressGenericNames; 00206 } 00207 00208 void KServiceGroup::load( QDataStream& s ) 00209 { 00210 QStringList groupList; 00211 Q_INT8 noDisplay; 00212 Q_INT8 _showEmptyMenu; 00213 Q_INT8 inlineHeader; 00214 Q_INT8 _inlineAlias; 00215 Q_INT8 _allowInline; 00216 s >> m_strCaption >> m_strIcon >> 00217 m_strComment >> groupList >> m_strBaseGroupName >> m_childCount >> 00218 noDisplay >> d->suppressGenericNames >> d->directoryEntryPath >> 00219 d->sortOrder >> _showEmptyMenu >> inlineHeader >> _inlineAlias >> _allowInline; 00220 00221 d->m_bNoDisplay = (noDisplay != 0); 00222 d->m_bShowEmptyMenu = ( _showEmptyMenu != 0 ); 00223 d->m_bShowInlineHeader = ( inlineHeader != 0 ); 00224 d->m_bInlineAlias = ( _inlineAlias != 0 ); 00225 d->m_bAllowInline = ( _allowInline != 0 ); 00226 00227 if (m_bDeep) 00228 { 00229 for(QStringList::ConstIterator it = groupList.begin(); 00230 it != groupList.end(); it++) 00231 { 00232 QString path = *it; 00233 if (path[path.length()-1] == '/') 00234 { 00235 KServiceGroup *serviceGroup; 00236 serviceGroup = KServiceGroupFactory::self()->findGroupByDesktopPath(path, false); 00237 if (serviceGroup) 00238 m_serviceList.append( SPtr(serviceGroup) ); 00239 } 00240 else 00241 { 00242 KService *service; 00243 service = KServiceFactory::self()->findServiceByDesktopPath(path); 00244 if (service) 00245 m_serviceList.append( SPtr(service) ); 00246 } 00247 } 00248 } 00249 } 00250 00251 void KServiceGroup::addEntry( KSycocaEntry *entry) 00252 { 00253 m_serviceList.append(entry); 00254 } 00255 00256 void KServiceGroup::save( QDataStream& s ) 00257 { 00258 KSycocaEntry::save( s ); 00259 00260 QStringList groupList; 00261 for( List::ConstIterator it = m_serviceList.begin(); 00262 it != m_serviceList.end(); it++) 00263 { 00264 KSycocaEntry *p = (*it); 00265 if (p->isType(KST_KService)) 00266 { 00267 KService *service = static_cast<KService *>(p); 00268 groupList.append( service->desktopEntryPath()); 00269 } 00270 else if (p->isType(KST_KServiceGroup)) 00271 { 00272 KServiceGroup *serviceGroup = static_cast<KServiceGroup *>(p); 00273 groupList.append( serviceGroup->relPath()); 00274 } 00275 else 00276 { 00277 //fprintf(stderr, "KServiceGroup: Unexpected object in list!\n"); 00278 } 00279 } 00280 00281 (void) childCount(); 00282 00283 Q_INT8 noDisplay = d->m_bNoDisplay ? 1 : 0; 00284 Q_INT8 _showEmptyMenu = d->m_bShowEmptyMenu ? 1 : 0; 00285 Q_INT8 inlineHeader = d->m_bShowInlineHeader ? 1 : 0; 00286 Q_INT8 _inlineAlias = d->m_bInlineAlias ? 1 : 0; 00287 Q_INT8 _allowInline = d->m_bAllowInline ? 1 : 0; 00288 s << m_strCaption << m_strIcon << 00289 m_strComment << groupList << m_strBaseGroupName << m_childCount << 00290 noDisplay << d->suppressGenericNames << d->directoryEntryPath << 00291 d->sortOrder <<_showEmptyMenu <<inlineHeader<<_inlineAlias<<_allowInline; 00292 } 00293 00294 KServiceGroup::List 00295 KServiceGroup::entries(bool sort) 00296 { 00297 return entries(sort, true); 00298 } 00299 00300 KServiceGroup::List 00301 KServiceGroup::entries(bool sort, bool excludeNoDisplay) 00302 { 00303 return entries(sort, excludeNoDisplay, false); 00304 } 00305 00306 static void addItem(KServiceGroup::List &sorted, const KSycocaEntry::Ptr &p, bool &addSeparator) 00307 { 00308 if (addSeparator && !sorted.isEmpty()) 00309 sorted.append(new KServiceSeparator()); 00310 sorted.append(p); 00311 addSeparator = false; 00312 } 00313 00314 KServiceGroup::List 00315 KServiceGroup::entries(bool sort, bool excludeNoDisplay, bool allowSeparators, bool sortByGenericName) 00316 { 00317 KServiceGroup *group = this; 00318 00319 // If the entries haven't been loaded yet, we have to reload ourselves 00320 // together with the entries. We can't only load the entries afterwards 00321 // since the offsets could have been changed if the database has changed. 00322 00323 if (!m_bDeep) { 00324 00325 group = 00326 KServiceGroupFactory::self()->findGroupByDesktopPath(relPath(), true); 00327 00328 if (0 == group) // No guarantee that we still exist! 00329 return List(); 00330 } 00331 00332 if (!sort) 00333 return group->m_serviceList; 00334 00335 // Sort the list alphabetically, according to locale. 00336 // Groups come first, then services. 00337 00338 KSortableValueList<SPtr,QCString> slist; 00339 KSortableValueList<SPtr,QCString> glist; 00340 for (List::ConstIterator it(group->m_serviceList.begin()); it != group->m_serviceList.end(); ++it) 00341 { 00342 KSycocaEntry *p = (*it); 00343 bool noDisplay = p->isType(KST_KServiceGroup) ? 00344 static_cast<KServiceGroup *>(p)->noDisplay() : 00345 static_cast<KService *>(p)->noDisplay(); 00346 if (excludeNoDisplay && noDisplay) 00347 continue; 00348 // Choose the right list 00349 KSortableValueList<SPtr,QCString> & list = p->isType(KST_KServiceGroup) ? glist : slist; 00350 QString name; 00351 if (p->isType(KST_KServiceGroup)) 00352 name = static_cast<KServiceGroup *>(p)->caption(); 00353 else if (sortByGenericName) 00354 name = static_cast<KService *>(p)->genericName() + " " + p->name(); 00355 else 00356 name = p->name() + " " + static_cast<KService *>(p)->genericName(); 00357 00358 QCString key( name.length() * 4 + 1 ); 00359 // strxfrm() crashes on Solaris 00360 #ifndef USE_SOLARIS 00361 // maybe it'd be better to use wcsxfrm() where available 00362 size_t ln = strxfrm( key.data(), name.local8Bit().data(), key.size()); 00363 if( ln != size_t( -1 )) 00364 { 00365 if( ln >= key.size()) 00366 { // didn't fit? 00367 key.resize( ln + 1 ); 00368 if( strxfrm( key.data(), name.local8Bit().data(), key.size()) == size_t( -1 )) 00369 key = name.local8Bit(); 00370 } 00371 } 00372 else 00373 #endif 00374 { 00375 key = name.local8Bit(); 00376 } 00377 list.insert(key,SPtr(*it)); 00378 } 00379 // Now sort 00380 slist.sort(); 00381 glist.sort(); 00382 00383 if (d->sortOrder.isEmpty()) 00384 { 00385 d->sortOrder << ":M"; 00386 d->sortOrder << ":F"; 00387 d->sortOrder << ":OIH IL[4]"; //just inline header 00388 } 00389 00390 QString rp = relPath(); 00391 if(rp == "/") rp = QString::null; 00392 00393 // Iterate through the sort spec list. 00394 // If an entry gets mentioned explicitly, we remove it from the sorted list 00395 for (QStringList::ConstIterator it(d->sortOrder.begin()); it != d->sortOrder.end(); ++it) 00396 { 00397 const QString &item = *it; 00398 if (item.isEmpty()) continue; 00399 if (item[0] == '/') 00400 { 00401 QString groupPath = rp + item.mid(1) + "/"; 00402 // Remove entry from sorted list of services. 00403 for(KSortableValueList<SPtr,QCString>::Iterator it2 = glist.begin(); it2 != glist.end(); ++it2) 00404 { 00405 KServiceGroup *group = (KServiceGroup *)((KSycocaEntry *)((*it2).value())); 00406 if (group->relPath() == groupPath) 00407 { 00408 glist.remove(it2); 00409 break; 00410 } 00411 } 00412 } 00413 else if (item[0] != ':') 00414 { 00415 // Remove entry from sorted list of services. 00416 // TODO: Remove item from sortOrder-list if not found 00417 // TODO: This prevents duplicates 00418 for(KSortableValueList<SPtr,QCString>::Iterator it2 = slist.begin(); it2 != slist.end(); ++it2) 00419 { 00420 KService *service = (KService *)((KSycocaEntry *)((*it2).value())); 00421 if (service->menuId() == item) 00422 { 00423 slist.remove(it2); 00424 break; 00425 } 00426 } 00427 } 00428 } 00429 00430 List sorted; 00431 00432 bool needSeparator = false; 00433 // Iterate through the sort spec list. 00434 // Add the entries to the list according to the sort spec. 00435 for (QStringList::ConstIterator it(d->sortOrder.begin()); it != d->sortOrder.end(); ++it) 00436 { 00437 const QString &item = *it; 00438 if (item.isEmpty()) continue; 00439 if (item[0] == ':') 00440 { 00441 // Special condition... 00442 if (item == ":S") 00443 { 00444 if (allowSeparators) 00445 needSeparator = true; 00446 } 00447 else if ( item.contains( ":O" ) ) 00448 { 00449 //todo parse attribute: 00450 QString tmp( item ); 00451 tmp = tmp.remove(":O"); 00452 QStringList optionAttribute = QStringList::split(" ",tmp); 00453 if( optionAttribute.count()==0) 00454 optionAttribute.append(tmp); 00455 bool showEmptyMenu = false; 00456 bool showInline = false; 00457 bool showInlineHeader = false; 00458 bool showInlineAlias = false; 00459 int inlineValue = -1; 00460 00461 for ( QStringList::Iterator it3 = optionAttribute.begin(); it3 != optionAttribute.end(); ++it3 ) 00462 { 00463 parseAttribute( *it3, showEmptyMenu, showInline, showInlineHeader, showInlineAlias, inlineValue ); 00464 } 00465 for(KSortableValueList<SPtr,QCString>::Iterator it2 = glist.begin(); it2 != glist.end(); ++it2) 00466 { 00467 KServiceGroup *group = (KServiceGroup *)((KSycocaEntry *)(*it2).value()); 00468 group->setShowEmptyMenu( showEmptyMenu ); 00469 group->setAllowInline( showInline ); 00470 group->setShowInlineHeader( showInlineHeader ); 00471 group->setInlineAlias( showInlineAlias ); 00472 group->setInlineValue( inlineValue ); 00473 } 00474 00475 } 00476 else if (item == ":M") 00477 { 00478 // Add sorted list of sub-menus 00479 for(KSortableValueList<SPtr,QCString>::Iterator it2 = glist.begin(); it2 != glist.end(); ++it2) 00480 { 00481 addItem(sorted, (*it2).value(), needSeparator); 00482 } 00483 } 00484 else if (item == ":F") 00485 { 00486 // Add sorted list of services 00487 for(KSortableValueList<SPtr,QCString>::Iterator it2 = slist.begin(); it2 != slist.end(); ++it2) 00488 { 00489 addItem(sorted, (*it2).value(), needSeparator); 00490 } 00491 } 00492 else if (item == ":A") 00493 { 00494 // Add sorted lists of services and submenus 00495 KSortableValueList<SPtr,QCString>::Iterator it_s = slist.begin(); 00496 KSortableValueList<SPtr,QCString>::Iterator it_g = glist.begin(); 00497 00498 while(true) 00499 { 00500 if (it_s == slist.end()) 00501 { 00502 if (it_g == glist.end()) 00503 break; // Done 00504 00505 // Insert remaining sub-menu 00506 addItem(sorted, (*it_g).value(), needSeparator); 00507 it_g++; 00508 } 00509 else if (it_g == glist.end()) 00510 { 00511 // Insert remaining service 00512 addItem(sorted, (*it_s).value(), needSeparator); 00513 it_s++; 00514 } 00515 else if ((*it_g).index() < (*it_s).index()) 00516 { 00517 // Insert sub-menu first 00518 addItem(sorted, (*it_g).value(), needSeparator); 00519 it_g++; 00520 } 00521 else 00522 { 00523 // Insert service first 00524 addItem(sorted, (*it_s).value(), needSeparator); 00525 it_s++; 00526 } 00527 } 00528 } 00529 } 00530 else if (item[0] == '/') 00531 { 00532 QString groupPath = rp + item.mid(1) + "/"; 00533 00534 for (List::ConstIterator it2(group->m_serviceList.begin()); it2 != group->m_serviceList.end(); ++it2) 00535 { 00536 if (!(*it2)->isType(KST_KServiceGroup)) 00537 continue; 00538 KServiceGroup *group = (KServiceGroup *)((KSycocaEntry *)(*it2)); 00539 if (group->relPath() == groupPath) 00540 { 00541 if (!excludeNoDisplay || !group->noDisplay()) 00542 { 00543 const QString &nextItem = *( ++it ); 00544 if ( nextItem.startsWith( ":O" ) ) 00545 { 00546 QString tmp( nextItem ); 00547 tmp = tmp.remove(":O"); 00548 QStringList optionAttribute = QStringList::split(" ",tmp); 00549 if( optionAttribute.count()==0) 00550 optionAttribute.append(tmp); 00551 bool bShowEmptyMenu = false; 00552 bool bShowInline = false; 00553 bool bShowInlineHeader = false; 00554 bool bShowInlineAlias = false; 00555 int inlineValue = -1; 00556 for ( QStringList::Iterator it3 = optionAttribute.begin(); it3 != optionAttribute.end(); ++it3 ) 00557 { 00558 parseAttribute( *it3 , bShowEmptyMenu, bShowInline, bShowInlineHeader, bShowInlineAlias , inlineValue ); 00559 group->setShowEmptyMenu( bShowEmptyMenu ); 00560 group->setAllowInline( bShowInline ); 00561 group->setShowInlineHeader( bShowInlineHeader ); 00562 group->setInlineAlias( bShowInlineAlias ); 00563 group->setInlineValue( inlineValue ); 00564 } 00565 } 00566 else 00567 it--; 00568 00569 addItem(sorted, (group), needSeparator); 00570 } 00571 break; 00572 } 00573 } 00574 } 00575 else 00576 { 00577 for (List::ConstIterator it2(group->m_serviceList.begin()); it2 != group->m_serviceList.end(); ++it2) 00578 { 00579 if (!(*it2)->isType(KST_KService)) 00580 continue; 00581 KService *service = (KService *)((KSycocaEntry *)(*it2)); 00582 if (service->menuId() == item) 00583 { 00584 if (!excludeNoDisplay || !service->noDisplay()) 00585 addItem(sorted, (*it2), needSeparator); 00586 break; 00587 } 00588 } 00589 } 00590 } 00591 00592 return sorted; 00593 } 00594 00595 void KServiceGroup::parseAttribute( const QString &item , bool &showEmptyMenu, bool &showInline, bool &showInlineHeader, bool & showInlineAlias , int &inlineValue ) 00596 { 00597 if( item == "ME") //menu empty 00598 showEmptyMenu=true; 00599 else if ( item == "NME") //not menu empty 00600 showEmptyMenu=false; 00601 else if( item == "I") //inline menu ! 00602 showInline = true; 00603 else if ( item == "NI") //not inline menu! 00604 showInline = false; 00605 else if( item == "IH") //inline header! 00606 showInlineHeader= true; 00607 else if ( item == "NIH") //not inline header! 00608 showInlineHeader = false; 00609 else if( item == "IA") //inline alias! 00610 showInlineAlias = true; 00611 else if ( item == "NIA") //not inline alias! 00612 showInlineAlias = false; 00613 else if( ( item ).contains( "IL" )) //inline limite! 00614 { 00615 QString tmp( item ); 00616 tmp = tmp.remove( "IL[" ); 00617 tmp = tmp.remove( "]" ); 00618 bool ok; 00619 int _inlineValue = tmp.toInt(&ok); 00620 if ( !ok ) //error 00621 _inlineValue = -1; 00622 inlineValue = _inlineValue; 00623 } 00624 else 00625 kdDebug()<<" This attribute is not supported :"<<item<<endl; 00626 } 00627 00628 void KServiceGroup::setLayoutInfo(const QStringList &layout) 00629 { 00630 d->sortOrder = layout; 00631 } 00632 00633 QStringList KServiceGroup::layoutInfo() const 00634 { 00635 return d->sortOrder; 00636 } 00637 00638 KServiceGroup::Ptr 00639 KServiceGroup::baseGroup( const QString & _baseGroupName ) 00640 { 00641 return KServiceGroupFactory::self()->findBaseGroup(_baseGroupName, true); 00642 } 00643 00644 KServiceGroup::Ptr 00645 KServiceGroup::root() 00646 { 00647 return KServiceGroupFactory::self()->findGroupByDesktopPath("/", true); 00648 } 00649 00650 KServiceGroup::Ptr 00651 KServiceGroup::group(const QString &relPath) 00652 { 00653 if (relPath.isEmpty()) return root(); 00654 return KServiceGroupFactory::self()->findGroupByDesktopPath(relPath, true); 00655 } 00656 00657 KServiceGroup::Ptr 00658 KServiceGroup::childGroup(const QString &parent) 00659 { 00660 return KServiceGroupFactory::self()->findGroupByDesktopPath("#parent#"+parent, true); 00661 } 00662 00663 QString 00664 KServiceGroup::directoryEntryPath() const 00665 { 00666 return d->directoryEntryPath; 00667 } 00668 00669 00670 void KServiceGroup::virtual_hook( int id, void* data ) 00671 { KSycocaEntry::virtual_hook( id, data ); } 00672 00673 00674 KServiceSeparator::KServiceSeparator( ) 00675 : KSycocaEntry("separator") 00676 { 00677 }