# kio Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# 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., 59 Temple Place - Suite 330,
    00016  *  Boston, MA 02111-1307, USA.
    00017  **/
    00018
    00019 // $Id: kservicegroup.cpp,v 1.25 2002/11/19 21:07:31 bausi Exp $
    00020
    00021 #include <kiconloader.h>
    00022 #include <kglobal.h>
    00023 #include <kstandarddirs.h>
    00024 #include <klocale.h>
    00025 #include <kdebug.h>
    00026 #include <ksortablevaluelist.h>
    00027 #include "kservicefactory.h"
    00028 #include "kservicegroupfactory.h"
    00029 #include "kservicegroup.h"
    00030 #include "kservice.h"
    00031 #include "ksycoca.h"
    00032
    00033 class KServiceGroup::Private
    00034 {
    00035 public:
    00036   Private() { m_bNoDisplay = false; }
    00037   bool m_bNoDisplay;
    00038 };
    00039
    00040 KServiceGroup::KServiceGroup( const QString & name )
    00041  : KSycocaEntry(name), m_childCount(-1)
    00042 {
    00043   d = new KServiceGroup::Private;
    00044   m_bDeleted = false;
    00045 }
    00046
    00047 KServiceGroup::KServiceGroup( const QString &configFile, const QString & _relpath )
    00048  : KSycocaEntry(_relpath), m_childCount(-1)
    00049 {
    00050   d = new KServiceGroup::Private;
    00051   m_bDeleted = false;
    00052
    00053   if (!configFile.isEmpty())
    00054   {
    00055      KConfig config( _relpath+".directory", true, false, "apps" );
    00056
    00057      config.setDesktopGroup();
    00058
    00059      m_strCaption = config.readEntry( "Name" );
    00060      m_strIcon = config.readEntry( "Icon" );
    00061      m_strComment = config.readEntry( "Comment" );
    00062      m_bDeleted = config.readBoolEntry( "Hidden", false );
    00063      d->m_bNoDisplay = config.readBoolEntry( "NoDisplay", false );
    00064      m_strBaseGroupName = config.readEntry( "X-KDE-BaseGroup" );
    00065   }
    00066   // Fill in defaults.
    00067   if (m_strCaption.isEmpty())
    00068   {
    00069      m_strCaption = _relpath;
    00070      if (m_strCaption.right(1) == "/")
    00071         m_strCaption = m_strCaption.left(m_strCaption.length()-1);
    00072      int i = m_strCaption.findRev('/');
    00073      if (i > 0)
    00074         m_strCaption = m_strCaption.mid(i+1);
    00075   }
    00076   if (m_strIcon.isEmpty())
    00077      m_strIcon = "folder";
    00078 }
    00079
    00080 KServiceGroup::KServiceGroup( QDataStream& _str, int offset, bool deep ) :
    00081     KSycocaEntry( _str, offset )
    00082 {
    00083   d = new KServiceGroup::Private;
    00084   m_bDeep = deep;
    00085   load( _str );
    00086 }
    00087
    00088 KServiceGroup::~KServiceGroup()
    00089 {
    00090   delete d;
    00091 }
    00092
    00093 int KServiceGroup::childCount()
    00094 {
    00095   if (m_childCount == -1)
    00096   {
    00097      m_childCount = 0;
    00098
    00099      for( List::ConstIterator it = m_serviceList.begin();
    00100           it != m_serviceList.end(); it++)
    00101      {
    00102         KSycocaEntry *p = (*it);
    00103         if (p->isType(KST_KService))
    00104         {
    00105            KService *service = static_cast<KService *>(p);
    00106            if (!service->noDisplay())
    00107               m_childCount++;
    00108         }
    00109         else if (p->isType(KST_KServiceGroup))
    00110         {
    00111            KServiceGroup *serviceGroup = static_cast<KServiceGroup *>(p);
    00112            m_childCount += serviceGroup->childCount();
    00113         }
    00114      }
    00115   }
    00116   return m_childCount;
    00117 }
    00118
    00119
    00120 bool KServiceGroup::noDisplay() const
    00121 {
    00122     return d->m_bNoDisplay;
    00123 }
    00124
    00125 void KServiceGroup::load( QDataStream& s )
    00126 {
    00127   QStringList groupList;
    00128   Q_INT8 noDisplay;
    00129   s >> m_strCaption >> m_strIcon >>
    00130       m_strComment >> groupList >> m_strBaseGroupName >> m_childCount >>
    00131       noDisplay;
    00132
    00133   d->m_bNoDisplay = (noDisplay != 0);
    00134
    00135   if (m_bDeep)
    00136   {
    00137      for(QStringList::ConstIterator it = groupList.begin();
    00138          it != groupList.end(); it++)
    00139      {
    00140         QString path = *it;
    00141         if (path[path.length()-1] == '/')
    00142         {
    00143            KServiceGroup *serviceGroup;
    00144            serviceGroup = KServiceGroupFactory::self()->findGroupByDesktopPath(path, false);
    00145            m_serviceList.append( SPtr(serviceGroup) );
    00146         }
    00147         else
    00148         {
    00149            KService *service;
    00150            service = KServiceFactory::self()->findServiceByDesktopPath(path);
    00151            m_serviceList.append( SPtr(service) );
    00152         }
    00153      }
    00154   }
    00155 }
    00156
    00157 void KServiceGroup::addEntry( KSycocaEntry *entry)
    00158 {
    00159   m_serviceList.append(entry);
    00160 }
    00161
    00162 void KServiceGroup::save( QDataStream& s )
    00163 {
    00164   KSycocaEntry::save( s );
    00165
    00166   QStringList groupList;
    00167   for( List::ConstIterator it = m_serviceList.begin();
    00168        it != m_serviceList.end(); it++)
    00169   {
    00170      KSycocaEntry *p = (*it);
    00171      if (p->isType(KST_KService))
    00172      {
    00173         KService *service = static_cast<KService *>(p);
    00174         groupList.append( service->desktopEntryPath());
    00175      }
    00176      else if (p->isType(KST_KServiceGroup))
    00177      {
    00178         KServiceGroup *serviceGroup = static_cast<KServiceGroup *>(p);
    00179         groupList.append( serviceGroup->relPath());
    00180      }
    00181      else
    00182      {
    00183         //fprintf(stderr, "KServiceGroup: Unexpected object in list!\n");
    00184      }
    00185   }
    00186
    00187   (void) childCount();
    00188
    00189   Q_INT8 noDisplay = d->m_bNoDisplay ? 1 : 0;
    00190   s << m_strCaption << m_strIcon <<
    00191       m_strComment << groupList << m_strBaseGroupName << m_childCount <<
    00192       noDisplay;
    00193 }
    00194
    00195 KServiceGroup::List
    00196 KServiceGroup::entries(bool sort)
    00197 {
    00198    return entries(sort, true);
    00199 }
    00200
    00201 KServiceGroup::List
    00202 KServiceGroup::entries(bool sort, bool excludeNoDisplay)
    00203 {
    00204     KServiceGroup *group = this;
    00205
    00206     // If the entries haven't been loaded yet, we have to reload ourselves
    00207     // together with the entries. We can't only load the entries afterwards
    00208     // since the offsets could have been changed if the database has changed.
    00209
    00210     if (!m_bDeep) {
    00211
    00212         group =
    00213             KServiceGroupFactory::self()->findGroupByDesktopPath(relPath(), true);
    00214
    00215         if (0 == group) // No guarantee that we still exist!
    00216             return List();
    00217     }
    00218
    00219     if (!sort)
    00220         return group->m_serviceList;
    00221
    00222
    00223     // Sort the list alphabetically, according to locale.
    00224     // Groups come first, then services.
    00225
    00226     KSortableValueList<SPtr,QCString> slist;
    00227     KSortableValueList<SPtr,QCString> glist;
    00228     for (List::ConstIterator it(group->m_serviceList.begin()); it != group->m_serviceList.end(); ++it)
    00229     {
    00230         KSycocaEntry *p = (*it);
    00231         // Choose the right list
    00232         KSortableValueList<SPtr,QCString> & list = p->isType(KST_KServiceGroup) ? glist : slist;
    00233         QString name = p->isType(KST_KServiceGroup) ?
    00234                                    static_cast<KServiceGroup *>(p)->caption() :
    00235                                    p->name();
    00236         QCString key( name.length() * 4 + 1 );
    00237         // strxfrm() crashes on Solaris
    00238 #ifndef USE_SOLARIS
    00239         // maybe it'd be better to use wcsxfrm() where available
    00240         size_t ln = strxfrm( key.data(), name.local8Bit().data(), key.size());
    00241         if( ln != size_t( -1 ))
    00242         {
    00243             if( ln >= key.size())
    00244             { // didn't fit?
    00245                 key.resize( ln + 1 );
    00246                 if( strxfrm( key.data(), name.local8Bit().data(), key.size()) == size_t( -1 ))
    00247                     key = name.local8Bit();
    00248             }
    00249         }
    00250         else
    00251 #endif
    00252         {
    00253             key = name.local8Bit();
    00254         }
    00255         list.insert(key,SPtr(*it));
    00256     }
    00257     // Now sort
    00258     slist.sort();
    00259     glist.sort();
    00260
    00261     List lsort;
    00262     for(KSortableValueList<SPtr,QCString>::ConstIterator it = glist.begin(); it != glist.end(); ++it)
    00263     {
    00264         if (excludeNoDisplay)
    00265         {
    00266            KServiceGroup *serviceGroup = (KServiceGroup *)((KSycocaEntry *)((*it).value()));
    00267            if (serviceGroup->noDisplay())
    00268               continue;
    00269         }
    00270         lsort.append((*it).value());
    00271     }
    00272     for(KSortableValueList<SPtr,QCString>::ConstIterator it = slist.begin(); it != slist.end(); ++it)
    00273     {
    00274         if (excludeNoDisplay)
    00275         {
    00276            KService *service = (KService *)((KSycocaEntry *)((*it).value()));
    00277            if (service->noDisplay())
    00278               continue;
    00279         }
    00280         lsort.append((*it).value());
    00281     }
    00282
    00283     // honor the SortOrder Key
    00284
    00285     QString rp = relPath();
    00286     if(rp == "/") rp = QString::null;
    00287
    00288     QStringList order =
    00289         KDesktopFile(rp + QString::fromUtf8(".directory")).sortOrder();
    00290
    00291     if (order.isEmpty())
    00292         return lsort;
    00293
    00294     //kdDebug() << "Honouring sort order " << order.join(",") << endl;
    00295
    00296     // Iterate through the sort spec list. If we find an entry that matches one
    00297     // in the original list, take it out of the original list and add it to the
    00298     // sorted list. Finally, add all entries that are still in the original list
    00299     // to the end of the sorted list.
    00300
    00301     List sorted;
    00302     List orig = lsort;
    00303
    00304     for (QStringList::ConstIterator it(order.begin()); it != order.end(); ++it)
    00305     {
    00306         //kdDebug() << "order has : " << *it << endl;
    00307         for (List::Iterator sit(orig.begin()); sit != orig.end(); ++sit)
    00308             {
    00309                 QString entry = (*sit)->entryPath();
    00310                 // Groups have a trailing slash, we need to remove it first
    00311                 if ( entry[entry.length()-1] == '/' )
    00312                    entry.truncate(entry.length()-1);
    00313                 //kdDebug() << "Comparing to : " << entry.mid(entry.findRev('/')+1) << endl;
    00314                 if (*it == entry.mid(entry.findRev('/')+1))
    00315                     {
    00316                         //kdDebug() << "Appending to sorted : " << *it << endl;
    00317                         sorted.append(*sit);
    00318                         orig.remove(sit);
    00319                         break;
    00320                     }
    00321             }
    00322     }
    00323
    00324     for (List::Iterator sit(orig.begin()); sit != orig.end(); ++sit)
    00325         sorted.append(*sit);
    00326
    00327     return sorted;
    00328 }
    00329
    00330 KServiceGroup::Ptr
    00331 KServiceGroup::baseGroup( const QString & _baseGroupName )
    00332 {
    00333     return KServiceGroupFactory::self()->findBaseGroup(_baseGroupName, true);
    00334 }
    00335
    00336 KServiceGroup::Ptr
    00337 KServiceGroup::root()
    00338 {
    00339    return KServiceGroupFactory::self()->findGroupByDesktopPath("/", true);
    00340 }
    00341
    00342 KServiceGroup::Ptr
    00343 KServiceGroup::group(const QString &relPath)
    00344 {
    00345    if (relPath.isEmpty()) return root();
    00346    return KServiceGroupFactory::self()->findGroupByDesktopPath(relPath, true);
    00347 }
    00348
    00349 KServiceGroup::Ptr
    00350 KServiceGroup::childGroup(const QString &parent)
    00351 {
    00352    return KServiceGroupFactory::self()->findGroupByDesktopPath("#parent#"+parent, true);
    00353 }
    00354
    00355
    00356
    00357 void KServiceGroup::virtual_hook( int id, void* data )
    00358 { KSycocaEntry::virtual_hook( id, data ); }

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:14:18 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001