kio
kservicefactory.cpp
Go to the documentation of this file.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., 51 Franklin Street, Fifth Floor, 00016 * Boston, MA 02110-1301, 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 if (!m_nameDict) return 0; // Error! 00116 00117 // Warning : this assumes we're NOT building a database 00118 // But since findServiceByName isn't called in that case... 00119 // [ see KServiceTypeFactory for how to do it if needed ] 00120 00121 int offset = m_nameDict->find_string( _name ); 00122 if (!offset) return 0; // Not found 00123 00124 KService * newService = createEntry(offset); 00125 00126 // Check whether the dictionary was right. 00127 if (newService && (newService->desktopEntryName() != _name)) 00128 { 00129 // No it wasn't... 00130 delete newService; 00131 newService = 0; // Not found 00132 } 00133 return newService; 00134 } 00135 00136 KService * KServiceFactory::findServiceByDesktopPath(const QString &_name) 00137 { 00138 if (!m_relNameDict) return 0; // Error! 00139 00140 // Warning : this assumes we're NOT building a database 00141 // But since findServiceByName isn't called in that case... 00142 // [ see KServiceTypeFactory for how to do it if needed ] 00143 00144 int offset = m_relNameDict->find_string( _name ); 00145 if (!offset) return 0; // Not found 00146 00147 KService * newService = createEntry(offset); 00148 00149 // Check whether the dictionary was right. 00150 if (newService && (newService->desktopEntryPath() != _name)) 00151 { 00152 // No it wasn't... 00153 delete newService; 00154 newService = 0; // Not found 00155 } 00156 return newService; 00157 } 00158 00159 KService * KServiceFactory::findServiceByMenuId(const QString &_menuId) 00160 { 00161 if (!m_menuIdDict) return 0; // Error! 00162 00163 // Warning : this assumes we're NOT building a database 00164 // But since findServiceByMenuId isn't called in that case... 00165 // [ see KServiceTypeFactory for how to do it if needed ] 00166 00167 int offset = m_menuIdDict->find_string( _menuId ); 00168 if (!offset) return 0; // Not found 00169 00170 KService * newService = createEntry(offset); 00171 00172 // Check whether the dictionary was right. 00173 if (newService && (newService->menuId() != _menuId)) 00174 { 00175 // No it wasn't... 00176 delete newService; 00177 newService = 0; // Not found 00178 } 00179 return newService; 00180 } 00181 00182 KService* KServiceFactory::createEntry(int offset) 00183 { 00184 KService * newEntry = 0L; 00185 KSycocaType type; 00186 QDataStream *str = KSycoca::self()->findEntry(offset, type); 00187 switch(type) 00188 { 00189 case KST_KService: 00190 newEntry = new KService(*str, offset); 00191 break; 00192 00193 default: 00194 kdError(7011) << QString("KServiceFactory: unexpected object entry in KSycoca database (type = %1)").arg((int)type) << endl; 00195 return 0; 00196 } 00197 if (!newEntry->isValid()) 00198 { 00199 kdError(7011) << "KServiceFactory: corrupt object in KSycoca database!\n" << endl; 00200 delete newEntry; 00201 newEntry = 0; 00202 } 00203 return newEntry; 00204 } 00205 00206 KService::List KServiceFactory::allServices() 00207 { 00208 KService::List result; 00209 KSycocaEntry::List list = allEntries(); 00210 for( KSycocaEntry::List::Iterator it = list.begin(); 00211 it != list.end(); 00212 ++it) 00213 { 00214 KService *newService = dynamic_cast<KService *>((*it).data()); 00215 if (newService) 00216 result.append( KService::Ptr( newService ) ); 00217 } 00218 return result; 00219 } 00220 00221 KService::List KServiceFactory::allInitServices() 00222 { 00223 KService::List list; 00224 if (!m_str) return list; 00225 00226 // Assume we're NOT building a database 00227 00228 m_str->device()->at(m_initListOffset); 00229 Q_INT32 entryCount; 00230 (*m_str) >> entryCount; 00231 00232 Q_INT32 *offsetList = new Q_INT32[entryCount]; 00233 for(int i = 0; i < entryCount; i++) 00234 { 00235 (*m_str) >> offsetList[i]; 00236 } 00237 00238 for(int i = 0; i < entryCount; i++) 00239 { 00240 KService *newEntry = createEntry(offsetList[i]); 00241 if (newEntry) 00242 { 00243 list.append( KService::Ptr( newEntry ) ); 00244 } 00245 } 00246 delete [] offsetList; 00247 return list; 00248 } 00249 00250 KService::List KServiceFactory::offers( int serviceTypeOffset ) 00251 { 00252 KService::List list; 00253 00254 QDataStream *str = m_str; 00255 // Jump to the offer list 00256 str->device()->at( m_offerListOffset ); 00257 00258 Q_INT32 aServiceTypeOffset; 00259 Q_INT32 aServiceOffset; 00260 // We might want to do a binary search instead of a linear search 00261 // since servicetype offsets are sorted. Bah. 00262 while (true) 00263 { 00264 (*str) >> aServiceTypeOffset; 00265 if ( aServiceTypeOffset ) 00266 { 00267 (*str) >> aServiceOffset; 00268 if ( aServiceTypeOffset == serviceTypeOffset ) 00269 { 00270 // Save stream position ! 00271 int savedPos = str->device()->at(); 00272 // Create Service 00273 KService * serv = createEntry( aServiceOffset ); 00274 if (serv) 00275 list.append( KService::Ptr( serv ) ); 00276 // Restore position 00277 str->device()->at( savedPos ); 00278 } else if ( aServiceTypeOffset > (Q_INT32)serviceTypeOffset ) 00279 break; // too far 00280 } 00281 else 00282 break; // 0 => end of list 00283 } 00284 return list; 00285 } 00286 00287 KServiceFactory *KServiceFactory::_self = 0; 00288 00289 void KServiceFactory::virtual_hook( int id, void* data ) 00290 { KSycocaFactory::virtual_hook( id, data ); } 00291