• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kio

kuserprofile.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor,
00016  *  Boston, MA 02110-1301, 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->storageId();
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     // HACK ksycoca may open the dummy db, in such case the first call to ksycoca
00102     // in initStatic() leads to closing the dummy db and clear() being called
00103     // in the middle of it, making s_lstProfiles be NULL
00104     if( s_lstProfiles == NULL || s_lstProfiles->count() == 0 )
00105         return;
00106     profileDeleter.destructObject();
00107 }
00108 
00109 //static
00110 KServiceTypeProfile::OfferList KServiceTypeProfile::offers( const QString& _servicetype, const QString& _genericServiceType )
00111 {
00112     OfferList offers;
00113     QStringList serviceList;
00114     //kdDebug(7014) << "KServiceTypeProfile::offers( " << _servicetype << "," << _genericServiceType << " )" << endl;
00115 
00116     // Note that KServiceTypeProfile::offers() calls KServiceType::offers(),
00117     // so we _do_ get the new services, that are available but not in the profile.
00118     if ( _genericServiceType.isEmpty() )
00119     {
00120         initStatic();
00121         // We want all profiles for servicetype, if we have profiles.
00122         // ## Slow loop, if profilerc is big. We should use a map instead?
00123         QPtrListIterator<KServiceTypeProfile> it( *s_lstProfiles );
00124         for( ; it.current(); ++it )
00125             if ( it.current()->m_strServiceType == _servicetype )
00126             {
00127                 offers += it.current()->offers();
00128             }
00129         //kdDebug(7014) << "Found profile: " << offers.count() << " offers" << endl;
00130     }
00131     else
00132     {
00133         KServiceTypeProfile* profile = serviceTypeProfile( _servicetype, _genericServiceType );
00134         if ( profile )
00135         {
00136             //kdDebug(7014) << "Found profile: " << profile->offers().count() << " offers" << endl;
00137             offers += profile->offers();
00138         }
00139         else
00140         {
00141             // Try the other way round, order is not like size, it doesn't matter.
00142             profile = serviceTypeProfile( _genericServiceType, _servicetype );
00143             if ( profile )
00144             {
00145                 //kdDebug(7014) << "Found profile after switching: " << profile->offers().count() << " offers" << endl;
00146                 offers += profile->offers();
00147             }
00148         }
00149     }
00150 
00151     // Collect services, to make the next loop faster
00152     OfferList::Iterator itOffers = offers.begin();
00153     for( ; itOffers != offers.end(); ++itOffers )
00154         serviceList += (*itOffers).service()->desktopEntryPath(); // this should identify each service uniquely
00155     //kdDebug(7014) << "serviceList: " << serviceList.join(",") << endl;
00156 
00157     // Now complete with any other offers that aren't in the profile
00158     // This can be because the services have been installed after the profile was written,
00159     // but it's also the case for any service that's neither App nor ReadOnlyPart, e.g. RenameDlg/Plugin
00160     KService::List list = KServiceType::offers( _servicetype );
00161     //kdDebug(7014) << "Using KServiceType::offers, result: " << list.count() << " offers" << endl;
00162     QValueListIterator<KService::Ptr> it = list.begin();
00163     for( ; it != list.end(); ++it )
00164     {
00165         if (_genericServiceType.isEmpty() /*no constraint*/ || (*it)->hasServiceType( _genericServiceType ))
00166         {
00167             // Check that we don't already have it ;)
00168             if ( serviceList.find( (*it)->desktopEntryPath() ) == serviceList.end() )
00169             {
00170                 bool allow = (*it)->allowAsDefault();
00171                 KServiceOffer o( (*it), (*it)->initialPreferenceForMimeType(_servicetype), allow );
00172                 offers.append( o );
00173                 //kdDebug(7014) << "Appending offer " << (*it)->name() << " initial preference=" << (*it)->initialPreference() << " allow-as-default=" << allow << endl;
00174             }
00175             //else
00176             //    kdDebug(7014) << "Already having offer " << (*it)->name() << endl;
00177         }
00178     }
00179 
00180     qBubbleSort( offers );
00181 
00182 #if 0
00183     // debug code, comment if you wish but don't remove.
00184     kdDebug(7014) << "Sorted list:" << endl;
00185     OfferList::Iterator itOff = offers.begin();
00186     for( ; itOff != offers.end(); ++itOff )
00187         kdDebug(7014) << (*itOff).service()->name() << " allow-as-default=" << (*itOff).allowAsDefault() << endl;
00188 #endif
00189 
00190     //kdDebug(7014) << "Returning " << offers.count() << " offers" << endl;
00191     return offers;
00192 }
00193 
00194 KServiceTypeProfile::KServiceTypeProfile( const QString& _servicetype, const QString& _genericServiceType )
00195 {
00196   initStatic();
00197 
00198   m_strServiceType = _servicetype;
00199   m_strGenericServiceType = _genericServiceType;
00200 }
00201 
00202 KServiceTypeProfile::~KServiceTypeProfile()
00203 {
00204 }
00205 
00206 void KServiceTypeProfile::addService( const QString& _service,
00207                       int _preference, bool _allow_as_default )
00208 {
00209   m_mapServices[ _service ].m_iPreference = _preference;
00210   m_mapServices[ _service ].m_bAllowAsDefault = _allow_as_default;
00211 }
00212 
00213 int KServiceTypeProfile::preference( const QString& _service ) const
00214 {
00215   KService::Ptr service = KService::serviceByName( _service );
00216   if (!service)
00217     return 0;
00218   QMap<QString,Service>::ConstIterator it = m_mapServices.find( service->storageId() );
00219   if ( it == m_mapServices.end() )
00220     return 0;
00221 
00222   return it.data().m_iPreference;
00223 }
00224 
00225 bool KServiceTypeProfile::allowAsDefault( const QString& _service ) const
00226 {
00227   KService::Ptr service = KService::serviceByName( _service );
00228   if (!service)
00229     return false;
00230 
00231   // Does the service itself not allow that ?
00232   if ( !service->allowAsDefault() )
00233     return false;
00234 
00235   // Look what the user says ...
00236   QMap<QString,Service>::ConstIterator it = m_mapServices.find( service->storageId() );
00237   if ( it == m_mapServices.end() )
00238     return 0;
00239 
00240   return it.data().m_bAllowAsDefault;
00241 }
00242 
00243 KServiceTypeProfile* KServiceTypeProfile::serviceTypeProfile( const QString& _servicetype, const QString& _genericServiceType )
00244 {
00245   initStatic();
00246   static const QString& app_str = KGlobal::staticQString("Application");
00247 
00248   const QString &_genservicetype  = ((!_genericServiceType.isEmpty()) ? _genericServiceType : app_str);
00249 
00250   QPtrListIterator<KServiceTypeProfile> it( *s_lstProfiles );
00251   for( ; it.current(); ++it )
00252     if (( it.current()->m_strServiceType == _servicetype ) &&
00253         ( it.current()->m_strGenericServiceType == _genservicetype))
00254       return it.current();
00255 
00256   return 0;
00257 }
00258 
00259 
00260 KServiceTypeProfile::OfferList KServiceTypeProfile::offers() const
00261 {
00262   OfferList offers;
00263 
00264   kdDebug(7014) << "KServiceTypeProfile::offers serviceType=" << m_strServiceType << " genericServiceType=" << m_strGenericServiceType << endl;
00265   KService::List list = KServiceType::offers( m_strServiceType );
00266   QValueListIterator<KService::Ptr> it = list.begin();
00267   for( ; it != list.end(); ++it )
00268   {
00269     //kdDebug(7014) << "KServiceTypeProfile::offers considering " << (*it)->name() << endl;
00270     if ( m_strGenericServiceType.isEmpty() || (*it)->hasServiceType( m_strGenericServiceType ) )
00271     {
00272       // Now look into the profile, to find this service's preference.
00273       QMap<QString,Service>::ConstIterator it2 = m_mapServices.find( (*it)->storageId() );
00274 
00275       if( it2 != m_mapServices.end() )
00276       {
00277         //kdDebug(7014) << "found in mapServices pref=" << it2.data().m_iPreference << endl;
00278         if ( it2.data().m_iPreference > 0 ) {
00279           bool allow = (*it)->allowAsDefault();
00280           if ( allow )
00281             allow = it2.data().m_bAllowAsDefault;
00282           KServiceOffer o( (*it), it2.data().m_iPreference, allow );
00283           offers.append( o );
00284         }
00285       }
00286       else
00287       {
00288         //kdDebug(7014) << "not found in mapServices. Appending." << endl;
00289         // We use 0 as the preference to ensure new apps don't take over existing apps (which default to 1)
00290         KServiceOffer o( (*it), 0, (*it)->allowAsDefault() );
00291         offers.append( o );
00292       }
00293     }/* else
00294       kdDebug(7014) << "Doesn't have " << m_strGenericServiceType << endl;*/
00295   }
00296 
00297   qBubbleSort( offers );
00298 
00299   //kdDebug(7014) << "KServiceTypeProfile::offers returning " << offers.count() << " offers" << endl;
00300   return offers;
00301 }
00302 
00303 KService::Ptr KServiceTypeProfile::preferredService( const QString & _serviceType, const QString & _genericServiceType )
00304 {
00305   OfferList lst = offers( _serviceType, _genericServiceType );
00306 
00307   OfferList::Iterator itOff = lst.begin();
00308   // Look for the first one that is allowed as default.
00309   // Since the allowed-as-default are first anyway, we only have
00310   // to look at the first one to know.
00311   if( itOff != lst.end() && (*itOff).allowAsDefault() )
00312     return (*itOff).service();
00313 
00314   //kdDebug(7014) << "No offers, or none allowed as default" << endl;
00315   return 0L;
00316 }
00317 
00318 /*********************************************
00319  *
00320  * KServiceOffer
00321  *
00322  *********************************************/
00323 
00324 KServiceOffer::KServiceOffer()
00325 {
00326   m_iPreference = -1;
00327 }
00328 
00329 KServiceOffer::KServiceOffer( const KServiceOffer& _o )
00330 {
00331   m_pService = _o.m_pService;
00332   m_iPreference = _o.m_iPreference;
00333   m_bAllowAsDefault = _o.m_bAllowAsDefault;
00334 }
00335 
00336 KServiceOffer::KServiceOffer( KService::Ptr _service, int _pref, bool _default )
00337 {
00338   m_pService = _service;
00339   m_iPreference = _pref;
00340   m_bAllowAsDefault = _default;
00341 }
00342 
00343 
00344 bool KServiceOffer::operator< ( const KServiceOffer& _o ) const
00345 {
00346   // Put offers allowed as default FIRST.
00347   if ( _o.m_bAllowAsDefault && !m_bAllowAsDefault )
00348     return false; // _o is default and not 'this'.
00349   if ( !_o.m_bAllowAsDefault && m_bAllowAsDefault )
00350     return true; // 'this' is default but not _o.
00351  // Both offers are allowed or not allowed as default
00352  // -> use preferences to sort them
00353  // The bigger the better, but we want the better FIRST
00354   return _o.m_iPreference < m_iPreference;
00355 }

kio

Skip menu "kio"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal