kio Library API Documentation

kservicetype.cpp

00001 /* This file is part of the KDE libraries 00002 * Copyright (C) 1999 Waldo Bastian <bastian@kde.org> 00003 * David Faure <faure@kde.org> 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Library General Public 00007 * License version 2 as published by the Free Software Foundation; 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Library General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Library General Public License 00015 * along with this library; see the file COPYING.LIB. If not, write to 00016 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00017 * Boston, MA 02111-1307, USA. 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 // Is it a mimetype ? 00061 m_strName = config->readEntry( "MimeType" ); 00062 00063 // Or is it a servicetype ? 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 // We store this as property to preserve BC, we can't change that 00074 // because KSycoca needs to remain BC between KDE 2.x and KDE 3.x 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 // !! This data structure should remain binary compatible at all times !! 00140 // You may add new fields at the end. Make sure to update the version 00141 // number in ksycoca.h 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; //error 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 // Services associated directly with this servicetype (the normal case) 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 // Find services associated with any mimetype parents. e.g. text/x-java -> text/plain 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 //QValueListIterator<KService::Ptr> it = lst.begin(); 00283 //for( ; it != lst.end(); ++it ) 00284 // kdDebug() << (*it).data() << " " << (*it)->name() << endl; 00285 00286 // Support for all/* is deactivated by KServiceTypeProfile::configurationMode() 00287 // (and makes no sense when querying for an "all" servicetype itself 00288 // nor for non-mimetypes service types) 00289 if ( !KServiceTypeProfile::configurationMode() 00290 && isAMimeType 00291 && _servicetype.left(4) != "all/" ) 00292 { 00293 // Support for services associated with "all" 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 // Support for services associated with "allfiles" 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 ); }
KDE Logo
This file is part of the documentation for kio Library Version 3.3.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 17 11:29:29 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003