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 
00029 #include <qtl.h>
00030 
00031 template class QPtrList<KServiceTypeProfile>;
00032 
00033 /*********************************************
00034  *
00035  * KServiceTypeProfile
00036  *
00037  *********************************************/
00038 
00039 QPtrList<KServiceTypeProfile>* KServiceTypeProfile::s_lstProfiles = 0L;
00040 bool KServiceTypeProfile::s_configurationMode = false;
00041 
00042 void KServiceTypeProfile::initStatic()
00043 {
00044   if ( s_lstProfiles )
00045     return;
00046 
00047   // Make sure that a KServiceTypeFactory gets created.
00048   (void) KServiceTypeFactory::self();
00049 
00050   s_lstProfiles = new QPtrList<KServiceTypeProfile>;
00051 
00052   KConfig config( "profilerc", true, false);
00053 
00054   static const QString & defaultGroup = KGlobal::staticQString("<default>");
00055 
00056   QStringList tmpList = config.groupList();
00057   for (QStringList::Iterator aIt = tmpList.begin();
00058        aIt != tmpList.end(); ++aIt) {
00059     if ( *aIt == defaultGroup )
00060       continue;
00061 
00062     config.setGroup( *aIt );
00063 
00064     QString appDesktopPath = config.readEntry( "Application" );
00065 
00066     KService::Ptr pService = KService::serviceByDesktopPath( appDesktopPath );
00067 
00068     if ( pService ) {
00069       QString application = pService->name();
00070       QString type = config.readEntry( "ServiceType" );
00071       QString type2 = config.readEntry( "GenericServiceType" );
00072       if (type2.isEmpty()) // compat code
00073           type2 = (pService->type() == "Application") ? "Application" : "KParts/ReadOnlyPart";
00074       int pref = config.readNumEntry( "Preference" );
00075 
00076       if ( !type.isEmpty() /* && pref >= 0*/ ) // Don't test for pref here. We want those in the list, to mark them as forbidden
00077       {
00078         KServiceTypeProfile* p =
00079           KServiceTypeProfile::serviceTypeProfile( type, type2 );
00080 
00081         if ( !p )
00082           p = new KServiceTypeProfile( type, type2 );
00083 
00084         bool allow = config.readBoolEntry( "AllowAsDefault" );
00085         //kdDebug(7014) << "KServiceTypeProfile::initStatic adding service " << application << " to profile for " << type << "," << type2 << " with preference " << pref << endl;
00086         p->addService( application, pref, allow );
00087       }
00088     }
00089   }
00090 }
00091 
00092 //static
00093 KServiceTypeProfile::OfferList KServiceTypeProfile::offers( const QString& _servicetype, const QString& _genericServiceType )
00094 {
00095     OfferList offers;
00096     QStringList serviceList;
00097     kdDebug(7014) << "KServiceTypeProfile::offers( " << _servicetype << "," << _genericServiceType << " )" << endl;
00098 
00099     // Note that KServiceTypeProfile::offers() calls KServiceType::offers(),
00100     // so we _do_ get the new services, that are available but not in the profile.
00101     if ( _genericServiceType.isEmpty() )
00102     {
00103         initStatic();
00104         // We want all profiles for servicetype, if we have profiles.
00105         // ## Slow loop, if profilerc is big. We should use a map instead?
00106         QPtrListIterator<KServiceTypeProfile> it( *s_lstProfiles );
00107         for( ; it.current(); ++it )
00108             if ( it.current()->m_strServiceType == _servicetype )
00109             {
00110                 offers += it.current()->offers();
00111             }
00112         //kdDebug(7014) << "Found profile: " << offers.count() << " offers" << endl;
00113     }
00114     else
00115     {
00116         KServiceTypeProfile* profile = serviceTypeProfile( _servicetype, _genericServiceType );
00117         if ( profile )
00118         {
00119             //kdDebug(7014) << "Found profile: " << profile->offers().count() << " offers" << endl;
00120             offers += profile->offers();
00121         }
00122         else
00123         {
00124             // Try the other way round, order is not like size, it doesn't matter.
00125             profile = serviceTypeProfile( _genericServiceType, _servicetype );
00126             if ( profile )
00127             {
00128                 //kdDebug(7014) << "Found profile after switching: " << profile->offers().count() << " offers" << endl;
00129                 offers += profile->offers();
00130             }
00131         }
00132     }
00133 
00134     // Collect services, to make the next loop faster
00135     OfferList::Iterator itOffers = offers.begin();
00136     for( ; itOffers != offers.end(); ++itOffers )
00137         serviceList += (*itOffers).service()->desktopEntryPath(); // this should identify each service uniquely
00138     //kdDebug(7014) << "serviceList: " << serviceList.join(",") << endl;
00139 
00140     // Now complete with any other offers that aren't in the profile
00141     // This can be because the services have been installed after the profile was written,
00142     // but it's also the case for any service that's neither App nor ReadOnlyPart, e.g. RenameDlg/Plugin
00143     KService::List list = KServiceType::offers( _servicetype );
00144     //kdDebug(7014) << "Using KServiceType::offers, result: " << list.count() << " offers" << endl;
00145     QValueListIterator<KService::Ptr> it = list.begin();
00146     for( ; it != list.end(); ++it )
00147     {
00148         if (_genericServiceType.isEmpty() /*no constraint*/ || (*it)->hasServiceType( _genericServiceType ))
00149         {
00150             // Check that we don't already have it ;)
00151             if ( serviceList.find( (*it)->desktopEntryPath() ) == serviceList.end() )
00152             {
00153                 bool allow = (*it)->allowAsDefault();
00154                 KServiceOffer o( (*it), (*it)->initialPreference(), allow );
00155                 offers.append( o );
00156                 //kdDebug(7014) << "Appending offer " << (*it)->name() << " initial preference=" << (*it)->initialPreference() << " allow-as-default=" << allow << endl;
00157             }
00158             //else
00159             //    kdDebug(7014) << "Already having offer " << (*it)->name() << endl;
00160         }
00161     }
00162 
00163     qBubbleSort( offers );
00164 
00165 #if 0
00166     // debug code, comment if you wish but don't remove.
00167     kdDebug(7014) << "Sorted list:" << endl;
00168     OfferList::Iterator itOff = offers.begin();
00169     for( ; itOff != offers.end(); ++itOff )
00170         kdDebug(7014) << (*itOff).service()->name() << " allow-as-default=" << (*itOff).allowAsDefault() << endl;
00171 #endif
00172 
00173     kdDebug(7014) << "Returning " << offers.count() << " offers" << endl;
00174     return offers;
00175 }
00176 
00177 KServiceTypeProfile::KServiceTypeProfile( const QString& _servicetype, const QString& _genericServiceType )
00178 {
00179   initStatic();
00180 
00181   m_strServiceType = _servicetype;
00182   m_strGenericServiceType = _genericServiceType;
00183 
00184   s_lstProfiles->append( this );
00185 }
00186 
00187 KServiceTypeProfile::~KServiceTypeProfile()
00188 {
00189   Q_ASSERT( s_lstProfiles );
00190 
00191   s_lstProfiles->removeRef( this );
00192 }
00193 
00194 void KServiceTypeProfile::addService( const QString& _service,
00195                       int _preference, bool _allow_as_default )
00196 {
00197   m_mapServices[ _service ].m_iPreference = _preference;
00198   m_mapServices[ _service ].m_bAllowAsDefault = _allow_as_default;
00199 }
00200 
00201 int KServiceTypeProfile::preference( const QString& _service ) const
00202 {
00203   QMap<QString,Service>::ConstIterator it = m_mapServices.find( _service );
00204   if ( it == m_mapServices.end() )
00205     return 0;
00206 
00207   return it.data().m_iPreference;
00208 }
00209 
00210 bool KServiceTypeProfile::allowAsDefault( const QString& _service ) const
00211 {
00212   // Does the service itself not allow that ?
00213   KService::Ptr s = KService::serviceByName( _service );
00214   if ( s && !s->allowAsDefault() )
00215     return false;
00216 
00217   // Look what the user says ...
00218   QMap<QString,Service>::ConstIterator it = m_mapServices.find( _service );
00219   if ( it == m_mapServices.end() )
00220     return 0;
00221 
00222   return it.data().m_bAllowAsDefault;
00223 }
00224 
00225 KServiceTypeProfile* KServiceTypeProfile::serviceTypeProfile( const QString& _servicetype, const QString& _genericServiceType )
00226 {
00227   initStatic();
00228   static const QString& app_str = KGlobal::staticQString("Application");
00229 
00230   const QString &_genservicetype  = ((!_genericServiceType.isEmpty()) ? _genericServiceType : app_str);
00231 
00232   QPtrListIterator<KServiceTypeProfile> it( *s_lstProfiles );
00233   for( ; it.current(); ++it )
00234     if (( it.current()->m_strServiceType == _servicetype ) &&
00235         ( it.current()->m_strGenericServiceType == _genservicetype))
00236       return it.current();
00237 
00238   return 0;
00239 }
00240 
00241 
00242 KServiceTypeProfile::OfferList KServiceTypeProfile::offers() const
00243 {
00244   OfferList offers;
00245 
00246   kdDebug(7014) << "KServiceTypeProfile::offers serviceType=" << m_strServiceType << " genericServiceType=" << m_strGenericServiceType << endl;
00247   KService::List list = KServiceType::offers( m_strServiceType );
00248   QValueListIterator<KService::Ptr> it = list.begin();
00249   for( ; it != list.end(); ++it )
00250   {
00251     //kdDebug(7014) << "KServiceTypeProfile::offers considering " << (*it)->name() << endl;
00252     if ( m_strGenericServiceType.isEmpty() || (*it)->hasServiceType( m_strGenericServiceType ) )
00253     {
00254       // Now look into the profile, to find this service's preference.
00255       QMap<QString,Service>::ConstIterator it2 = m_mapServices.find( (*it)->name() );
00256 
00257       if( it2 != m_mapServices.end() )
00258       {
00259         //kdDebug(7014) << "found in mapServices pref=" << it2.data().m_iPreference << endl;
00260         if ( it2.data().m_iPreference > 0 ) {
00261           bool allow = (*it)->allowAsDefault();
00262           if ( allow )
00263             allow = it2.data().m_bAllowAsDefault;
00264           KServiceOffer o( (*it), it2.data().m_iPreference, allow );
00265           offers.append( o );
00266         }
00267       }
00268       else
00269       {
00270         //kdDebug(7014) << "not found in mapServices. Appending." << endl;
00271         KServiceOffer o( (*it), 1, (*it)->allowAsDefault() );
00272         offers.append( o );
00273       }
00274     }/* else
00275       kdDebug(7014) << "Doesn't have " << m_strGenericServiceType << endl;*/
00276   }
00277 
00278   qBubbleSort( offers );
00279 
00280   //kdDebug(7014) << "KServiceTypeProfile::offers returning " << offers.count() << " offers" << endl;
00281   return offers;
00282 }
00283 
00284 KService::Ptr KServiceTypeProfile::preferredService( const QString & _serviceType, const QString & _genericServiceType )
00285 {
00286   OfferList lst = offers( _serviceType, _genericServiceType );
00287 
00288   OfferList::Iterator itOff = lst.begin();
00289   // Look for the first one that is allowed as default.
00290   // Since the allowed-as-default are first anyway, we only have
00291   // to look at the first one to know.
00292   if( itOff != lst.end() && (*itOff).allowAsDefault() )
00293     return (*itOff).service();
00294 
00295   kdDebug(7014) << "No offers, or none allowed as default" << endl;
00296   return 0L;
00297 }
00298 
00299 /*********************************************
00300  *
00301  * KServiceOffer
00302  *
00303  *********************************************/
00304 
00305 KServiceOffer::KServiceOffer()
00306 {
00307   m_iPreference = -1;
00308 }
00309 
00310 KServiceOffer::KServiceOffer( const KServiceOffer& _o )
00311 {
00312   m_pService = _o.m_pService;
00313   m_iPreference = _o.m_iPreference;
00314   m_bAllowAsDefault = _o.m_bAllowAsDefault;
00315 }
00316 
00317 KServiceOffer::KServiceOffer( KService::Ptr _service, int _pref, bool _default )
00318 {
00319   m_pService = _service;
00320   m_iPreference = _pref;
00321   m_bAllowAsDefault = _default;
00322 }
00323 
00324 
00325 bool KServiceOffer::operator< ( const KServiceOffer& _o ) const
00326 {
00327   // Put offers allowed as default FIRST.
00328   if ( _o.m_bAllowAsDefault && !m_bAllowAsDefault )
00329     return false; // _o is default and not 'this'.
00330   if ( !_o.m_bAllowAsDefault && m_bAllowAsDefault )
00331     return true; // 'this' is default but not _o.
00332  // Both offers are allowed or not allowed as default
00333  // -> use preferences to sort them
00334  // The bigger the better, but we want the better FIRST
00335   return _o.m_iPreference < m_iPreference;
00336 }
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 27 22:15:33 2005 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001