kded
kbuildservicetypefactory.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "kbuildservicetypefactory.h"
00020 #include "tdesycoca.h"
00021 #include "tdesycocadict.h"
00022 #include "kresourcelist.h"
00023
00024 #include <tdeglobal.h>
00025 #include <kstandarddirs.h>
00026 #include <kmessageboxwrapper.h>
00027 #include <kdebug.h>
00028 #include <tdelocale.h>
00029 #include <assert.h>
00030 #include <kdesktopfile.h>
00031
00032 template class TQDict<KMimeType>;
00033
00034 KBuildServiceTypeFactory::KBuildServiceTypeFactory() :
00035 KServiceTypeFactory()
00036 {
00037
00038 m_resourceList = new KSycocaResourceList;
00039 m_resourceList->add("servicetypes", "*.desktop");
00040 m_resourceList->add("servicetypes", "*.kdelnk");
00041 m_resourceList->add( "mime", "*.desktop" );
00042 m_resourceList->add( "mime", "*.kdelnk" );
00043 }
00044
00045
00046
00047 TQStringList KBuildServiceTypeFactory::resourceTypes()
00048 {
00049 return TQStringList() << "servicetypes" << "mime";
00050 }
00051
00052 KBuildServiceTypeFactory::~KBuildServiceTypeFactory()
00053 {
00054 delete m_resourceList;
00055 }
00056
00057 KServiceType * KBuildServiceTypeFactory::findServiceTypeByName(const TQString &_name)
00058 {
00059 assert (KSycoca::self()->isBuilding());
00060
00061 KSycocaEntry::Ptr * servType = (*m_entryDict)[ _name ];
00062 if (!servType)
00063 return 0;
00064 return (KServiceType *) ((KSycocaEntry*)*servType);
00065 }
00066
00067
00068 KSycocaEntry *
00069 KBuildServiceTypeFactory::createEntry(const TQString &file, const char *resource)
00070 {
00071 TQString name = file;
00072 int pos = name.findRev('/');
00073 if (pos != -1)
00074 {
00075 name = name.mid(pos+1);
00076 }
00077
00078 if (name.isEmpty())
00079 return 0;
00080
00081 KDesktopFile desktopFile(file, true, resource);
00082
00083 if ( desktopFile.readBoolEntry( "Hidden", false ) == true )
00084 return 0;
00085
00086
00087 TQString mime = desktopFile.readEntry( "MimeType" );
00088 TQString service = desktopFile.readEntry( "X-TDE-ServiceType" );
00089
00090 if ( mime.isEmpty() && service.isEmpty() )
00091 {
00092 TQString tmp = TQString("The service/mime type config file\n%1\n"
00093 "does not contain a ServiceType=...\nor MimeType=... entry").arg( file );
00094 kdWarning(7012) << tmp << endl;
00095 return 0;
00096 }
00097
00098 KServiceType* e;
00099 if ( mime == "inode/directory" )
00100 e = new KFolderType( &desktopFile );
00101 else if ( (mime == "application/x-desktop")
00102 || (mime == "media/builtin-mydocuments")
00103 || (mime == "media/builtin-mycomputer")
00104 || (mime == "media/builtin-mynetworkplaces")
00105 || (mime == "media/builtin-printers")
00106 || (mime == "media/builtin-trash")
00107 || (mime == "media/builtin-webbrowser") )
00108 e = new KDEDesktopMimeType( &desktopFile );
00109 else if ( mime == "application/x-executable" || mime == "application/x-shellscript" )
00110 e = new KExecMimeType( &desktopFile );
00111 else if ( !mime.isEmpty() )
00112 e = new KMimeType( &desktopFile );
00113 else
00114 e = new KServiceType( &desktopFile );
00115
00116 if (e->isDeleted())
00117 {
00118 delete e;
00119 return 0;
00120 }
00121
00122 if ( !(e->isValid()) )
00123 {
00124 kdWarning(7012) << "Invalid ServiceType : " << file << endl;
00125 delete e;
00126 return 0;
00127 }
00128
00129 return e;
00130 }
00131
00132 void
00133 KBuildServiceTypeFactory::saveHeader(TQDataStream &str)
00134 {
00135 KSycocaFactory::saveHeader(str);
00136 str << (TQ_INT32) m_fastPatternOffset;
00137 str << (TQ_INT32) m_otherPatternOffset;
00138 str << (TQ_INT32) m_propertyTypeDict.count();
00139
00140 TQMapIterator<TQString, int> it;
00141 for (it = m_propertyTypeDict.begin(); it != m_propertyTypeDict.end(); ++it)
00142 {
00143 str << it.key() << (TQ_INT32)it.data();
00144 }
00145
00146 }
00147
00148 void
00149 KBuildServiceTypeFactory::save(TQDataStream &str)
00150 {
00151 KSycocaFactory::save(str);
00152
00153 savePatternLists(str);
00154
00155 int endOfFactoryData = str.device()->at();
00156
00157
00158 saveHeader(str);
00159
00160
00161 str.device()->at(endOfFactoryData);
00162 }
00163
00164 void
00165 KBuildServiceTypeFactory::savePatternLists(TQDataStream &str)
00166 {
00167
00168 TQStringList fastPatterns;
00169 TQStringList otherPatterns;
00170 TQDict<KMimeType> dict;
00171
00172
00173 for(TQDictIterator<KSycocaEntry::Ptr> it ( *m_entryDict );
00174 it.current();
00175 ++it)
00176 {
00177 KSycocaEntry *entry = (*it.current());
00178 if ( entry->isType( KST_KMimeType ) )
00179 {
00180 KMimeType *mimeType = (KMimeType *) entry;
00181 TQStringList pat = mimeType->patterns();
00182 TQStringList::ConstIterator patit = pat.begin();
00183 for ( ; patit != pat.end() ; ++patit )
00184 {
00185 const TQString &pattern = *patit;
00186 if ( pattern.findRev('*') == 0
00187 && pattern.findRev('.') == 1
00188 && pattern.length() <= 6 )
00189
00190
00191 fastPatterns.append( pattern );
00192 else if (!pattern.isEmpty())
00193 otherPatterns.append( pattern );
00194
00195
00196 dict.replace( pattern, mimeType );
00197 }
00198 }
00199 }
00200
00201 fastPatterns.sort();
00202
00203 TQ_INT32 entrySize = 0;
00204 TQ_INT32 nrOfEntries = 0;
00205
00206 m_fastPatternOffset = str.device()->at();
00207
00208
00209 str.device()->at(m_fastPatternOffset);
00210 str << nrOfEntries;
00211 str << entrySize;
00212
00213
00214 TQStringList::ConstIterator it = fastPatterns.begin();
00215 for ( ; it != fastPatterns.end() ; ++it )
00216 {
00217 int start = str.device()->at();
00218
00219
00220 TQString paddedPattern = (*it).leftJustify(6).right(4);
00221
00222 str << paddedPattern;
00223 str << dict[(*it)]->offset();
00224 entrySize = str.device()->at() - start;
00225 nrOfEntries++;
00226 }
00227
00228
00229 m_otherPatternOffset = str.device()->at();
00230
00231
00232 str.device()->at(m_fastPatternOffset);
00233 str << nrOfEntries;
00234 str << entrySize;
00235
00236
00237 str.device()->at(m_otherPatternOffset);
00238
00239 it = otherPatterns.begin();
00240 for ( ; it != otherPatterns.end() ; ++it )
00241 {
00242
00243 str << (*it);
00244 str << dict[(*it)]->offset();
00245 }
00246
00247 str << TQString("");
00248 }
00249
00250 void
00251 KBuildServiceTypeFactory::addEntry(KSycocaEntry *newEntry, const char *resource)
00252 {
00253 KServiceType * serviceType = (KServiceType *) newEntry;
00254 if ( (*m_entryDict)[ newEntry->name() ] )
00255 {
00256
00257 if (serviceType->desktopEntryPath().endsWith("kdelnk"))
00258 return;
00259
00260
00261 KSycocaFactory::removeEntry(newEntry);
00262 }
00263 KSycocaFactory::addEntry(newEntry, resource);
00264
00265
00266 const TQMap<TQString,TQVariant::Type>& pd = serviceType->propertyDefs();
00267 TQMap<TQString,TQVariant::Type>::ConstIterator pit = pd.begin();
00268 for( ; pit != pd.end(); ++pit )
00269 {
00270 if (!m_propertyTypeDict.contains(pit.key()))
00271 m_propertyTypeDict.insert(pit.key(), pit.data());
00272 else if (m_propertyTypeDict[pit.key()] != pit.data())
00273 kdWarning(7021) << "Property '"<< pit.key() << "' is defined multiple times ("<< serviceType->name() <<")" <<endl;
00274 }
00275 }
00276