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