kio
kservicetype.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
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 kdWarning(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 ); }