kio Library API Documentation

kuserprofile.cpp

00001 /* This file is part of the KDE libraries 00002 * Copyright (C) 1999 Torben Weis <weis@kde.org> 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Library General Public 00006 * License version 2 as published by the Free Software Foundation; 00007 * 00008 * This library is distributed in the hope that it will be useful, 00009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 * Library General Public License for more details. 00012 * 00013 * You should have received a copy of the GNU Library General Public License 00014 * along with this library; see the file COPYING.LIB. If not, write to 00015 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00016 * Boston, MA 02111-1307, USA. 00017 **/ 00018 00019 #include "kuserprofile.h" 00020 #include "kservice.h" 00021 #include "kservicetype.h" 00022 #include "kservicetypefactory.h" 00023 00024 #include <kconfig.h> 00025 #include <kapplication.h> 00026 #include <kglobal.h> 00027 #include <kdebug.h> 00028 #include <kstaticdeleter.h> 00029 00030 #include <qtl.h> 00031 00032 template class QPtrList<KServiceTypeProfile>; 00033 typedef QPtrList<KServiceTypeProfile> KServiceTypeProfileList; 00034 00035 /********************************************* 00036 * 00037 * KServiceTypeProfile 00038 * 00039 *********************************************/ 00040 00041 KServiceTypeProfileList* KServiceTypeProfile::s_lstProfiles = 0L; 00042 static KStaticDeleter< KServiceTypeProfileList > profileDeleter; 00043 bool KServiceTypeProfile::s_configurationMode = false; 00044 00045 void KServiceTypeProfile::initStatic() 00046 { 00047 if ( s_lstProfiles ) 00048 return; 00049 00050 // Make sure that a KServiceTypeFactory gets created. 00051 (void) KServiceTypeFactory::self(); 00052 00053 profileDeleter.setObject(s_lstProfiles, new KServiceTypeProfileList); 00054 s_lstProfiles->setAutoDelete( true ); 00055 00056 KConfig config( "profilerc", true, false); 00057 00058 static const QString & defaultGroup = KGlobal::staticQString("<default>"); 00059 00060 QStringList tmpList = config.groupList(); 00061 for (QStringList::Iterator aIt = tmpList.begin(); 00062 aIt != tmpList.end(); ++aIt) { 00063 if ( *aIt == defaultGroup ) 00064 continue; 00065 00066 config.setGroup( *aIt ); 00067 00068 QString appId = config.readEntry( "Application" ); 00069 00070 KService::Ptr pService = KService::serviceByStorageId(appId); 00071 00072 if ( pService ) { 00073 QString application = pService->name(); 00074 QString type = config.readEntry( "ServiceType" ); 00075 QString type2 = config.readEntry( "GenericServiceType" ); 00076 if (type2.isEmpty()) // compat code 00077 type2 = (pService->type() == "Application") ? "Application" : "KParts/ReadOnlyPart"; 00078 int pref = config.readNumEntry( "Preference" ); 00079 00080 if ( !type.isEmpty() /* && pref >= 0*/ ) // Don't test for pref here. We want those in the list, to mark them as forbidden 00081 { 00082 KServiceTypeProfile* p = 00083 KServiceTypeProfile::serviceTypeProfile( type, type2 ); 00084 00085 if ( !p ) { 00086 p = new KServiceTypeProfile( type, type2 ); 00087 s_lstProfiles->append( p ); 00088 } 00089 00090 bool allow = config.readBoolEntry( "AllowAsDefault" ); 00091 //kdDebug(7014) << "KServiceTypeProfile::initStatic adding service " << application << " to profile for " << type << "," << type2 << " with preference " << pref << endl; 00092 p->addService( application, pref, allow ); 00093 } 00094 } 00095 } 00096 } 00097 00098 //static 00099 void KServiceTypeProfile::clear() 00100 { 00101 profileDeleter.destructObject(); 00102 } 00103 00104 //static 00105 KServiceTypeProfile::OfferList KServiceTypeProfile::offers( const QString& _servicetype, const QString& _genericServiceType ) 00106 { 00107 OfferList offers; 00108 QStringList serviceList; 00109 kdDebug(7014) << "KServiceTypeProfile::offers( " << _servicetype << "," << _genericServiceType << " )" << endl; 00110 00111 // Note that KServiceTypeProfile::offers() calls KServiceType::offers(), 00112 // so we _do_ get the new services, that are available but not in the profile. 00113 if ( _genericServiceType.isEmpty() ) 00114 { 00115 initStatic(); 00116 // We want all profiles for servicetype, if we have profiles. 00117 // ## Slow loop, if profilerc is big. We should use a map instead? 00118 QPtrListIterator<KServiceTypeProfile> it( *s_lstProfiles ); 00119 for( ; it.current(); ++it ) 00120 if ( it.current()->m_strServiceType == _servicetype ) 00121 { 00122 offers += it.current()->offers(); 00123 } 00124 //kdDebug(7014) << "Found profile: " << offers.count() << " offers" << endl; 00125 } 00126 else 00127 { 00128 KServiceTypeProfile* profile = serviceTypeProfile( _servicetype, _genericServiceType ); 00129 if ( profile ) 00130 { 00131 //kdDebug(7014) << "Found profile: " << profile->offers().count() << " offers" << endl; 00132 offers += profile->offers(); 00133 } 00134 else 00135 { 00136 // Try the other way round, order is not like size, it doesn't matter. 00137 profile = serviceTypeProfile( _genericServiceType, _servicetype ); 00138 if ( profile ) 00139 { 00140 //kdDebug(7014) << "Found profile after switching: " << profile->offers().count() << " offers" << endl; 00141 offers += profile->offers(); 00142 } 00143 } 00144 } 00145 00146 // Collect services, to make the next loop faster 00147 OfferList::Iterator itOffers = offers.begin(); 00148 for( ; itOffers != offers.end(); ++itOffers ) 00149 serviceList += (*itOffers).service()->desktopEntryPath(); // this should identify each service uniquely 00150 //kdDebug(7014) << "serviceList: " << serviceList.join(",") << endl; 00151 00152 // Now complete with any other offers that aren't in the profile 00153 // This can be because the services have been installed after the profile was written, 00154 // but it's also the case for any service that's neither App nor ReadOnlyPart, e.g. RenameDlg/Plugin 00155 KService::List list = KServiceType::offers( _servicetype ); 00156 //kdDebug(7014) << "Using KServiceType::offers, result: " << list.count() << " offers" << endl; 00157 QValueListIterator<KService::Ptr> it = list.begin(); 00158 for( ; it != list.end(); ++it ) 00159 { 00160 if (_genericServiceType.isEmpty() /*no constraint*/ || (*it)->hasServiceType( _genericServiceType )) 00161 { 00162 // Check that we don't already have it ;) 00163 if ( serviceList.find( (*it)->desktopEntryPath() ) == serviceList.end() ) 00164 { 00165 bool allow = (*it)->allowAsDefault(); 00166 KServiceOffer o( (*it), (*it)->initialPreferenceForMimeType(_servicetype), allow ); 00167 offers.append( o ); 00168 //kdDebug(7014) << "Appending offer " << (*it)->name() << " initial preference=" << (*it)->initialPreference() << " allow-as-default=" << allow << endl; 00169 } 00170 //else 00171 // kdDebug(7014) << "Already having offer " << (*it)->name() << endl; 00172 } 00173 } 00174 00175 qBubbleSort( offers ); 00176 00177 #if 0 00178 // debug code, comment if you wish but don't remove. 00179 kdDebug(7014) << "Sorted list:" << endl; 00180 OfferList::Iterator itOff = offers.begin(); 00181 for( ; itOff != offers.end(); ++itOff ) 00182 kdDebug(7014) << (*itOff).service()->name() << " allow-as-default=" << (*itOff).allowAsDefault() << endl; 00183 #endif 00184 00185 kdDebug(7014) << "Returning " << offers.count() << " offers" << endl; 00186 return offers; 00187 } 00188 00189 KServiceTypeProfile::KServiceTypeProfile( const QString& _servicetype, const QString& _genericServiceType ) 00190 { 00191 initStatic(); 00192 00193 m_strServiceType = _servicetype; 00194 m_strGenericServiceType = _genericServiceType; 00195 } 00196 00197 KServiceTypeProfile::~KServiceTypeProfile() 00198 { 00199 } 00200 00201 void KServiceTypeProfile::addService( const QString& _service, 00202 int _preference, bool _allow_as_default ) 00203 { 00204 m_mapServices[ _service ].m_iPreference = _preference; 00205 m_mapServices[ _service ].m_bAllowAsDefault = _allow_as_default; 00206 } 00207 00208 int KServiceTypeProfile::preference( const QString& _service ) const 00209 { 00210 QMap<QString,Service>::ConstIterator it = m_mapServices.find( _service ); 00211 if ( it == m_mapServices.end() ) 00212 return 0; 00213 00214 return it.data().m_iPreference; 00215 } 00216 00217 bool KServiceTypeProfile::allowAsDefault( const QString& _service ) const 00218 { 00219 // Does the service itself not allow that ? 00220 KService::Ptr s = KService::serviceByName( _service ); 00221 if ( s && !s->allowAsDefault() ) 00222 return false; 00223 00224 // Look what the user says ... 00225 QMap<QString,Service>::ConstIterator it = m_mapServices.find( _service ); 00226 if ( it == m_mapServices.end() ) 00227 return 0; 00228 00229 return it.data().m_bAllowAsDefault; 00230 } 00231 00232 KServiceTypeProfile* KServiceTypeProfile::serviceTypeProfile( const QString& _servicetype, const QString& _genericServiceType ) 00233 { 00234 initStatic(); 00235 static const QString& app_str = KGlobal::staticQString("Application"); 00236 00237 const QString &_genservicetype = ((!_genericServiceType.isEmpty()) ? _genericServiceType : app_str); 00238 00239 QPtrListIterator<KServiceTypeProfile> it( *s_lstProfiles ); 00240 for( ; it.current(); ++it ) 00241 if (( it.current()->m_strServiceType == _servicetype ) && 00242 ( it.current()->m_strGenericServiceType == _genservicetype)) 00243 return it.current(); 00244 00245 return 0; 00246 } 00247 00248 00249 KServiceTypeProfile::OfferList KServiceTypeProfile::offers() const 00250 { 00251 OfferList offers; 00252 00253 kdDebug(7014) << "KServiceTypeProfile::offers serviceType=" << m_strServiceType << " genericServiceType=" << m_strGenericServiceType << endl; 00254 KService::List list = KServiceType::offers( m_strServiceType ); 00255 QValueListIterator<KService::Ptr> it = list.begin(); 00256 for( ; it != list.end(); ++it ) 00257 { 00258 //kdDebug(7014) << "KServiceTypeProfile::offers considering " << (*it)->name() << endl; 00259 if ( m_strGenericServiceType.isEmpty() || (*it)->hasServiceType( m_strGenericServiceType ) ) 00260 { 00261 // Now look into the profile, to find this service's preference. 00262 QMap<QString,Service>::ConstIterator it2 = m_mapServices.find( (*it)->name() ); 00263 00264 if( it2 != m_mapServices.end() ) 00265 { 00266 //kdDebug(7014) << "found in mapServices pref=" << it2.data().m_iPreference << endl; 00267 if ( it2.data().m_iPreference > 0 ) { 00268 bool allow = (*it)->allowAsDefault(); 00269 if ( allow ) 00270 allow = it2.data().m_bAllowAsDefault; 00271 KServiceOffer o( (*it), it2.data().m_iPreference, allow ); 00272 offers.append( o ); 00273 } 00274 } 00275 else 00276 { 00277 //kdDebug(7014) << "not found in mapServices. Appending." << endl; 00278 // We use 0 as the preference to ensure new apps don't take over existing apps (which default to 1) 00279 KServiceOffer o( (*it), 0, (*it)->allowAsDefault() ); 00280 offers.append( o ); 00281 } 00282 }/* else 00283 kdDebug(7014) << "Doesn't have " << m_strGenericServiceType << endl;*/ 00284 } 00285 00286 qBubbleSort( offers ); 00287 00288 //kdDebug(7014) << "KServiceTypeProfile::offers returning " << offers.count() << " offers" << endl; 00289 return offers; 00290 } 00291 00292 KService::Ptr KServiceTypeProfile::preferredService( const QString & _serviceType, const QString & _genericServiceType ) 00293 { 00294 OfferList lst = offers( _serviceType, _genericServiceType ); 00295 00296 OfferList::Iterator itOff = lst.begin(); 00297 // Look for the first one that is allowed as default. 00298 // Since the allowed-as-default are first anyway, we only have 00299 // to look at the first one to know. 00300 if( itOff != lst.end() && (*itOff).allowAsDefault() ) 00301 return (*itOff).service(); 00302 00303 kdDebug(7014) << "No offers, or none allowed as default" << endl; 00304 return 0L; 00305 } 00306 00307 /********************************************* 00308 * 00309 * KServiceOffer 00310 * 00311 *********************************************/ 00312 00313 KServiceOffer::KServiceOffer() 00314 { 00315 m_iPreference = -1; 00316 } 00317 00318 KServiceOffer::KServiceOffer( const KServiceOffer& _o ) 00319 { 00320 m_pService = _o.m_pService; 00321 m_iPreference = _o.m_iPreference; 00322 m_bAllowAsDefault = _o.m_bAllowAsDefault; 00323 } 00324 00325 KServiceOffer::KServiceOffer( KService::Ptr _service, int _pref, bool _default ) 00326 { 00327 m_pService = _service; 00328 m_iPreference = _pref; 00329 m_bAllowAsDefault = _default; 00330 } 00331 00332 00333 bool KServiceOffer::operator< ( const KServiceOffer& _o ) const 00334 { 00335 // Put offers allowed as default FIRST. 00336 if ( _o.m_bAllowAsDefault && !m_bAllowAsDefault ) 00337 return false; // _o is default and not 'this'. 00338 if ( !_o.m_bAllowAsDefault && m_bAllowAsDefault ) 00339 return true; // 'this' is default but not _o. 00340 // Both offers are allowed or not allowed as default 00341 // -> use preferences to sort them 00342 // The bigger the better, but we want the better FIRST 00343 return _o.m_iPreference < m_iPreference; 00344 }
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:30 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003