kbuildservicefactory.cpp
00001 /* This file is part of the KDE libraries 00002 * Copyright (C) 1999 David Faure <faure@kde.org> 00003 * 1999 Waldo Bastian <bastian@kde.org> 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Library General Public 00007 * License version 2 as published by the Free Software Foundation; 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Library General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Library General Public License 00015 * along with this library; see the file COPYING.LIB. If not, write to 00016 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 * Boston, MA 02110-1301, USA. 00018 **/ 00019 00020 #include "kbuildservicefactory.h" 00021 #include "ksycoca.h" 00022 #include "ksycocadict.h" 00023 #include "kresourcelist.h" 00024 #include "kmimetype.h" 00025 00026 #include <kglobal.h> 00027 #include <kstandarddirs.h> 00028 #include <kmessageboxwrapper.h> 00029 #include <klocale.h> 00030 #include <kdebug.h> 00031 #include <assert.h> 00032 00033 KBuildServiceFactory::KBuildServiceFactory( KSycocaFactory *serviceTypeFactory, 00034 KBuildServiceGroupFactory *serviceGroupFactory ) : 00035 KServiceFactory(), 00036 m_serviceDict(977), 00037 m_dupeDict(977), 00038 m_serviceTypeFactory( serviceTypeFactory ), 00039 m_serviceGroupFactory( serviceGroupFactory ) 00040 { 00041 m_resourceList = new KSycocaResourceList(); 00042 // m_resourceList->add( "apps", "*.desktop" ); 00043 // m_resourceList->add( "apps", "*.kdelnk" ); 00044 m_resourceList->add( "services", "*.desktop" ); 00045 m_resourceList->add( "services", "*.kdelnk" ); 00046 } 00047 00048 // return all service types for this factory 00049 // i.e. first arguments to m_resourceList->add() above 00050 TQStringList KBuildServiceFactory::resourceTypes() 00051 { 00052 return TQStringList() << "apps" << "services"; 00053 } 00054 00055 KBuildServiceFactory::~KBuildServiceFactory() 00056 { 00057 delete m_resourceList; 00058 } 00059 00060 KService * KBuildServiceFactory::findServiceByName(const TQString &_name) 00061 { 00062 return m_serviceDict[_name]; 00063 } 00064 00065 00066 KSycocaEntry * 00067 KBuildServiceFactory::createEntry( const TQString& file, const char *resource ) 00068 { 00069 TQString name = file; 00070 int pos = name.findRev('/'); 00071 if (pos != -1) 00072 { 00073 name = name.mid(pos+1); 00074 } 00075 00076 if (name.isEmpty()) 00077 return 0; 00078 00079 // Is it a .desktop file? 00080 if (!name.endsWith(".desktop") && !name.endsWith(".kdelnk")) 00081 return 0; 00082 00083 KDesktopFile desktopFile(file, true, resource); 00084 00085 KService * serv = new KService( &desktopFile ); 00086 00087 if ( serv->isValid() && !serv->isDeleted() ) 00088 { 00089 return serv; 00090 } else { 00091 if (!serv->isDeleted()) 00092 kdWarning(7012) << "Invalid Service : " << file << endl; 00093 delete serv; 00094 return 0L; 00095 } 00096 } 00097 00098 00099 void 00100 KBuildServiceFactory::saveHeader(TQDataStream &str) 00101 { 00102 KSycocaFactory::saveHeader(str); 00103 00104 str << (TQ_INT32) m_nameDictOffset; 00105 str << (TQ_INT32) m_relNameDictOffset; 00106 str << (TQ_INT32) m_offerListOffset; 00107 str << (TQ_INT32) m_initListOffset; 00108 str << (TQ_INT32) m_menuIdDictOffset; 00109 } 00110 00111 void 00112 KBuildServiceFactory::save(TQDataStream &str) 00113 { 00114 KSycocaFactory::save(str); 00115 00116 m_nameDictOffset = str.device()->at(); 00117 m_nameDict->save(str); 00118 00119 m_relNameDictOffset = str.device()->at(); 00120 m_relNameDict->save(str); 00121 00122 saveOfferList(str); 00123 saveInitList(str); 00124 00125 m_menuIdDictOffset = str.device()->at(); 00126 m_menuIdDict->save(str); 00127 00128 int endOfFactoryData = str.device()->at(); 00129 00130 // Update header (pass #3) 00131 saveHeader(str); 00132 00133 00134 // Seek to end. 00135 str.device()->at(endOfFactoryData); 00136 } 00137 00138 void 00139 KBuildServiceFactory::saveOfferList(TQDataStream &str) 00140 { 00141 m_offerListOffset = str.device()->at(); 00142 00143 bool isNumber; 00144 for(TQDictIterator<KSycocaEntry::Ptr> itserv ( *m_entryDict ); 00145 itserv.current(); 00146 ++itserv) 00147 { 00148 KService *service = (KService *) ((KSycocaEntry *)(*itserv.current())); 00149 TQStringList serviceTypeList = service->serviceTypes(); 00150 KServiceType::List serviceTypes; 00151 TQStringList::ConstIterator it = serviceTypeList.begin(); 00152 for( ; it != serviceTypeList.end(); ++it ) 00153 { 00154 (*it).toInt(&isNumber); 00155 if (isNumber) 00156 continue; 00157 00158 KServiceType::Ptr serviceType = KServiceType::serviceType(*it); 00159 if (!serviceType) 00160 { 00161 // kdWarning() << "'"<< service->desktopEntryPath() << "' specifies undefined mimetype/servicetype '"<< (*it) << "'" << endl; 00162 continue; 00163 } 00164 serviceTypes.append(serviceType); 00165 } 00166 00167 while(serviceTypes.count()) 00168 { 00169 KServiceType::Ptr serviceType = serviceTypes.first(); 00170 serviceTypes.pop_front(); 00171 00172 KServiceType::Ptr parentType = serviceType->parentType(); 00173 if (parentType) 00174 serviceTypes.append(parentType); 00175 00176 serviceType->addService(service); 00177 } 00178 } 00179 00180 // For each entry in servicetypeFactory 00181 for(TQDictIterator<KSycocaEntry::Ptr> it ( *(m_serviceTypeFactory->entryDict()) ); 00182 it.current(); 00183 ++it) 00184 { 00185 // export associated services 00186 KServiceType *entry = static_cast<KServiceType*>(static_cast<KSycocaEntry*>(*it.current())); 00187 KService::List services = entry->services(); 00188 00189 for(KService::List::ConstIterator it2 = services.begin(); 00190 it2 != services.end(); ++it2) 00191 { 00192 KService *service = *it2; 00193 str << (TQ_INT32) entry->offset(); 00194 str << (TQ_INT32) service->offset(); 00195 } 00196 } 00197 00198 str << (TQ_INT32) 0; // End of list marker (0) 00199 } 00200 00201 void 00202 KBuildServiceFactory::saveInitList(TQDataStream &str) 00203 { 00204 m_initListOffset = str.device()->at(); 00205 00206 KService::List initList; 00207 00208 for(TQDictIterator<KSycocaEntry::Ptr> itserv ( *m_entryDict ); 00209 itserv.current(); 00210 ++itserv) 00211 { 00212 KService::Ptr service = (KService *) ((KSycocaEntry *) *itserv.current()); 00213 if ( !service->init().isEmpty() ) 00214 { 00215 initList.append(service); 00216 } 00217 } 00218 str << (TQ_INT32) initList.count(); // Nr of init services. 00219 for(KService::List::Iterator it = initList.begin(); 00220 it != initList.end(); 00221 ++it) 00222 { 00223 str << (TQ_INT32) (*it)->offset(); 00224 } 00225 } 00226 00227 void 00228 KBuildServiceFactory::addEntry(KSycocaEntry *newEntry, const char *resource) 00229 { 00230 if (m_dupeDict.find(newEntry)) 00231 return; 00232 00233 KSycocaFactory::addEntry(newEntry, resource); 00234 00235 KService * service = (KService *) newEntry; 00236 m_dupeDict.insert(newEntry, service); 00237 00238 if (!service->isDeleted()) 00239 { 00240 TQString parent = service->parentApp(); 00241 if (!parent.isEmpty()) 00242 m_serviceGroupFactory->addNewChild(parent, resource, service); 00243 } 00244 00245 TQString name = service->desktopEntryName(); 00246 m_nameDict->add( name, newEntry ); 00247 m_serviceDict.replace(name, service); 00248 00249 TQString relName = service->desktopEntryPath(); 00250 m_relNameDict->add( relName, newEntry ); 00251 TQString menuId = service->menuId(); 00252 if (!menuId.isEmpty()) 00253 m_menuIdDict->add( menuId, newEntry ); 00254 }