kio Library API Documentation

kservicefactory.cpp

00001 /*  This file is part of the KDE libraries
00002  *  Copyright (C) 1999 David Faure <faure@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 #include "kservicefactory.h"
00020 #include "ksycoca.h"
00021 #include "ksycocatype.h"
00022 #include "ksycocadict.h"
00023 #include "kservice.h"
00024 
00025 #include <qstring.h>
00026 
00027 #include <klocale.h>
00028 #include <kdebug.h>
00029 #include <kglobal.h>
00030 #include <kstandarddirs.h>
00031 #include <kstaticdeleter.h>
00032 
00033 KServiceFactory::KServiceFactory()
00034  : KSycocaFactory( KST_KServiceFactory )
00035 {
00036    m_offerListOffset = 0;
00037    m_nameDictOffset = 0;
00038    m_relNameDictOffset = 0;
00039    if (m_str)
00040    {
00041       // Read Header
00042       Q_INT32 i;
00043       (*m_str) >> i;
00044       m_nameDictOffset = i;
00045       (*m_str) >> i;
00046       m_relNameDictOffset = i;
00047       (*m_str) >> i;
00048       m_offerListOffset = i;
00049       (*m_str) >> i;
00050       m_initListOffset = i;
00051 
00052       int saveOffset = m_str->device()->at();
00053       // Init index tables
00054       m_nameDict = new KSycocaDict(m_str, m_nameDictOffset);
00055       // Init index tables
00056       m_relNameDict = new KSycocaDict(m_str, m_relNameDictOffset);
00057       saveOffset = m_str->device()->at(saveOffset);
00058    }
00059    else
00060    {
00061       // Build new database
00062       m_nameDict = new KSycocaDict();
00063       m_relNameDict = new KSycocaDict();
00064    }
00065    _self = this;
00066 }
00067 
00068 KServiceFactory::~KServiceFactory()
00069 {
00070    _self = 0L;
00071    delete m_nameDict;
00072    delete m_relNameDict;
00073 }
00074 
00075 KServiceFactory * KServiceFactory::self()
00076 {
00077     if (!_self) {
00078         _self = new KServiceFactory();
00079     }
00080     return _self;
00081 }
00082 
00083 KService * KServiceFactory::findServiceByName(const QString &_name)
00084 {
00085    if (!m_sycocaDict) return 0; // Error!
00086 
00087    // Warning : this assumes we're NOT building a database
00088    // But since findServiceByName isn't called in that case...
00089    // [ see KServiceTypeFactory for how to do it if needed ]
00090 
00091    int offset = m_sycocaDict->find_string( _name );
00092    if (!offset) return 0; // Not found
00093 
00094    KService * newService = createEntry(offset);
00095 
00096    // Check whether the dictionary was right.
00097    if (newService && (newService->name() != _name))
00098    {
00099       // No it wasn't...
00100       delete newService;
00101       newService = 0; // Not found
00102    }
00103    return newService;
00104 }
00105 
00106 KService * KServiceFactory::findServiceByDesktopName(const QString &_name)
00107 {
00108    KService *newService = _findServiceByDesktopName(_name);
00109    if (newService) return newService;
00110 
00111    newService = _findServiceByDesktopName("kde-" + _name);
00112    if (newService) return newService;
00113 
00114    delete newService;
00115    newService = 0;
00116    return newService;
00117 }
00118 
00119 KService * KServiceFactory::findServiceByDesktopPath(const QString &_name)
00120 {
00121    KService *newService = _findServiceByDesktopPath(_name);
00122    if (newService) return newService;
00123 
00124    int pos = _name.findRev('/') + 1;
00125    QString newName = _name;
00126    newService = _findServiceByDesktopPath(newName.insert(pos, "kde-"));
00127    if (newService) return newService;
00128 
00129    delete newService;
00130    newService = 0;
00131    return newService;
00132 }
00133 
00134 KService * KServiceFactory::_findServiceByDesktopName(const QString &_name)
00135 {
00136    if (!m_nameDict) return 0; // Error!
00137 
00138    // Warning : this assumes we're NOT building a database
00139    // But since findServiceByName isn't called in that case...
00140    // [ see KServiceTypeFactory for how to do it if needed ]
00141 
00142    int offset = m_nameDict->find_string( _name );
00143    if (!offset) return 0; // Not found
00144 
00145    KService * newService = createEntry(offset);
00146 
00147    // Check whether the dictionary was right.
00148    if (newService && (newService->desktopEntryName() != _name))
00149    {
00150       // No it wasn't...
00151       delete newService;
00152       newService = 0; // Not found
00153    }
00154    return newService;
00155 }
00156 
00157 KService * KServiceFactory::_findServiceByDesktopPath(const QString &_name)
00158 {
00159    if (!m_relNameDict) return 0; // Error!
00160 
00161    // Warning : this assumes we're NOT building a database
00162    // But since findServiceByName isn't called in that case...
00163    // [ see KServiceTypeFactory for how to do it if needed ]
00164 
00165    int offset = m_relNameDict->find_string( _name );
00166    if (!offset) return 0; // Not found
00167 
00168    KService * newService = createEntry(offset);
00169 
00170    // Check whether the dictionary was right.
00171    if (newService && (newService->desktopEntryPath() != _name))
00172    {
00173       // No it wasn't...
00174       delete newService;
00175       newService = 0; // Not found
00176    }
00177    return newService;
00178 }
00179 
00180 KService* KServiceFactory::createEntry(int offset)
00181 {
00182    KService * newEntry = 0L;
00183    KSycocaType type;
00184    QDataStream *str = KSycoca::self()->findEntry(offset, type);
00185    switch(type)
00186    {
00187      case KST_KService:
00188         newEntry = new KService(*str, offset);
00189         break;
00190 
00191      default:
00192         kdError(7011) << QString("KServiceFactory: unexpected object entry in KSycoca database (type = %1)").arg((int)type) << endl;
00193         return 0;
00194    }
00195    if (!newEntry->isValid())
00196    {
00197       kdError(7011) << "KServiceFactory: corrupt object in KSycoca database!\n" << endl;
00198       delete newEntry;
00199       newEntry = 0;
00200    }
00201    return newEntry;
00202 }
00203 
00204 KService::List KServiceFactory::allServices()
00205 {
00206    KService::List result;
00207    KSycocaEntry::List list = allEntries();
00208    for( KSycocaEntry::List::Iterator it = list.begin();
00209         it != list.end();
00210         ++it)
00211    {
00212       KService *newService = dynamic_cast<KService *>((*it).data());
00213       if (newService)
00214          result.append( KService::Ptr( newService ) );
00215    }
00216    return result;
00217 }
00218 
00219 KService::List KServiceFactory::allInitServices()
00220 {
00221    KService::List list;
00222    if (!m_str) return list;
00223 
00224    // Assume we're NOT building a database
00225 
00226    m_str->device()->at(m_initListOffset);
00227    Q_INT32 entryCount;
00228    (*m_str) >> entryCount;
00229 
00230    Q_INT32 *offsetList = new Q_INT32[entryCount];
00231    for(int i = 0; i < entryCount; i++)
00232    {
00233       (*m_str) >> offsetList[i];
00234    }
00235 
00236    for(int i = 0; i < entryCount; i++)
00237    {
00238       KService *newEntry = createEntry(offsetList[i]);
00239       if (newEntry)
00240       {
00241          list.append( KService::Ptr( newEntry ) );
00242       }
00243    }
00244    delete [] offsetList;
00245    return list;
00246 }
00247 
00248 KService::List KServiceFactory::offers( int serviceTypeOffset )
00249 {
00250    KService::List list;
00251 
00252    QDataStream *str = m_str;
00253    // Jump to the offer list
00254    str->device()->at( m_offerListOffset );
00255 
00256    Q_INT32 aServiceTypeOffset;
00257    Q_INT32 aServiceOffset;
00258    // We might want to do a binary search instead of a linear search
00259    // since servicetype offsets are sorted. Bah.
00260    while (true)
00261    {
00262       (*str) >> aServiceTypeOffset;
00263       if ( aServiceTypeOffset )
00264       {
00265          (*str) >> aServiceOffset;
00266          if ( aServiceTypeOffset == serviceTypeOffset )
00267          {
00268             // Save stream position !
00269             int savedPos = str->device()->at();
00270             // Create Service
00271             KService * serv = createEntry( aServiceOffset );
00272             if (serv)
00273                 list.append( KService::Ptr( serv ) );
00274             // Restore position
00275             str->device()->at( savedPos );
00276          } else if ( aServiceTypeOffset > (Q_INT32)serviceTypeOffset )
00277             break; // too far
00278       }
00279       else
00280          break; // 0 => end of list
00281    }
00282    return list;
00283 }
00284 
00285 KServiceFactory *KServiceFactory::_self = 0;
00286 
00287 void KServiceFactory::virtual_hook( int id, void* data )
00288 { KSycocaFactory::virtual_hook( id, data ); }
00289 
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 27 22:15:32 2005 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001