00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "kservice.h"
00021
#include "ksycoca.h"
00022
#include "kservicetype.h"
00023
#include "kservicetypefactory.h"
00024
#include "kservicefactory.h"
00025
#include "kuserprofile.h"
00026
#include <assert.h>
00027
#include <kdebug.h>
00028
#include <kdesktopfile.h>
00029
00030
template QDataStream& operator>> <QString, QVariant>(
QDataStream&,
QMap<QString, QVariant>&);
00031
template QDataStream& operator<< <QString, QVariant>(
QDataStream&,
const QMap<QString, QVariant>&);
00032
00033
class KServiceType::KServiceTypePrivate
00034 {
00035
public:
00036 KServiceTypePrivate() : parentTypeLoaded(false) { }
00037
00038 KServiceType::Ptr parentType;
00039 KService::List services;
00040
bool parentTypeLoaded;
00041 };
00042
00043 KServiceType::KServiceType(
const QString & _fullpath)
00044 :
KSycocaEntry(_fullpath), d(0)
00045 {
00046
KDesktopFile config( _fullpath );
00047
00048 init(&config);
00049 }
00050
00051 KServiceType::KServiceType(
KDesktopFile *config )
00052 :
KSycocaEntry(config->fileName()), d(0)
00053 {
00054 init(config);
00055 }
00056
00057
void
00058 KServiceType::init(
KDesktopFile *config)
00059 {
00060
00061 m_strName = config->
readEntry(
"MimeType" );
00062
00063
00064
if ( m_strName.isEmpty() )
00065 {
00066 m_strName = config->
readEntry(
"X-KDE-ServiceType" );
00067 }
00068
00069 m_strComment = config->
readComment();
00070
m_bDeleted = config->
readBoolEntry(
"Hidden",
false );
00071 m_strIcon = config->
readIcon();
00072
00073
00074
00075
QString sDerived = config->
readEntry(
"X-KDE-Derived" );
00076 m_bDerived = !sDerived.isEmpty();
00077
if ( m_bDerived )
00078 m_mapProps.insert(
"X-KDE-Derived", sDerived );
00079
00080
QStringList tmpList = config->
groupList();
00081 QStringList::Iterator gIt = tmpList.begin();
00082
00083
for( ; gIt != tmpList.end(); ++gIt )
00084 {
00085
if ( (*gIt).find(
"Property::" ) == 0 )
00086 {
00087 config->
setGroup( *gIt );
00088
QVariant v = config->
readPropertyEntry(
"Value",
00089 QVariant::nameToType( config->
readEntry(
"Type" ).ascii() ) );
00090
if ( v.isValid() )
00091 m_mapProps.insert( (*gIt).mid( 10 ), v );
00092 }
00093 }
00094
00095 gIt = tmpList.begin();
00096
for( ; gIt != tmpList.end(); ++gIt )
00097 {
00098
if( (*gIt).find(
"PropertyDef::" ) == 0 )
00099 {
00100 config->
setGroup( *gIt );
00101 m_mapPropDefs.insert( (*gIt).mid( 13 ),
00102 QVariant::nameToType( config->
readEntry(
"Type" ).ascii() ) );
00103 }
00104 }
00105
00106 m_bValid = !m_strName.isEmpty();
00107 }
00108
00109 KServiceType::KServiceType(
const QString & _fullpath,
const QString& _type,
00110
const QString& _icon,
const QString& _comment )
00111 :
KSycocaEntry(_fullpath), d(0)
00112 {
00113 m_strName = _type;
00114 m_strIcon = _icon;
00115 m_strComment = _comment;
00116 m_bValid = !m_strName.isEmpty();
00117 }
00118
00119 KServiceType::KServiceType(
QDataStream& _str,
int offset )
00120 :
KSycocaEntry( _str, offset ), d(0)
00121 {
00122 load( _str);
00123 }
00124
00125
void
00126 KServiceType::load(
QDataStream& _str )
00127 {
00128 Q_INT8 b;
00129 _str >> m_strName >> m_strIcon >> m_strComment >> m_mapProps >> m_mapPropDefs
00130 >> b;
00131 m_bValid = b;
00132 m_bDerived = m_mapProps.contains(
"X-KDE-Derived");
00133 }
00134
00135
void
00136 KServiceType::save(
QDataStream& _str )
00137 {
00138
KSycocaEntry::save( _str );
00139
00140
00141
00142 _str << m_strName << m_strIcon << m_strComment << m_mapProps << m_mapPropDefs
00143 << (Q_INT8)m_bValid;
00144 }
00145
00146 KServiceType::~KServiceType()
00147 {
00148
delete d;
00149 }
00150
00151 QString KServiceType::parentServiceType()
const
00152
{
00153
QVariant v =
property(
"X-KDE-Derived");
00154
return v.toString();
00155 }
00156
00157 bool KServiceType::inherits(
const QString& servTypeName )
const
00158
{
00159
if (
name() == servTypeName )
00160
return true;
00161
QString st =
parentServiceType();
00162
while ( !st.isEmpty() )
00163 {
00164
KServiceType::Ptr ptr =
KServiceType::serviceType( st );
00165
if (!ptr)
return false;
00166
if ( ptr->name() == servTypeName )
00167
return true;
00168 st = ptr->parentServiceType();
00169 }
00170
return false;
00171 }
00172
00173
QVariant
00174 KServiceType::property(
const QString& _name )
const
00175
{
00176
QVariant v;
00177
00178
if ( _name ==
"Name" )
00179 v =
QVariant( m_strName );
00180
else if ( _name ==
"Icon" )
00181 v = QVariant( m_strIcon );
00182
else if ( _name ==
"Comment" )
00183 v = QVariant( m_strComment );
00184
else {
00185
QMap<QString,QVariant>::ConstIterator it = m_mapProps.find( _name );
00186
if ( it != m_mapProps.end() )
00187 v = it.data();
00188 }
00189
00190
return v;
00191 }
00192
00193
QStringList
00194 KServiceType::propertyNames()
const
00195
{
00196
QStringList res;
00197
00198
QMap<QString,QVariant>::ConstIterator it = m_mapProps.begin();
00199
for( ; it != m_mapProps.end(); ++it )
00200 res.append( it.key() );
00201
00202 res.append(
"Name" );
00203 res.append(
"Comment" );
00204 res.append(
"Icon" );
00205
00206
return res;
00207 }
00208
00209 QVariant::Type
00210 KServiceType::propertyDef(
const QString& _name )
const
00211
{
00212
QMap<QString,QVariant::Type>::ConstIterator it = m_mapPropDefs.find( _name );
00213
if ( it == m_mapPropDefs.end() )
00214
return QVariant::Invalid;
00215
return it.data();
00216 }
00217
00218
QStringList
00219 KServiceType::propertyDefNames()
const
00220
{
00221
QStringList l;
00222
00223
QMap<QString,QVariant::Type>::ConstIterator it = m_mapPropDefs.begin();
00224
for( ; it != m_mapPropDefs.end(); ++it )
00225 l.append( it.key() );
00226
00227
return l;
00228 }
00229
00230 KServiceType::Ptr KServiceType::serviceType(
const QString& _name )
00231 {
00232
KServiceType * p = KServiceTypeFactory::self()->findServiceTypeByName( _name );
00233
return KServiceType::Ptr( p );
00234 }
00235
00236
static void addUnique(KService::List &lst,
QDict<KService> &dict,
const KService::List &newLst,
bool lowPrio)
00237 {
00238
QValueListConstIterator<KService::Ptr> it = newLst.begin();
00239
for( ; it != newLst.end(); ++it )
00240 {
00241
KService *service = static_cast<KService*>(*it);
00242
if (dict.find(service->
desktopEntryPath()))
00243
continue;
00244 dict.insert(service->
desktopEntryPath(), service);
00245 lst.append(service);
00246
if (lowPrio)
00247 service->
setInitialPreference( 0 );
00248 }
00249 }
00250
00251 KService::List KServiceType::offers(
const QString& _servicetype )
00252 {
00253
QDict<KService> dict(53);
00254
KService::List lst;
00255
00256
00257
KServiceType::Ptr serv = KServiceTypeFactory::self()->findServiceTypeByName( _servicetype );
00258
if ( serv )
00259 addUnique(lst, dict, KServiceFactory::self()->
offers( serv->offset() ),
false);
00260
else
00261
kdWarning(7009) <<
"KServiceType::offers : servicetype " << _servicetype <<
" not found" <<
endl;
00262
00263
00264
KMimeType::Ptr mime = dynamic_cast<KMimeType*>(static_cast<KServiceType *>(serv));
00265
bool isAMimeType = (mime != 0);
00266
if (mime)
00267 {
00268
while(
true)
00269 {
00270
QString parent = mime->parentMimeType();
00271
if (parent.isEmpty())
00272
break;
00273 mime = dynamic_cast<KMimeType *>(KServiceTypeFactory::self()->findServiceTypeByName( parent ));
00274
if (!mime)
00275
break;
00276
00277 addUnique(lst, dict, KServiceFactory::self()->
offers( mime->offset() ),
false);
00278 }
00279 }
00280 serv = mime = 0;
00281
00282
00283
00284
00285
00286
00287
00288
00289
if ( !KServiceTypeProfile::configurationMode()
00290 && isAMimeType
00291 && _servicetype.left(4) !=
"all/" )
00292 {
00293
00294
KServiceType * servAll = KServiceTypeFactory::self()->findServiceTypeByName(
"all/all" );
00295
if ( servAll )
00296 {
00297 addUnique(lst, dict, KServiceFactory::self()->
offers( servAll->
offset() ),
true);
00298 }
00299
else
00300
kdWarning(7009) <<
"KServiceType::offers : servicetype all/all not found" <<
endl;
00301
delete servAll;
00302
00303
00304
if ( _servicetype !=
"inode/directory" && _servicetype !=
"inode/directory-locked" )
00305 {
00306
KServiceType * servAllFiles = KServiceTypeFactory::self()->findServiceTypeByName(
"all/allfiles" );
00307
if ( servAllFiles )
00308 {
00309 addUnique(lst, dict, KServiceFactory::self()->
offers( servAllFiles->
offset() ),
true);
00310 }
00311
else
00312
kdWarning(7009) <<
"KServiceType::offers : servicetype all/allfiles not found" <<
endl;
00313
delete servAllFiles;
00314 }
00315 }
00316
00317
return lst;
00318 }
00319
00320 KServiceType::List KServiceType::allServiceTypes()
00321 {
00322
return KServiceTypeFactory::self()->allServiceTypes();
00323 }
00324
00325 KServiceType::Ptr KServiceType::parentType()
00326 {
00327
if (d && d->parentTypeLoaded)
00328
return d->parentType;
00329
00330
if (!d)
00331 d =
new KServiceTypePrivate;
00332
00333
QString parentSt =
parentServiceType();
00334
if (!parentSt.isEmpty())
00335 {
00336 d->parentType = KServiceTypeFactory::self()->findServiceTypeByName( parentSt );
00337
if (!d->parentType)
00338
kdDebug(7009) <<
"'" <<
desktopEntryPath() <<
"' specifies undefined mimetype/servicetype '"<< parentSt <<
"'" <<
endl;
00339 }
00340
00341 d->parentTypeLoaded =
true;
00342
00343
return d->parentType;
00344 }
00345
00346
void KServiceType::addService(KService::Ptr service)
00347 {
00348
if (!d)
00349 d =
new KServiceTypePrivate;
00350
00351
if (d->services.count() && d->services.last() == service)
00352
return;
00353
00354 d->services.append(service);
00355 }
00356
00357 KService::List KServiceType::services()
00358 {
00359
if (d)
00360
return d->services;
00361
00362
return KService::List();
00363 }
00364
00365
void KServiceType::virtual_hook(
int id,
void* data )
00366 {
KSycocaEntry::virtual_hook(
id, data ); }