KDED
kbuildservicetypefactory.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "kbuildservicetypefactory.h"
00020 #include "ksycoca.h"
00021 #include "ksycocadict.h"
00022 #include "kresourcelist.h"
00023
00024 #include <kglobal.h>
00025 #include <kstandarddirs.h>
00026 #include <kmessageboxwrapper.h>
00027 #include <kdebug.h>
00028 #include <klocale.h>
00029 #include <assert.h>
00030 #include <kdesktopfile.h>
00031
00032 template class QDict<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 QStringList KBuildServiceTypeFactory::resourceTypes()
00048 {
00049 return QStringList() << "servicetypes" << "mime";
00050 }
00051
00052 KBuildServiceTypeFactory::~KBuildServiceTypeFactory()
00053 {
00054 delete m_resourceList;
00055 }
00056
00057 KServiceType * KBuildServiceTypeFactory::findServiceTypeByName(const QString &_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 QString &file, const char *resource)
00070 {
00071 QString 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 QString mime = desktopFile.readEntry( "MimeType" );
00088 QString service = desktopFile.readEntry( "X-KDE-ServiceType" );
00089
00090 if ( mime.isEmpty() && service.isEmpty() )
00091 {
00092 QString tmp = QString("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 e = new KDEDesktopMimeType( &desktopFile );
00103 else if ( mime == "application/x-executable" || mime == "application/x-shellscript" )
00104 e = new KExecMimeType( &desktopFile );
00105 else if ( !mime.isEmpty() )
00106 e = new KMimeType( &desktopFile );
00107 else
00108 e = new KServiceType( &desktopFile );
00109
00110 if (e->isDeleted())
00111 {
00112 delete e;
00113 return 0;
00114 }
00115
00116 if ( !(e->isValid()) )
00117 {
00118 kdWarning(7012) << "Invalid ServiceType : " << file << endl;
00119 delete e;
00120 return 0;
00121 }
00122
00123 return e;
00124 }
00125
00126 void
00127 KBuildServiceTypeFactory::saveHeader(QDataStream &str)
00128 {
00129 KSycocaFactory::saveHeader(str);
00130 str << (Q_INT32) m_fastPatternOffset;
00131 str << (Q_INT32) m_otherPatternOffset;
00132 str << (Q_INT32) m_propertyTypeDict.count();
00133
00134 QMapIterator<QString, int> it;
00135 for (it = m_propertyTypeDict.begin(); it != m_propertyTypeDict.end(); ++it)
00136 {
00137 str << it.key() << (Q_INT32)it.data();
00138 }
00139
00140 }
00141
00142 void
00143 KBuildServiceTypeFactory::save(QDataStream &str)
00144 {
00145 KSycocaFactory::save(str);
00146
00147 savePatternLists(str);
00148
00149 int endOfFactoryData = str.device()->at();
00150
00151
00152 saveHeader(str);
00153
00154
00155 str.device()->at(endOfFactoryData);
00156 }
00157
00158 void
00159 KBuildServiceTypeFactory::savePatternLists(QDataStream &str)
00160 {
00161
00162 QStringList fastPatterns;
00163 QStringList otherPatterns;
00164 QDict<KMimeType> dict;
00165
00166
00167 for(QDictIterator<KSycocaEntry::Ptr> it ( *m_entryDict );
00168 it.current();
00169 ++it)
00170 {
00171 KSycocaEntry *entry = (*it.current());
00172 if ( entry->isType( KST_KMimeType ) )
00173 {
00174 KMimeType *mimeType = (KMimeType *) entry;
00175 QStringList pat = mimeType->patterns();
00176 QStringList::ConstIterator patit = pat.begin();
00177 for ( ; patit != pat.end() ; ++patit )
00178 {
00179 const QString &pattern = *patit;
00180 if ( pattern.findRev('*') == 0
00181 && pattern.findRev('.') == 1
00182 && pattern.length() <= 6 )
00183
00184
00185 fastPatterns.append( pattern );
00186 else if (!pattern.isEmpty())
00187 otherPatterns.append( pattern );
00188
00189
00190 dict.replace( pattern, mimeType );
00191 }
00192 }
00193 }
00194
00195 fastPatterns.sort();
00196
00197 Q_INT32 entrySize = 0;
00198 Q_INT32 nrOfEntries = 0;
00199
00200 m_fastPatternOffset = str.device()->at();
00201
00202
00203 str.device()->at(m_fastPatternOffset);
00204 str << nrOfEntries;
00205 str << entrySize;
00206
00207
00208 QStringList::ConstIterator it = fastPatterns.begin();
00209 for ( ; it != fastPatterns.end() ; ++it )
00210 {
00211 int start = str.device()->at();
00212
00213
00214 QString paddedPattern = (*it).leftJustify(6).right(4);
00215
00216 str << paddedPattern;
00217 str << dict[(*it)]->offset();
00218 entrySize = str.device()->at() - start;
00219 nrOfEntries++;
00220 }
00221
00222
00223 m_otherPatternOffset = str.device()->at();
00224
00225
00226 str.device()->at(m_fastPatternOffset);
00227 str << nrOfEntries;
00228 str << entrySize;
00229
00230
00231 str.device()->at(m_otherPatternOffset);
00232
00233 it = otherPatterns.begin();
00234 for ( ; it != otherPatterns.end() ; ++it )
00235 {
00236
00237 str << (*it);
00238 str << dict[(*it)]->offset();
00239 }
00240
00241 str << QString("");
00242 }
00243
00244 void
00245 KBuildServiceTypeFactory::addEntry(KSycocaEntry *newEntry, const char *resource)
00246 {
00247 KServiceType * serviceType = (KServiceType *) newEntry;
00248 if ( (*m_entryDict)[ newEntry->name() ] )
00249 {
00250
00251 if (serviceType->desktopEntryPath().endsWith("kdelnk"))
00252 return;
00253
00254
00255 KSycocaFactory::removeEntry(newEntry);
00256 }
00257 KSycocaFactory::addEntry(newEntry, resource);
00258
00259
00260 const QMap<QString,QVariant::Type>& pd = serviceType->propertyDefs();
00261 QMap<QString,QVariant::Type>::ConstIterator pit = pd.begin();
00262 for( ; pit != pd.end(); ++pit )
00263 {
00264 if (!m_propertyTypeDict.contains(pit.key()))
00265 m_propertyTypeDict.insert(pit.key(), pit.data());
00266 else if (m_propertyTypeDict[pit.key()] != pit.data())
00267 kdWarning(7021) << "Property '"<< pit.key() << "' is defined multiple times ("<< serviceType->name() <<")" <<endl;
00268 }
00269 }
00270