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;
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 matchingOffset = *it_offset;
00196
if (match)
00197 *match = *it;
00198
break;
00199 }
00200 }
00201
00202
if ( matchingOffset ) {
00203
KServiceType *newServiceType = createEntry( matchingOffset );
00204 assert (newServiceType && newServiceType->
isType( KST_KMimeType ));
00205
return (
KMimeType *) newServiceType;
00206 }
00207
else
00208
return 0;
00209 }
00210
00211 KMimeType::List KServiceTypeFactory::allMimeTypes()
00212 {
00213 KMimeType::List result;
00214
KSycocaEntry::List list = allEntries();
00215
for( KSycocaEntry::List::Iterator it = list.begin();
00216 it != list.end();
00217 ++it)
00218 {
00219
KMimeType *newMimeType = dynamic_cast<KMimeType *>((*it).data());
00220
if (newMimeType)
00221 result.append( KMimeType::Ptr( newMimeType ) );
00222 }
00223
return result;
00224 }
00225
00226 KServiceType::List KServiceTypeFactory::allServiceTypes()
00227 {
00228 KServiceType::List result;
00229
KSycocaEntry::List list = allEntries();
00230
for( KSycocaEntry::List::Iterator it = list.begin();
00231 it != list.end();
00232 ++it)
00233 {
00234
#ifndef Q_WS_QWS
00235
KServiceType *newServiceType = dynamic_cast<KServiceType *>((*it).data());
00236
#else //FIXME
00237
KServiceType *newServiceType = (
KServiceType*)(*it).data();
00238
#endif
00239
if (newServiceType)
00240 result.append( KServiceType::Ptr( newServiceType ) );
00241 }
00242
return result;
00243 }
00244
00245
bool KServiceTypeFactory::checkMimeTypes()
00246 {
00247
QDataStream *str = KSycoca::self()->findFactory( factoryId() );
00248
if (!str)
return false;
00249
00250
00251
return (m_beginEntryOffset != m_endEntryOffset);
00252 }
00253
00254
KServiceType * KServiceTypeFactory::createEntry(
int offset)
00255 {
00256
KServiceType *newEntry = 0;
00257 KSycocaType type;
00258
QDataStream *str = KSycoca::self()->findEntry(offset, type);
00259
if (!str)
return 0;
00260
00261
switch(type)
00262 {
00263
case KST_KServiceType:
00264 newEntry =
new KServiceType(*str, offset);
00265
break;
00266
case KST_KMimeType:
00267 newEntry =
new KMimeType(*str, offset);
00268
break;
00269
case KST_KFolderType:
00270 newEntry =
new KFolderType(*str, offset);
00271
break;
00272
case KST_KDEDesktopMimeType:
00273 newEntry =
new KDEDesktopMimeType(*str, offset);
00274
break;
00275
case KST_KExecMimeType:
00276 newEntry =
new KExecMimeType(*str, offset);
00277
break;
00278
00279
default:
00280
kdError(7011) <<
QString(
"KServiceTypeFactory: unexpected object entry in KSycoca database (type = %1)").arg((
int)type) <<
endl;
00281
break;
00282 }
00283
if (!newEntry->
isValid())
00284 {
00285
kdError(7011) <<
"KServiceTypeFactory: corrupt object in KSycoca database!\n" <<
endl;
00286
delete newEntry;
00287 newEntry = 0;
00288 }
00289
return newEntry;
00290 }
00291
00292 KServiceTypeFactory *KServiceTypeFactory::_self = 0;
00293
00294
void KServiceTypeFactory::virtual_hook(
int id,
void* data )
00295 { KSycocaFactory::virtual_hook(
id, data ); }
00296
00297