Example #1
0
KServiceGroup::List
KServiceGroup::entries(bool sort, bool excludeNoDisplay, bool allowSeparators, bool sortByGenericName)
{
    KServiceGroup *group = this;

    // If the entries haven't been loaded yet, we have to reload ourselves
    // together with the entries. We can't only load the entries afterwards
    // since the offsets could have been changed if the database has changed.

    if (!m_bDeep) {

        group =
            KServiceGroupFactory::self()->findGroupByDesktopPath(relPath(), true);

        if (0 == group) // No guarantee that we still exist!
            return List();
    }

    if (!sort)
        return group->m_serviceList;

    // Sort the list alphabetically, according to locale.
    // Groups come first, then services.

    KSortableValueList<SPtr,QCString> slist;
    KSortableValueList<SPtr,QCString> glist;
    for (List::ConstIterator it(group->m_serviceList.begin()); it != group->m_serviceList.end(); ++it)
    {
        KSycocaEntry *p = (*it);
	bool noDisplay = p->isType(KST_KServiceGroup) ?
                                   static_cast<KServiceGroup *>(p)->noDisplay() :
                                   static_cast<KService *>(p)->noDisplay();
        if (excludeNoDisplay && noDisplay)
           continue;
        // Choose the right list
        KSortableValueList<SPtr,QCString> & list = p->isType(KST_KServiceGroup) ? glist : slist;
        QString name;
        if (p->isType(KST_KServiceGroup))
          name = static_cast<KServiceGroup *>(p)->caption();
        else if (sortByGenericName)
          name = static_cast<KService *>(p)->genericName() + " " + p->name();
        else
          name = p->name() + " " + static_cast<KService *>(p)->genericName();

        QCString key( name.length() * 4 + 1 );
        // strxfrm() crashes on Solaris
#ifndef USE_SOLARIS
        // maybe it'd be better to use wcsxfrm() where available
        size_t ln = strxfrm( key.data(), name.local8Bit().data(), key.size());
        if( ln != size_t( -1 ))
        {
            if( ln >= key.size())
            { // didn't fit?
                key.resize( ln + 1 );
                if( strxfrm( key.data(), name.local8Bit().data(), key.size()) == size_t( -1 ))
                    key = name.local8Bit();
            }
        }
        else
#endif
        {
            key = name.local8Bit();
        }
        list.insert(key,SPtr(*it));
    }
    // Now sort
    slist.sort();
    glist.sort();

    if (d->sortOrder.isEmpty())
    {
       d->sortOrder << ":M";
       d->sortOrder << ":F";
       d->sortOrder << ":OIH IL[4]"; //just inline header
    }

    QString rp = relPath();
    if(rp == "/") rp = QString::null;

    // Iterate through the sort spec list.
    // If an entry gets mentioned explicitly, we remove it from the sorted list
    for (QStringList::ConstIterator it(d->sortOrder.begin()); it != d->sortOrder.end(); ++it)
    {
        const QString &item = *it;
        if (item.isEmpty()) continue;
        if (item[0] == '/')
        {
          QString groupPath = rp + item.mid(1) + "/";
           // Remove entry from sorted list of services.
          for(KSortableValueList<SPtr,QCString>::Iterator it2 = glist.begin(); it2 != glist.end(); ++it2)
          {
             KServiceGroup *group = (KServiceGroup *)((KSycocaEntry *)((*it2).value()));
             if (group->relPath() == groupPath)
             {
                glist.remove(it2);
                break;
             }
          }
        }
        else if (item[0] != ':')
        {
           // Remove entry from sorted list of services.
           // TODO: Remove item from sortOrder-list if not found
           // TODO: This prevents duplicates
          for(KSortableValueList<SPtr,QCString>::Iterator it2 = slist.begin(); it2 != slist.end(); ++it2)
          {
             KService *service = (KService *)((KSycocaEntry *)((*it2).value()));
             if (service->menuId() == item)
             {
                slist.remove(it2);
                break;
             }
          }
        }
    }

    List sorted;

    bool needSeparator = false;
    // Iterate through the sort spec list.
    // Add the entries to the list according to the sort spec.
    for (QStringList::ConstIterator it(d->sortOrder.begin()); it != d->sortOrder.end(); ++it)
    {
        const QString &item = *it;
        if (item.isEmpty()) continue;
        if (item[0] == ':')
        {
          // Special condition...
          if (item == ":S")
          {
             if (allowSeparators)
                needSeparator = true;
          }
          else if ( item.contains( ":O" ) )
          {
              //todo parse attribute:
              QString tmp(  item );
              tmp = tmp.remove(":O");
              QStringList optionAttribute = QStringList::split(" ",tmp);
              if( optionAttribute.count()==0)
                  optionAttribute.append(tmp);
              bool showEmptyMenu = false;
              bool showInline = false;
              bool showInlineHeader = false;
              bool showInlineAlias = false;
              int inlineValue = -1;

              for ( QStringList::Iterator it3 = optionAttribute.begin(); it3 != optionAttribute.end(); ++it3 )
              {
                  parseAttribute( *it3,  showEmptyMenu, showInline, showInlineHeader, showInlineAlias, inlineValue );
              }
              for(KSortableValueList<SPtr,QCString>::Iterator it2 = glist.begin(); it2 != glist.end(); ++it2)
              {
                  KServiceGroup *group = (KServiceGroup *)((KSycocaEntry *)(*it2).value());
                  group->setShowEmptyMenu(  showEmptyMenu  );
                  group->setAllowInline( showInline );
                  group->setShowInlineHeader( showInlineHeader );
                  group->setInlineAlias( showInlineAlias );
                  group->setInlineValue( inlineValue );
              }

          }
          else if (item == ":M")
          {
            // Add sorted list of sub-menus
            for(KSortableValueList<SPtr,QCString>::Iterator it2 = glist.begin(); it2 != glist.end(); ++it2)
            {
              addItem(sorted, (*it2).value(), needSeparator);
            }
          }
          else if (item == ":F")
          {
            // Add sorted list of services
            for(KSortableValueList<SPtr,QCString>::Iterator it2 = slist.begin(); it2 != slist.end(); ++it2)
            {
              addItem(sorted, (*it2).value(), needSeparator);
            }
          }
          else if (item == ":A")
          {
            // Add sorted lists of services and submenus
            KSortableValueList<SPtr,QCString>::Iterator it_s = slist.begin();
            KSortableValueList<SPtr,QCString>::Iterator it_g = glist.begin();

            while(true)
            {
               if (it_s == slist.end())
               {
                  if (it_g == glist.end())
                     break; // Done

                  // Insert remaining sub-menu
                  addItem(sorted, (*it_g).value(), needSeparator);
                  it_g++;
               }
               else if (it_g == glist.end())
               {
                  // Insert remaining service
                  addItem(sorted, (*it_s).value(), needSeparator);
                  it_s++;
               }
               else if ((*it_g).index() < (*it_s).index())
               {
                  // Insert sub-menu first
                  addItem(sorted, (*it_g).value(), needSeparator);
                  it_g++;
               }
               else
               {
                  // Insert service first
                  addItem(sorted, (*it_s).value(), needSeparator);
                  it_s++;
               }
            }
          }
        }
        else if (item[0] == '/')
        {
            QString groupPath = rp + item.mid(1) + "/";

            for (List::ConstIterator it2(group->m_serviceList.begin()); it2 != group->m_serviceList.end(); ++it2)
            {
                if (!(*it2)->isType(KST_KServiceGroup))
                    continue;
                KServiceGroup *group = (KServiceGroup *)((KSycocaEntry *)(*it2));
                if (group->relPath() == groupPath)
                {
                    if (!excludeNoDisplay || !group->noDisplay())
                    {
                        const QString &nextItem = *( ++it );
                        if ( nextItem.startsWith( ":O" ) )
                        {
                            QString tmp(  nextItem );
                            tmp = tmp.remove(":O");
                            QStringList optionAttribute = QStringList::split(" ",tmp);
                            if( optionAttribute.count()==0)
                                optionAttribute.append(tmp);
                            bool bShowEmptyMenu = false;
                            bool bShowInline = false;
                            bool bShowInlineHeader = false;
                            bool bShowInlineAlias = false;
                            int inlineValue = -1;
                            for ( QStringList::Iterator it3 = optionAttribute.begin(); it3 != optionAttribute.end(); ++it3 )
                            {
                                parseAttribute( *it3 , bShowEmptyMenu, bShowInline, bShowInlineHeader, bShowInlineAlias , inlineValue );
                                group->setShowEmptyMenu( bShowEmptyMenu );
                                group->setAllowInline( bShowInline );
                                group->setShowInlineHeader( bShowInlineHeader );
                                group->setInlineAlias( bShowInlineAlias );
                                group->setInlineValue( inlineValue );
                            }
                        }
                        else
                            it--;

                        addItem(sorted, (group), needSeparator);
                    }
                    break;
                }
            }
        }
        else
        {
            for (List::ConstIterator it2(group->m_serviceList.begin()); it2 != group->m_serviceList.end(); ++it2)
            {
                if (!(*it2)->isType(KST_KService))
                    continue;
                KService *service = (KService *)((KSycocaEntry *)(*it2));
                if (service->menuId() == item)
                {
                    if (!excludeNoDisplay || !service->noDisplay())
                        addItem(sorted, (*it2), needSeparator);
                    break;
                }
            }
        }
    }

    return sorted;
}