kio
kservicetypefactory.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 "kservicetypefactory.h"
00020 #include "ksycoca.h"
00021 #include "ksycocatype.h"
00022 #include "ksycocadict.h"
00023 #include "kservicetype.h"
00024 #include "kmimetype.h"
00025 #include "kuserprofile.h"
00026
00027 #include <kapplication.h>
00028 #include <kdebug.h>
00029 #include <assert.h>
00030 #include <kstringhandler.h>
00031 #include <qfile.h>
00032
00033 KServiceTypeFactory::KServiceTypeFactory()
00034 : KSycocaFactory( KST_KServiceTypeFactory )
00035 {
00036 _self = this;
00037 m_fastPatternOffset = 0;
00038 m_otherPatternOffset = 0;
00039 if (m_str)
00040 {
00041
00042 Q_INT32 i,n;
00043 (*m_str) >> i;
00044 m_fastPatternOffset = i;
00045 (*m_str) >> i;
00046 m_otherPatternOffset = i;
00047 (*m_str) >> n;
00048
00049 if (n > 1024)
00050 {
00051 KSycoca::flagError();
00052 }
00053 else
00054 {
00055 QString str;
00056 for(;n;n--)
00057 {
00058 KSycocaEntry::read(*m_str, str);
00059 (*m_str) >> i;
00060 m_propertyTypeDict.insert(str, i);
00061 }
00062 }
00063 }
00064 }
00065
00066
00067 KServiceTypeFactory::~KServiceTypeFactory()
00068 {
00069 _self = 0L;
00070 KServiceTypeProfile::clear();
00071 }
00072
00073 KServiceTypeFactory * KServiceTypeFactory::self()
00074 {
00075 if (!_self)
00076 _self = new KServiceTypeFactory();
00077 return _self;
00078 }
00079
00080 KServiceType * KServiceTypeFactory::findServiceTypeByName(const QString &_name)
00081 {
00082 if (!m_sycocaDict) return 0L;
00083 assert (!KSycoca::self()->isBuilding());
00084 int offset = m_sycocaDict->find_string( _name );
00085 if (!offset) return 0;
00086 KServiceType * newServiceType = createEntry(offset);
00087
00088
00089 if (newServiceType && (newServiceType->name() != _name))
00090 {
00091
00092 delete newServiceType;
00093 newServiceType = 0;
00094 }
00095 return newServiceType;
00096 }
00097
00098 QVariant::Type KServiceTypeFactory::findPropertyTypeByName(const QString &_name)
00099 {
00100 if (!m_sycocaDict)
00101 return QVariant::Invalid;
00102
00103 assert (!KSycoca::self()->isBuilding());
00104
00105 QMapConstIterator<QString,int> it = m_propertyTypeDict.find(_name);
00106 if (it != m_propertyTypeDict.end()) {
00107 return (QVariant::Type)it.data();
00108 }
00109
00110 return QVariant::Invalid;
00111 }
00112
00113 KMimeType * KServiceTypeFactory::findFromPattern(const QString &_filename, QString *match)
00114 {
00115
00116 if (!m_str) return 0;
00117
00118
00119 QDataStream *str = m_str;
00120
00121 str->device()->at( m_fastPatternOffset );
00122
00123 Q_INT32 nrOfEntries;
00124 (*str) >> nrOfEntries;
00125 Q_INT32 entrySize;
00126 (*str) >> entrySize;
00127
00128 Q_INT32 fastOffset = str->device()->at( );
00129
00130 Q_INT32 matchingOffset = 0;
00131
00132
00133 Q_INT32 left = 0;
00134 Q_INT32 right = nrOfEntries - 1;
00135 Q_INT32 middle;
00136
00137 int lastDot = _filename.findRev('.');
00138 int ext_len = _filename.length() - lastDot - 1;
00139 if (lastDot != -1 && ext_len <= 4)
00140 {
00141 QString extension = _filename.right( ext_len );
00142 extension = extension.leftJustify(4);
00143
00144 QString pattern;
00145 while (left <= right) {
00146 middle = (left + right) / 2;
00147
00148 str->device()->at( middle * entrySize + fastOffset );
00149 KSycocaEntry::read(*str, pattern);
00150 int cmp = pattern.compare( extension );
00151 if (cmp < 0)
00152 left = middle + 1;
00153 else if (cmp == 0)
00154 {
00155 (*str) >> matchingOffset;
00156
00157
00158 if (match)
00159 *match = "*."+pattern.stripWhiteSpace();
00160 break;
00161 }
00162 else
00163 right = middle - 1;
00164 }
00165 }
00166
00167
00168 if ( m_patterns.isEmpty() ) {
00169 str->device()->at( m_otherPatternOffset );
00170
00171 QString pattern;
00172 Q_INT32 mimetypeOffset;
00173
00174 while (true)
00175 {
00176 KSycocaEntry::read(*str, pattern);
00177 if (pattern.isEmpty())
00178 break;
00179 (*str) >> mimetypeOffset;
00180 m_patterns.push_back( pattern );
00181 m_pattern_offsets.push_back( mimetypeOffset );
00182 }
00183 }
00184
00185 assert( m_patterns.size() == m_pattern_offsets.size() );
00186
00187 QStringList::const_iterator it = m_patterns.begin();
00188 QStringList::const_iterator end = m_patterns.end();
00189 QValueVector<Q_INT32>::const_iterator it_offset = m_pattern_offsets.begin();
00190
00191 for ( ; it != end; ++it, ++it_offset )
00192 {
00193 if ( KStringHandler::matchFileName( _filename, *it ) )
00194 {
00195 if ( !matchingOffset || !(*it).endsWith( "*" ) )
00196 {
00197 matchingOffset = *it_offset;
00198 if (match)
00199 *match = *it;
00200 break;
00201 }
00202 }
00203 }
00204
00205 if ( matchingOffset ) {
00206 KServiceType *newServiceType = createEntry( matchingOffset );
00207 assert (newServiceType && newServiceType->isType( KST_KMimeType ));
00208 return (KMimeType *) newServiceType;
00209 }
00210 else
00211 return 0;
00212 }
00213
00214 KMimeType::List KServiceTypeFactory::allMimeTypes()
00215 {
00216 KMimeType::List result;
00217 KSycocaEntry::List list = allEntries();
00218 for( KSycocaEntry::List::Iterator it = list.begin();
00219 it != list.end();
00220 ++it)
00221 {
00222 KMimeType *newMimeType = dynamic_cast<KMimeType *>((*it).data());
00223 if (newMimeType)
00224 result.append( KMimeType::Ptr( newMimeType ) );
00225 }
00226 return result;
00227 }
00228
00229 KServiceType::List KServiceTypeFactory::allServiceTypes()
00230 {
00231 KServiceType::List result;
00232 KSycocaEntry::List list = allEntries();
00233 for( KSycocaEntry::List::Iterator it = list.begin();
00234 it != list.end();
00235 ++it)
00236 {
00237 #ifndef Q_WS_QWS
00238 KServiceType *newServiceType = dynamic_cast<KServiceType *>((*it).data());
00239 #else //FIXME
00240 KServiceType *newServiceType = (KServiceType*)(*it).data();
00241 #endif
00242 if (newServiceType)
00243 result.append( KServiceType::Ptr( newServiceType ) );
00244 }
00245 return result;
00246 }
00247
00248 bool KServiceTypeFactory::checkMimeTypes()
00249 {
00250 QDataStream *str = KSycoca::self()->findFactory( factoryId() );
00251 if (!str) return false;
00252
00253
00254 return (m_beginEntryOffset != m_endEntryOffset);
00255 }
00256
00257 KServiceType * KServiceTypeFactory::createEntry(int offset)
00258 {
00259 KServiceType *newEntry = 0;
00260 KSycocaType type;
00261 QDataStream *str = KSycoca::self()->findEntry(offset, type);
00262 if (!str) return 0;
00263
00264 switch(type)
00265 {
00266 case KST_KServiceType:
00267 newEntry = new KServiceType(*str, offset);
00268 break;
00269 case KST_KMimeType:
00270 newEntry = new KMimeType(*str, offset);
00271 break;
00272 case KST_KFolderType:
00273 newEntry = new KFolderType(*str, offset);
00274 break;
00275 case KST_KDEDesktopMimeType:
00276 newEntry = new KDEDesktopMimeType(*str, offset);
00277 break;
00278 case KST_KExecMimeType:
00279 newEntry = new KExecMimeType(*str, offset);
00280 break;
00281
00282 default:
00283 kdError(7011) << QString("KServiceTypeFactory: unexpected object entry in KSycoca database (type = %1)").arg((int)type) << endl;
00284 break;
00285 }
00286 if (newEntry && !newEntry->isValid())
00287 {
00288 kdError(7011) << "KServiceTypeFactory: corrupt object in KSycoca database!\n" << endl;
00289 delete newEntry;
00290 newEntry = 0;
00291 }
00292 return newEntry;
00293 }
00294
00295 KServiceTypeFactory *KServiceTypeFactory::_self = 0;
00296
00297 void KServiceTypeFactory::virtual_hook( int id, void* data )
00298 { KSycocaFactory::virtual_hook( id, data ); }
00299
00300