kio Library: kuserprofile.cpp Source File (kio Library)

| # kio Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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 }

This file is part of the documentation for kio Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:24:05 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003