TDE core libraries
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

kbuildservicefactory.cpp 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /* This file is part of the KDE libraries
  2. * Copyright (C) 1999 David Faure <faure@kde.org>
  3. * 1999 Waldo Bastian <bastian@kde.org>
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Library General Public
  7. * License version 2 as published by the Free Software Foundation;
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Library General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Library General Public License
  15. * along with this library; see the file COPYING.LIB. If not, write to
  16. * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  17. * Boston, MA 02110-1301, USA.
  18. **/
  19. #include "kbuildservicefactory.h"
  20. #include "tdesycoca.h"
  21. #include "tdesycocadict.h"
  22. #include "kresourcelist.h"
  23. #include "kmimetype.h"
  24. #include <tdeglobal.h>
  25. #include <kstandarddirs.h>
  26. #include <kmessageboxwrapper.h>
  27. #include <tdelocale.h>
  28. #include <kdebug.h>
  29. #include <assert.h>
  30. KBuildServiceFactory::KBuildServiceFactory( KSycocaFactory *serviceTypeFactory,
  31. KBuildServiceGroupFactory *serviceGroupFactory ) :
  32. KServiceFactory(),
  33. m_serviceDict(977),
  34. m_dupeDict(977),
  35. m_serviceTypeFactory( serviceTypeFactory ),
  36. m_serviceGroupFactory( serviceGroupFactory )
  37. {
  38. m_resourceList = new KSycocaResourceList();
  39. // m_resourceList->add( "apps", "*.desktop" );
  40. // m_resourceList->add( "apps", "*.kdelnk" );
  41. m_resourceList->add( "services", "*.desktop" );
  42. m_resourceList->add( "services", "*.kdelnk" );
  43. }
  44. // return all service types for this factory
  45. // i.e. first arguments to m_resourceList->add() above
  46. TQStringList KBuildServiceFactory::resourceTypes()
  47. {
  48. return TQStringList() << "apps" << "services";
  49. }
  50. KBuildServiceFactory::~KBuildServiceFactory()
  51. {
  52. delete m_resourceList;
  53. }
  54. KService * KBuildServiceFactory::findServiceByName(const TQString &_name)
  55. {
  56. return m_serviceDict[_name];
  57. }
  58. KSycocaEntry *
  59. KBuildServiceFactory::createEntry( const TQString& file, const char *resource )
  60. {
  61. TQString name = file;
  62. int pos = name.findRev('/');
  63. if (pos != -1)
  64. {
  65. name = name.mid(pos+1);
  66. }
  67. if (name.isEmpty())
  68. return 0;
  69. // Is it a .desktop file?
  70. if (!name.endsWith(".desktop") && !name.endsWith(".kdelnk"))
  71. return 0;
  72. KDesktopFile desktopFile(file, true, resource);
  73. KService * serv = new KService( &desktopFile );
  74. if ( serv->isValid() && !serv->isDeleted() )
  75. {
  76. return serv;
  77. } else {
  78. if (!serv->isDeleted())
  79. kdWarning(7012) << "Invalid Service : " << file << endl;
  80. delete serv;
  81. return 0L;
  82. }
  83. }
  84. void
  85. KBuildServiceFactory::saveHeader(TQDataStream &str)
  86. {
  87. KSycocaFactory::saveHeader(str);
  88. str << (TQ_INT32) m_nameDictOffset;
  89. str << (TQ_INT32) m_relNameDictOffset;
  90. str << (TQ_INT32) m_offerListOffset;
  91. str << (TQ_INT32) m_initListOffset;
  92. str << (TQ_INT32) m_menuIdDictOffset;
  93. }
  94. void
  95. KBuildServiceFactory::save(TQDataStream &str)
  96. {
  97. KSycocaFactory::save(str);
  98. m_nameDictOffset = str.device()->at();
  99. m_nameDict->save(str);
  100. m_relNameDictOffset = str.device()->at();
  101. m_relNameDict->save(str);
  102. saveOfferList(str);
  103. saveInitList(str);
  104. m_menuIdDictOffset = str.device()->at();
  105. m_menuIdDict->save(str);
  106. int endOfFactoryData = str.device()->at();
  107. // Update header (pass #3)
  108. saveHeader(str);
  109. // Seek to end.
  110. str.device()->at(endOfFactoryData);
  111. }
  112. void
  113. KBuildServiceFactory::saveOfferList(TQDataStream &str)
  114. {
  115. m_offerListOffset = str.device()->at();
  116. bool isNumber;
  117. for(TQDictIterator<KSycocaEntry::Ptr> itserv ( *m_entryDict );
  118. itserv.current();
  119. ++itserv)
  120. {
  121. KService *service = (KService *) ((KSycocaEntry *)(*itserv.current()));
  122. TQStringList serviceTypeList = service->serviceTypes();
  123. KServiceType::List serviceTypes;
  124. TQStringList::ConstIterator it = serviceTypeList.begin();
  125. for( ; it != serviceTypeList.end(); ++it )
  126. {
  127. (*it).toInt(&isNumber);
  128. if (isNumber)
  129. continue;
  130. KServiceType::Ptr serviceType = KServiceType::serviceType(*it);
  131. if (!serviceType)
  132. {
  133. // kdWarning() << "'"<< service->desktopEntryPath() << "' specifies undefined mimetype/servicetype '"<< (*it) << "'" << endl;
  134. continue;
  135. }
  136. serviceTypes.append(serviceType);
  137. }
  138. while(serviceTypes.count())
  139. {
  140. KServiceType::Ptr serviceType = serviceTypes.first();
  141. serviceTypes.pop_front();
  142. KServiceType::Ptr parentType = serviceType->parentType();
  143. if (parentType)
  144. serviceTypes.append(parentType);
  145. serviceType->addService(service);
  146. }
  147. }
  148. // For each entry in servicetypeFactory
  149. for(TQDictIterator<KSycocaEntry::Ptr> it ( *(m_serviceTypeFactory->entryDict()) );
  150. it.current();
  151. ++it)
  152. {
  153. // export associated services
  154. KServiceType *entry = static_cast<KServiceType*>(static_cast<KSycocaEntry*>(*it.current()));
  155. KService::List services = entry->services();
  156. for(KService::List::ConstIterator it2 = services.begin();
  157. it2 != services.end(); ++it2)
  158. {
  159. KService *service = *it2;
  160. str << (TQ_INT32) entry->offset();
  161. str << (TQ_INT32) service->offset();
  162. }
  163. }
  164. str << (TQ_INT32) 0; // End of list marker (0)
  165. }
  166. void
  167. KBuildServiceFactory::saveInitList(TQDataStream &str)
  168. {
  169. m_initListOffset = str.device()->at();
  170. KService::List initList;
  171. for(TQDictIterator<KSycocaEntry::Ptr> itserv ( *m_entryDict );
  172. itserv.current();
  173. ++itserv)
  174. {
  175. KService::Ptr service = (KService *) ((KSycocaEntry *) *itserv.current());
  176. if ( !service->init().isEmpty() )
  177. {
  178. initList.append(service);
  179. }
  180. }
  181. str << (TQ_INT32) initList.count(); // Nr of init services.
  182. for(KService::List::Iterator it = initList.begin();
  183. it != initList.end();
  184. ++it)
  185. {
  186. str << (TQ_INT32) (*it)->offset();
  187. }
  188. }
  189. void
  190. KBuildServiceFactory::addEntry(KSycocaEntry *newEntry, const char *resource)
  191. {
  192. if (m_dupeDict.find(newEntry))
  193. return;
  194. KSycocaFactory::addEntry(newEntry, resource);
  195. KService * service = (KService *) newEntry;
  196. m_dupeDict.insert(newEntry, service);
  197. if (!service->isDeleted())
  198. {
  199. TQString parent = service->parentApp();
  200. if (!parent.isEmpty())
  201. m_serviceGroupFactory->addNewChild(parent, resource, service);
  202. }
  203. TQString name = service->desktopEntryName();
  204. m_nameDict->add( name, newEntry );
  205. m_serviceDict.replace(name, service);
  206. TQString relName = service->desktopEntryPath();
  207. m_relNameDict->add( relName, newEntry );
  208. TQString menuId = service->menuId();
  209. if (!menuId.isEmpty())
  210. m_menuIdDict->add( menuId, newEntry );
  211. }