21 #include <kiconloader.h>
23 #include <kstandarddirs.h>
26 #include <ksortablevaluelist.h>
28 #include "kservicefactory.h"
29 #include "kservicegroupfactory.h"
30 #include "kservicegroup.h"
34 class KServiceGroup::Private
37 Private() { m_bNoDisplay =
false; m_bShowEmptyMenu =
false;m_bShowInlineHeader=
false;m_bInlineAlias=
false; m_bAllowInline =
false; m_inlineValue = 4; m_bShortMenu =
false; m_bGeneralDescription =
false;}
40 bool m_bGeneralDescription;
41 bool m_bShowEmptyMenu;
42 bool m_bShowInlineHeader;
48 TQStringList sortOrder;
52 : KSycocaEntry(name), m_childCount(-1)
54 d =
new KServiceGroup::Private;
60 : KSycocaEntry(_relpath), m_childCount(-1)
62 d =
new KServiceGroup::Private;
66 TQString cfg = configFile;
68 cfg = _relpath+
".directory";
70 d->directoryEntryPath = cfg;
72 KDesktopFile config( cfg,
true,
"apps" );
74 m_strCaption = config.readName();
75 m_strIcon = config.readIcon();
76 m_strComment = config.readComment();
77 m_bDeleted = config.readBoolEntry(
"Hidden",
false );
78 d->m_bNoDisplay = config.readBoolEntry(
"NoDisplay",
false );
79 if (d->directoryEntryPath.startsWith(TQDir::homeDirPath()))
80 d->m_bShortMenu =
false;
82 d->m_bShortMenu = config.readBoolEntry(
"X-SuSE-AutoShortMenu",
false );
83 d->m_bGeneralDescription = config.readBoolEntry(
"X-SuSE-GeneralDescription",
false );
85 if (config.hasKey(
"OnlyShowIn"))
87 if ((!config.readListEntry(
"OnlyShowIn",
';').contains(
"TDE")) && (!config.readListEntry(
"OnlyShowIn",
';').contains(
"KDE")))
88 d->m_bNoDisplay =
true;
90 if (config.hasKey(
"NotShowIn"))
92 if ((config.readListEntry(
"NotShowIn",
';').contains(
"TDE")) || (config.readListEntry(
"NotShowIn",
';').contains(
"KDE")))
93 d->m_bNoDisplay =
true;
96 m_strBaseGroupName = config.readEntry(
"X-KDE-BaseGroup" );
97 d->suppressGenericNames = config.readListEntry(
"X-KDE-SuppressGenericNames" );
98 d->sortOrder = config.readListEntry(
"SortOrder");
101 if (m_strCaption.isEmpty())
103 m_strCaption = _relpath;
104 if (m_strCaption.right(1) ==
"/")
105 m_strCaption = m_strCaption.left(m_strCaption.length()-1);
106 int i = m_strCaption.findRev(
'/');
108 m_strCaption = m_strCaption.mid(i+1);
110 if (m_strIcon.isEmpty())
111 m_strIcon =
"folder";
115 KSycocaEntry( _str, offset )
117 d =
new KServiceGroup::Private;
122 KServiceGroup::~KServiceGroup()
129 if (m_childCount == -1)
131 KConfig global(
"kdeglobals");
132 global.setGroup(
"KDE");
133 bool showUnimportant = global.readBoolEntry(
"showUnimportant",
true);
137 for( List::ConstIterator it = m_serviceList.begin();
138 it != m_serviceList.end(); it++)
140 KSycocaEntry *p = (*it);
141 if (p->isType(KST_KService))
148 else if (p->isType(KST_KServiceGroup))
161 return d->m_bShowInlineHeader;
166 return d->m_bShowEmptyMenu;
171 return d->m_bInlineAlias;
174 void KServiceGroup::setInlineAlias(
bool _b)
176 d->m_bInlineAlias = _b;
179 void KServiceGroup::setShowEmptyMenu(
bool _b)
181 d->m_bShowEmptyMenu=_b;
184 void KServiceGroup::setShowInlineHeader(
bool _b)
186 d->m_bShowInlineHeader=_b;
191 return d->m_inlineValue;
194 void KServiceGroup::setInlineValue(
int _val)
196 d->m_inlineValue = _val;
201 return d->m_bAllowInline;
204 void KServiceGroup::setAllowInline(
bool _b)
206 d->m_bAllowInline = _b;
211 return d->m_bNoDisplay || m_strCaption.startsWith(
".");
216 return d->suppressGenericNames;
219 bool KServiceGroup::SuSEgeneralDescription()
const
221 return d->m_bGeneralDescription;
226 return d->m_bShortMenu;
229 void KServiceGroup::load( TQDataStream& s )
231 TQStringList groupList;
233 TQ_INT8 _showEmptyMenu;
234 TQ_INT8 inlineHeader;
235 TQ_INT8 _inlineAlias;
236 TQ_INT8 _allowInline;
237 s >> m_strCaption >> m_strIcon >>
238 m_strComment >> groupList >> m_strBaseGroupName >> m_childCount >>
239 noDisplay >> d->suppressGenericNames >> d->directoryEntryPath >>
240 d->sortOrder >> _showEmptyMenu >> inlineHeader >> _inlineAlias >>
241 _allowInline >> d->m_bShortMenu >> d->m_bGeneralDescription;
243 d->m_bNoDisplay = (noDisplay != 0);
244 d->m_bShowEmptyMenu = ( _showEmptyMenu != 0 );
245 d->m_bShowInlineHeader = ( inlineHeader != 0 );
246 d->m_bInlineAlias = ( _inlineAlias != 0 );
247 d->m_bAllowInline = ( _allowInline != 0 );
251 for(TQStringList::ConstIterator it = groupList.begin();
252 it != groupList.end(); it++)
255 if (path[path.length()-1] ==
'/')
258 serviceGroup = KServiceGroupFactory::self()->findGroupByDesktopPath(path,
false);
260 m_serviceList.append( SPtr(serviceGroup) );
265 service = KServiceFactory::self()->findServiceByDesktopPath(path);
267 m_serviceList.append( SPtr(service) );
273 void KServiceGroup::addEntry( KSycocaEntry *entry)
275 m_serviceList.append(entry);
278 void KServiceGroup::save( TQDataStream& s )
280 KSycocaEntry::save( s );
282 TQStringList groupList;
283 for( List::ConstIterator it = m_serviceList.begin();
284 it != m_serviceList.end(); it++)
286 KSycocaEntry *p = (*it);
287 if (p->isType(KST_KService))
292 else if (p->isType(KST_KServiceGroup))
295 groupList.append( serviceGroup->
relPath());
305 TQ_INT8 noDisplay = d->m_bNoDisplay ? 1 : 0;
306 TQ_INT8 _showEmptyMenu = d->m_bShowEmptyMenu ? 1 : 0;
307 TQ_INT8 inlineHeader = d->m_bShowInlineHeader ? 1 : 0;
308 TQ_INT8 _inlineAlias = d->m_bInlineAlias ? 1 : 0;
309 TQ_INT8 _allowInline = d->m_bAllowInline ? 1 : 0;
310 s << m_strCaption << m_strIcon <<
311 m_strComment << groupList << m_strBaseGroupName << m_childCount <<
312 noDisplay << d->suppressGenericNames << d->directoryEntryPath <<
313 d->sortOrder <<_showEmptyMenu <<inlineHeader<<_inlineAlias<<_allowInline <<
314 d->m_bShortMenu << d->m_bGeneralDescription;
326 return entries(sort, excludeNoDisplay,
false);
329 static void addItem(KServiceGroup::List &sorted,
const KSycocaEntry::Ptr &p,
bool &addSeparator)
331 if (addSeparator && !sorted.isEmpty())
332 sorted.append(
new KServiceSeparator());
334 addSeparator =
false;
340 return SuSEentries(sort, excludeNoDisplay, allowSeparators, sortByGenericName);
344 KServiceGroup::SuSEentries(
bool sort,
bool excludeNoDisplay,
bool allowSeparators,
bool sortByGenericName,
bool excludeSuSEunimportant)
355 KServiceGroupFactory::self()->findGroupByDesktopPath(
relPath(),
true);
362 return group->m_serviceList;
367 KSortableValueList<SPtr,TQCString> slist;
368 KSortableValueList<SPtr,TQCString> glist;
369 for (List::ConstIterator it(group->m_serviceList.begin()); it != group->m_serviceList.end(); ++it)
371 KSycocaEntry *p = (*it);
374 bool noDisplay = p->isType(KST_KServiceGroup) ?
377 if (excludeNoDisplay && noDisplay)
379 bool SuSEunimportant = p->isType(KST_KService) &&
380 static_cast<KService *
>(p)->SuSEunimportant();
381 if (excludeSuSEunimportant && SuSEunimportant)
385 KSortableValueList<SPtr,TQCString> & list = p->isType(KST_KServiceGroup) ? glist : slist;
387 if (p->isType(KST_KServiceGroup))
388 name = static_cast<KServiceGroup *>(p)->caption();
389 else if (sortByGenericName)
390 name =
static_cast<KService *
>(p)->genericName() +
" " + p->
name();
392 name = p->name() +
" " +
static_cast<KService *
>(p)->genericName();
394 TQCString key( name.length() * 4 + 1 );
398 size_t ln = strxfrm( key.data(), name.local8Bit().data(), key.size());
399 if( ln !=
size_t( -1 ))
401 if( ln >= key.size())
403 key.resize( ln + 1 );
404 if( strxfrm( key.data(), name.local8Bit().data(), key.size()) ==
size_t( -1 ))
405 key = name.local8Bit();
411 key = name.local8Bit();
413 list.insert(key,SPtr(*it));
416 return group->SuSEsortEntries( slist, glist, excludeNoDisplay, allowSeparators );
420 KServiceGroup::SuSEsortEntries( KSortableValueList<SPtr,TQCString> slist, KSortableValueList<SPtr,TQCString> glist,
bool excludeNoDisplay,
bool allowSeparators )
428 if (d->sortOrder.isEmpty())
430 d->sortOrder <<
":M";
431 d->sortOrder <<
":F";
432 d->sortOrder <<
":OIH IL[4]";
436 if(rp ==
"/") rp = TQString::null;
440 for (TQStringList::ConstIterator it(d->sortOrder.begin()); it != d->sortOrder.end(); ++it)
442 const TQString &item = *it;
443 if (item.isEmpty())
continue;
446 TQString groupPath = rp + item.mid(1) +
"/";
448 for(KSortableValueList<SPtr,TQCString>::Iterator it2 = glist.begin(); it2 != glist.end(); ++it2)
451 if (group->
relPath() == groupPath)
458 else if (item[0] !=
':')
463 for(KSortableValueList<SPtr,TQCString>::Iterator it2 = slist.begin(); it2 != slist.end(); ++it2)
465 if (!(*it2).value()->isType(KST_KService))
468 if (service->
menuId() == item)
479 bool needSeparator =
false;
482 for (TQStringList::ConstIterator it(d->sortOrder.begin()); it != d->sortOrder.end(); ++it)
484 const TQString &item = *it;
485 if (item.isEmpty())
continue;
492 needSeparator =
true;
494 else if ( item.contains(
":O" ) )
497 TQString tmp( item );
498 tmp = tmp.remove(
":O");
499 TQStringList optionAttribute = TQStringList::split(
" ",tmp);
500 if( optionAttribute.count()==0)
501 optionAttribute.append(tmp);
503 bool showInline =
false;
505 bool showInlineAlias =
false;
508 for ( TQStringList::Iterator it3 = optionAttribute.begin(); it3 != optionAttribute.end(); ++it3 )
510 parseAttribute( *it3, showEmptyMenu, showInline, showInlineHeader, showInlineAlias, inlineValue );
512 for(KSortableValueList<SPtr,TQCString>::Iterator it2 = glist.begin(); it2 != glist.end(); ++it2)
515 group->setShowEmptyMenu( showEmptyMenu );
516 group->setAllowInline( showInline );
517 group->setShowInlineHeader( showInlineHeader );
518 group->setInlineAlias( showInlineAlias );
519 group->setInlineValue( inlineValue );
523 else if (item ==
":M")
526 for(KSortableValueList<SPtr,TQCString>::Iterator it2 = glist.begin(); it2 != glist.end(); ++it2)
528 addItem(sorted, (*it2).value(), needSeparator);
531 else if (item ==
":F")
534 for(KSortableValueList<SPtr,TQCString>::Iterator it2 = slist.begin(); it2 != slist.end(); ++it2)
536 addItem(sorted, (*it2).value(), needSeparator);
539 else if (item ==
":A")
542 KSortableValueList<SPtr,TQCString>::Iterator it_s = slist.begin();
543 KSortableValueList<SPtr,TQCString>::Iterator it_g = glist.begin();
547 if (it_s == slist.end())
549 if (it_g == glist.end())
553 addItem(sorted, (*it_g).value(), needSeparator);
556 else if (it_g == glist.end())
559 addItem(sorted, (*it_s).value(), needSeparator);
562 else if ((*it_g).index() < (*it_s).index())
565 addItem(sorted, (*it_g).value(), needSeparator);
571 addItem(sorted, (*it_s).value(), needSeparator);
577 else if (item[0] ==
'/')
579 TQString groupPath = rp + item.mid(1) +
"/";
581 for (List::ConstIterator it2(group->m_serviceList.begin()); it2 != group->m_serviceList.end(); ++it2)
583 if (!(*it2)->isType(KST_KServiceGroup))
586 if (group->
relPath() == groupPath)
588 if (!excludeNoDisplay || !group->
noDisplay())
590 const TQString &nextItem = *( ++it );
591 if ( nextItem.startsWith(
":O" ) )
593 TQString tmp( nextItem );
594 tmp = tmp.remove(
":O");
595 TQStringList optionAttribute = TQStringList::split(
" ",tmp);
596 if( optionAttribute.count()==0)
597 optionAttribute.append(tmp);
598 bool bShowEmptyMenu =
false;
599 bool bShowInline =
false;
600 bool bShowInlineHeader =
false;
601 bool bShowInlineAlias =
false;
602 int inlineValue = -1;
603 for ( TQStringList::Iterator it3 = optionAttribute.begin(); it3 != optionAttribute.end(); ++it3 )
605 parseAttribute( *it3 , bShowEmptyMenu, bShowInline, bShowInlineHeader, bShowInlineAlias , inlineValue );
606 group->setShowEmptyMenu( bShowEmptyMenu );
607 group->setAllowInline( bShowInline );
608 group->setShowInlineHeader( bShowInlineHeader );
609 group->setInlineAlias( bShowInlineAlias );
610 group->setInlineValue( inlineValue );
616 addItem(sorted, (group), needSeparator);
624 for (List::ConstIterator it2(group->m_serviceList.begin()); it2 != group->m_serviceList.end(); ++it2)
626 if (!(*it2)->isType(KST_KService))
629 if (service->
menuId() == item)
631 if (!excludeNoDisplay || !service->
noDisplay())
632 addItem(sorted, (*it2), needSeparator);
642 void KServiceGroup::parseAttribute(
const TQString &item ,
bool &showEmptyMenu,
bool &showInline,
bool &showInlineHeader,
bool & showInlineAlias ,
int &inlineValue )
646 else if ( item ==
"NME")
648 else if( item ==
"I")
650 else if ( item ==
"NI")
652 else if( item ==
"IH")
653 showInlineHeader=
true;
654 else if ( item ==
"NIH")
655 showInlineHeader =
false;
656 else if( item ==
"IA")
657 showInlineAlias =
true;
658 else if ( item ==
"NIA")
659 showInlineAlias =
false;
660 else if( ( item ).contains(
"IL" ))
662 TQString tmp( item );
663 tmp = tmp.remove(
"IL[" );
664 tmp = tmp.remove(
"]" );
666 int _inlineValue = tmp.toInt(&ok);
669 inlineValue = _inlineValue;
672 kdDebug()<<
" This attribute is not supported :"<<item<<endl;
675 void KServiceGroup::setLayoutInfo(
const TQStringList &layout)
677 d->sortOrder = layout;
680 TQStringList KServiceGroup::layoutInfo()
const
688 return KServiceGroupFactory::self()->findBaseGroup(_baseGroupName,
true);
694 return KServiceGroupFactory::self()->findGroupByDesktopPath(
"/",
true);
700 if (relPath.isEmpty())
return root();
701 return KServiceGroupFactory::self()->findGroupByDesktopPath(relPath,
true);
707 return KServiceGroupFactory::self()->findGroupByDesktopPath(
"#parent#"+parent,
true);
713 return d->directoryEntryPath;
717 void KServiceGroup::virtual_hook(
int id,
void* data )
718 { KSycocaEntry::virtual_hook(
id, data ); }
721 KServiceSeparator::KServiceSeparator( )
722 : KSycocaEntry(
"separator")