# kio Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kservice.cpp

    00001 /*  This file is part of the KDE libraries
    00002  *  Copyright (C) 1999 - 2001 Waldo Bastian <bastian@kde.org>
    00003  *  Copyright (C) 1999        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 // $Id$
    00021
    00022 #include <config.h>
    00023
    00024 #include "kservice.h"
    00025 #include "kservice_p.h"
    00026
    00027 #include <sys/types.h>
    00028 #include <sys/stat.h>
    00029
    00030 #include <stddef.h>
    00031 #include <unistd.h>
    00032 #include <stdlib.h>
    00033
    00034 #include <qstring.h>
    00035 #include <qfile.h>
    00036 #include <qdir.h>
    00037 #include <qtl.h>
    00038
    00039 #include <ksimpleconfig.h>
    00040 #include <kapplication.h>
    00041 #include <kdebug.h>
    00042 #include <kdesktopfile.h>
    00043 #include <kglobal.h>
    00044 #include <kiconloader.h>
    00045 #include <klocale.h>
    00046 #include <kconfigbase.h>
    00047 #include <kstandarddirs.h>
    00048 #include <dcopclient.h>
    00049
    00050 #include "kservicefactory.h"
    00051 #include "kservicetypefactory.h"
    00052 #include "kservicetype.h"
    00053 #include "kuserprofile.h"
    00054 #include "ksycoca.h"
    00055
    00056 class KService::KServicePrivate
    00057 {
    00058 public:
    00059   QStringList categories;
    00060   QString menuId;
    00061 };
    00062
    00063 KService::KService( const QString & _name, const QString &_exec, const QString &_icon)
    00064  : KSycocaEntry( QString::null)
    00065 {
    00066   d = new KServicePrivate;
    00067   m_bValid = true;
    00068   m_bDeleted = false;
    00069   m_strType = "Application";
    00070   m_strName = _name;
    00071   m_strExec = _exec;
    00072   m_strIcon = _icon;
    00073   m_bTerminal = false;
    00074   m_bAllowAsDefault = true;
    00075   m_initialPreference = 10;
    00076 }
    00077
    00078
    00079 KService::KService( const QString & _fullpath )
    00080  : KSycocaEntry( _fullpath)
    00081 {
    00082   KDesktopFile config( _fullpath );
    00083
    00084   init(&config);
    00085 }
    00086
    00087 KService::KService( KDesktopFile *config )
    00088  : KSycocaEntry( config->fileName())
    00089 {
    00090   init(config);
    00091 }
    00092
    00093 void
    00094 KService::init( KDesktopFile *config )
    00095 {
    00096   d = new KServicePrivate;
    00097   m_bValid = true;
    00098
    00099   bool absPath = !QDir::isRelativePath(entryPath());
    00100
    00101   config->setDesktopGroup();
    00102
    00103   QMap<QString, QString> entryMap = config->entryMap(config->group());
    00104
    00105   entryMap.remove("Encoding"); // reserved as part of Desktop Entry Standard
    00106   entryMap.remove("Version");  // reserved as part of Desktop Entry Standard
    00107
    00108   m_bDeleted = config->readBoolEntry( "Hidden", false );
    00109   entryMap.remove("Hidden");
    00110   if (m_bDeleted)
    00111   {
    00112     m_bValid = false;
    00113     return;
    00114   }
    00115
    00116   m_strName = config->readEntry( "Name" );
    00117   entryMap.remove("Name");
    00118   if ( m_strName.isEmpty() )
    00119   {
    00120     if (config->readEntry( "Exec" ).isEmpty())
    00121     {
    00122       m_bValid = false;
    00123       return;
    00124     }
    00125     // Try to make up a name.
    00126     m_strName = entryPath();
    00127     int i = m_strName.findRev('/');
    00128     m_strName = m_strName.mid(i+1);
    00129     i = m_strName.findRev('.');
    00130     if (i != -1)
    00131        m_strName = m_strName.left(i);
    00132   }
    00133
    00134   m_strType = config->readEntry( "Type" );
    00135   entryMap.remove("Type");
    00136   if ( m_strType.isEmpty() )
    00137   {
    00138     /*kdWarning(7012) << "The desktop entry file " << entryPath()
    00139                     << " has no Type=... entry."
    00140                     << " It should be \"Application\" or \"Service\"" << endl;
    00141     m_bValid = false;
    00142     return;*/
    00143     m_strType = "Application";
    00144   } else if ( m_strType != "Application" && m_strType != "Service" )
    00145   {
    00146     kdWarning(7012) << "The desktop entry file " << entryPath()
    00147                     << " has Type=" << m_strType
    00148                     << " instead of \"Application\" or \"Service\"" << endl;
    00149     m_bValid = false;
    00150     return;
    00151   }
    00152
    00153   // In case Try Exec is set, check if the application is available
    00154   if (!config->tryExec()) {
    00155       m_bDeleted = true;
    00156       m_bValid = false;
    00157       return;
    00158   }
    00159
    00160   QString resource = config->resource();
    00161
    00162   if ( (m_strType == "Application") &&
    00163        (!resource.isEmpty()) &&
    00164        (resource != "apps") &&
    00165        !absPath)
    00166   {
    00167     kdWarning(7012) << "The desktop entry file " << entryPath()
    00168            << " has Type=" << m_strType << " but is located under \"" << resource
    00169            << "\" instead of \"apps\"" << endl;
    00170     m_bValid = false;
    00171     return;
    00172   }
    00173
    00174   if ( (m_strType == "Service") &&
    00175        (!resource.isEmpty()) &&
    00176        (resource != "services") &&
    00177        !absPath)
    00178   {
    00179     kdWarning(7012) << "The desktop entry file " << entryPath()
    00180            << " has Type=" << m_strType << " but is located under \"" << resource
    00181            << "\" instead of \"services\"" << endl;
    00182     m_bValid = false;
    00183     return;
    00184   }
    00185
    00186   QString name = entryPath();
    00187   int pos = name.findRev('/');
    00188   if (pos != -1)
    00189      name = name.mid(pos+1);
    00190   pos = name.find('.');
    00191   if (pos != -1)
    00192      name = name.left(pos);
    00193
    00194   m_strExec = config->readPathEntry( "Exec" );
    00195   entryMap.remove("Exec");
    00196
    00197   m_strIcon = config->readEntry( "Icon", "unknown" );
    00198   entryMap.remove("Icon");
    00199   m_bTerminal = (config->readBoolEntry( "Terminal" )); // should be a property IMHO
    00200   entryMap.remove("Terminal");
    00201   m_strTerminalOptions = config->readEntry( "TerminalOptions" ); // should be a property IMHO
    00202   entryMap.remove("TerminalOptions");
    00203   m_strPath = config->readPathEntry( "Path" );
    00204   entryMap.remove("Path");
    00205   m_strComment = config->readEntry( "Comment" );
    00206   entryMap.remove("Comment");
    00207   m_strGenName = config->readEntry( "GenericName" );
    00208   entryMap.remove("GenericName");
    00209   QString untranslatedGenericName = config->readEntryUntranslated( "GenericName" );
    00210   entryMap.insert("UntranslatedGenericName", untranslatedGenericName);
    00211
    00212   m_lstKeywords = config->readListEntry("Keywords");
    00213   entryMap.remove("Keywords");
    00214   d->categories = config->readListEntry("Categories", ';');
    00215   entryMap.remove("Categories");
    00216   m_strLibrary = config->readEntry( "X-KDE-Library" );
    00217   entryMap.remove("X-KDE-Library");
    00218   m_strInit = config->readEntry("X-KDE-Init" );
    00219   entryMap.remove("X-KDE-Init");
    00220
    00221   m_lstServiceTypes = config->readListEntry( "ServiceTypes" );
    00222   entryMap.remove("ServiceTypes");
    00223   // For compatibility with KDE 1.x
    00224   m_lstServiceTypes += config->readListEntry( "MimeType", ';' );
    00225   entryMap.remove("MimeType");
    00226
    00227   if ( m_strType == "Application" && !m_lstServiceTypes.contains("Application") )
    00228     // Applications implement the service type "Application" ;-)
    00229     m_lstServiceTypes += "Application";
    00230
    00231   QString dcopServiceType = config->readEntry("X-DCOP-ServiceType").lower();
    00232   entryMap.remove("X-DCOP-ServiceType");
    00233   if (dcopServiceType == "unique")
    00234      m_DCOPServiceType = DCOP_Unique;
    00235   else if (dcopServiceType == "multi")
    00236      m_DCOPServiceType = DCOP_Multi;
    00237   else if (dcopServiceType == "wait")
    00238      m_DCOPServiceType = DCOP_Wait;
    00239   else
    00240      m_DCOPServiceType = DCOP_None;
    00241
    00242   m_strDesktopEntryName = name.lower();
    00243
    00244   m_bAllowAsDefault = config->readBoolEntry( "AllowDefault", true );
    00245   entryMap.remove("AllowDefault");
    00246
    00247   m_initialPreference = config->readNumEntry( "InitialPreference", 1 );
    00248   entryMap.remove("InitialPreference");
    00249
    00250   // Store all additional entries in the property map.
    00251   // A QMap<QString,QString> would be easier for this but we can't
    00252   // brake BC, so we have to store it in m_mapProps.
    00253 //  qWarning("Path = %s", entryPath().latin1());
    00254   QMap<QString,QString>::ConstIterator it = entryMap.begin();
    00255   for( ; it != entryMap.end();++it)
    00256   {
    00257 //     qWarning("   Key = %s Data = %s", it.key().latin1(), it.data().latin1());
    00258      m_mapProps.insert( it.key(), QVariant( it.data()));
    00259   }
    00260 }
    00261
    00262 KService::KService( QDataStream& _str, int offset ) : KSycocaEntry( _str, offset )
    00263 {
    00264   d = new KServicePrivate;
    00265   load( _str );
    00266 }
    00267
    00268 KService::~KService()
    00269 {
    00270   //debug("KService::~KService()");
    00271   delete d;
    00272 }
    00273
    00274 QPixmap KService::pixmap( KIcon::Group _group, int _force_size, int _state, QString * _path ) const
    00275 {
    00276   KIconLoader *iconLoader=KGlobal::iconLoader();
    00277   if (!iconLoader->extraDesktopThemesAdded())
    00278   {
    00279       QPixmap pixmap=iconLoader->loadIcon( m_strIcon, _group, _force_size, _state, _path, true );
    00280       if (!pixmap.isNull() ) return pixmap;
    00281
    00282       iconLoader->addExtraDesktopThemes();
    00283   }
    00284
    00285   return iconLoader->loadIcon( m_strIcon, _group, _force_size, _state, _path );
    00286 }
    00287
    00288 void KService::load( QDataStream& s )
    00289 {
    00290   // dummies are here because of fields that were removed, to keep bin compat.
    00291   // Feel free to re-use, but fields for Applications only (not generic services)
    00292   // should rather be added to application.desktop
    00293   Q_INT8 def, term, dummy1, dummy2;
    00294   Q_INT8 dst, initpref;
    00295   QString dummyStr1, dummyStr2;
    00296   int dummyI1, dummyI2;
    00297   Q_UINT32 dummyUI32;
    00298
    00299   // WARNING: IN KDE 3.x THIS NEEDS TO REMAIN COMPATIBLE WITH KDE 2.x!
    00300   // !! This data structure should remain binary compatible at all times !!
    00301   // You may add new fields at the end. Make sure to update the version
    00302   // number in ksycoca.h
    00303   s >> m_strType >> m_strName >> m_strExec >> m_strIcon
    00304     >> term >> m_strTerminalOptions
    00305     >> m_strPath >> m_strComment >> m_lstServiceTypes >> def >> m_mapProps
    00306     >> m_strLibrary >> dummyI1 >> dummyI2
    00307     >> dst
    00308     >> m_strDesktopEntryName
    00309     >> dummy1 >> dummyStr1 >> initpref >> dummyStr2 >> dummy2
    00310     >> m_lstKeywords >> m_strInit >> dummyUI32 >> m_strGenName
    00311     >> d->categories >> d->menuId;
    00312
    00313   m_bAllowAsDefault = def;
    00314   m_bTerminal = term;
    00315   m_DCOPServiceType = (DCOPServiceType_t) dst;
    00316   m_initialPreference = initpref;
    00317
    00318   m_bValid = true;
    00319 }
    00320
    00321 void KService::save( QDataStream& s )
    00322 {
    00323   KSycocaEntry::save( s );
    00324   Q_INT8 def = m_bAllowAsDefault, initpref = m_initialPreference;
    00325   Q_INT8 term = m_bTerminal;
    00326   Q_INT8 dst = (Q_INT8) m_DCOPServiceType;
    00327   Q_INT8 dummy1 = 0, dummy2 = 0; // see ::load
    00328   QString dummyStr1, dummyStr2;
    00329   int dummyI1 = 0, dummyI2 = 0;
    00330   Q_UINT32 dummyUI32 = 0;
    00331
    00332   // WARNING: IN KDE 3.x THIS NEEDS TO REMAIN COMPATIBLE WITH KDE 2.x!
    00333   // !! This data structure should remain binary compatible at all times !!
    00334   // You may add new fields at the end. Make sure to update the version
    00335   // number in ksycoca.h
    00336   s << m_strType << m_strName << m_strExec << m_strIcon
    00337     << term << m_strTerminalOptions
    00338     << m_strPath << m_strComment << m_lstServiceTypes << def << m_mapProps
    00339     << m_strLibrary << dummyI1 << dummyI2
    00340     << dst
    00341     << m_strDesktopEntryName
    00342     << dummy1 << dummyStr1 << initpref << dummyStr2 << dummy2
    00343     << m_lstKeywords << m_strInit << dummyUI32 << m_strGenName
    00344     << d->categories << d->menuId;
    00345 }
    00346
    00347 bool KService::hasServiceType( const QString& _servicetype ) const
    00348 {
    00349   if (!m_bValid) return false; // safety test
    00350
    00351   //kdDebug(7012) << "Testing " << m_strDesktopEntryName << " for " << _servicetype << endl;
    00352
    00353   KMimeType::Ptr mimePtr = KMimeType::mimeType( _servicetype );
    00354   if ( mimePtr && mimePtr == KMimeType::defaultMimeTypePtr() )
    00355       mimePtr = 0;
    00356
    00357   bool isNumber;
    00358   // For each service type we are associated with, if it doesn't
    00359   // match then we try its parent service types.
    00360   QStringList::ConstIterator it = m_lstServiceTypes.begin();
    00361   for( ; it != m_lstServiceTypes.end(); ++it )
    00362   {
    00363       (*it).toInt(&isNumber);
    00364       if (isNumber)
    00365          continue;
    00366       //kdDebug(7012) << "    has " << (*it) << endl;
    00367       KServiceType::Ptr ptr = KServiceType::serviceType( *it );
    00368       if ( ptr && ptr->inherits( _servicetype ) )
    00369           return true;
    00370
    00371       // The mimetype inheritance ("is also") works the other way.
    00372       // e.g. if we're looking for a handler for mimePtr==smb-workgroup
    00373       // then a handler for inode/directory is ok.
    00374       if ( mimePtr && mimePtr->is( *it ) )
    00375           return true;
    00376   }
    00377   return false;
    00378 }
    00379
    00380 int KService::initialPreferenceForMimeType( const QString& mimeType ) const
    00381 {
    00382   if (!m_bValid) return 0; // safety test
    00383
    00384   bool isNumber;
    00385
    00386   // For each service type we are associated with
    00387   QStringList::ConstIterator it = m_lstServiceTypes.begin();
    00388   for( ; it != m_lstServiceTypes.end(); ++it )
    00389   {
    00390       (*it).toInt(&isNumber);
    00391       if (isNumber)
    00392          continue;
    00393       //kdDebug(7012) << "    has " << (*it) << endl;
    00394       KServiceType::Ptr ptr = KServiceType::serviceType( *it );
    00395       if ( !ptr || !ptr->inherits( mimeType ) )
    00396           continue;
    00397
    00398       int initalPreference = m_initialPreference;
    00399       ++it;
    00400       if (it != m_lstServiceTypes.end())
    00401       {
    00402          int i = (*it).toInt(&isNumber);
    00403          if (isNumber)
    00404             initalPreference = i;
    00405       }
    00406       return initalPreference;
    00407   }
    00408
    00409   KMimeType::Ptr mimePtr = KMimeType::mimeType( mimeType );
    00410   if ( mimePtr && mimePtr == KMimeType::defaultMimeTypePtr() )
    00411       mimePtr = 0;
    00412
    00413   // Try its parent service types.
    00414   it = m_lstServiceTypes.begin();
    00415   for( ; it != m_lstServiceTypes.end(); ++it )
    00416   {
    00417       (*it).toInt(&isNumber);
    00418       if (isNumber)
    00419          continue;
    00420
    00421       // The mimetype inheritance ("is also") works the other way.
    00422       // e.g. if we're looking for a handler for mimePtr==smb-workgroup
    00423       // then a handler for inode/directory is ok.
    00424       if ( !mimePtr || !mimePtr->is( *it ) )
    00425           continue;
    00426
    00427       int initalPreference = m_initialPreference;
    00428       ++it;
    00429       if (it != m_lstServiceTypes.end())
    00430       {
    00431          int i = (*it).toInt(&isNumber);
    00432          if (isNumber)
    00433             initalPreference = i;
    00434       }
    00435       return initalPreference;
    00436   }
    00437   return 0;
    00438 }
    00439
    00440 class KServiceReadProperty : public KConfigBase
    00441 {
    00442 public:
    00443    KServiceReadProperty(const QString &_key, const QCString &_value)
    00444     : key(_key), value(_value) { }
    00445
    00446    bool internalHasGroup(const QCString &) const { /*qDebug("hasGroup(const QCString &)");*/ return false; }
    00447
    00448    QStringList groupList() const { return QStringList(); }
    00449
    00450    QMap<QString,QString> entryMap(const QString &) const
    00451       { return QMap<QString,QString>(); }
    00452
    00453    void reparseConfiguration() { }
    00454
    00455    KEntryMap internalEntryMap( const QString &) const { return KEntryMap(); }
    00456
    00457    KEntryMap internalEntryMap() const { return KEntryMap(); }
    00458
    00459    void putData(const KEntryKey &, const KEntry&, bool) { }
    00460
    00461    KEntry lookupData(const KEntryKey &) const
    00462    { KEntry entry; entry.mValue = value; return entry; }
    00463 protected:
    00464    QString key;
    00465    QCString value;
    00466 };
    00467
    00468 QVariant KService::property( const QString& _name) const
    00469 {
    00470    return property( _name, QVariant::Invalid);
    00471 }
    00472
    00473 // Return a string QVariant if string isn't null, and invalid variant otherwise
    00474 // (the variant must be invalid if the field isn't in the .desktop file)
    00475 // This allows trader queries like "exist Library" to work.
    00476 static QVariant makeStringVariant( const QString& string )
    00477 {
    00478     // Using isEmpty here would be wrong.
    00479     // Empty is "specified but empty", null is "not specified" (in the .desktop file)
    00480     return string.isNull() ? QVariant() : QVariant( string );
    00481 }
    00482
    00483 QVariant KService::property( const QString& _name, QVariant::Type t ) const
    00484 {
    00485   if ( _name == "Type" )
    00486     return QVariant( m_strType ); // can't be null
    00487   else if ( _name == "Name" )
    00488     return QVariant( m_strName ); // can't be null
    00489   else if ( _name == "Exec" )
    00490     return makeStringVariant( m_strExec );
    00491   else if ( _name == "Icon" )
    00492     return makeStringVariant( m_strIcon );
    00493   else if ( _name == "Terminal" )
    00494     return QVariant( static_cast<int>(m_bTerminal) );
    00495   else if ( _name == "TerminalOptions" )
    00496     return makeStringVariant( m_strTerminalOptions );
    00497   else if ( _name == "Path" )
    00498     return makeStringVariant( m_strPath );
    00499   else if ( _name == "Comment" )
    00500     return makeStringVariant( m_strComment );
    00501   else if ( _name == "GenericName" )
    00502     return makeStringVariant( m_strGenName );
    00503   else if ( _name == "ServiceTypes" )
    00504     return QVariant( m_lstServiceTypes );
    00505   else if ( _name == "AllowAsDefault" )
    00506     return QVariant( static_cast<int>(m_bAllowAsDefault) );
    00507   else if ( _name == "InitialPreference" )
    00508     return QVariant( m_initialPreference );
    00509   else if ( _name == "Library" )
    00510     return makeStringVariant( m_strLibrary );
    00511   else if ( _name == "DesktopEntryPath" ) // can't be null
    00512     return QVariant( entryPath() );
    00513   else if ( _name == "DesktopEntryName")
    00514     return QVariant( m_strDesktopEntryName ); // can't be null
    00515   else if ( _name == "Categories")
    00516     return QVariant( d->categories );
    00517   else if ( _name == "Keywords")
    00518     return QVariant( m_lstKeywords );
    00519
    00520   // Ok we need to convert the property from a QString to its real type.
    00521   // Maybe the caller helped us.
    00522   if (t == QVariant::Invalid)
    00523   {
    00524     // No luck, let's ask KServiceTypeFactory what the type of this property
    00525     // is supposed to be.
    00526     t = KServiceTypeFactory::self()->findPropertyTypeByName(_name);
    00527     if (t == QVariant::Invalid)
    00528     {
    00529       kdDebug(7012) << "Request for unknown property '" << _name << "'\n";
    00530       return QVariant(); // Unknown property: Invalid variant.
    00531     }
    00532   }
    00533
    00534   // Then we use a homebuild class based on KConfigBase to convert the QString.
    00535   // For some often used property types we do the conversion ourselves.
    00536   QMap<QString,QVariant>::ConstIterator it = m_mapProps.find( _name );
    00537   if ( (it == m_mapProps.end()) || (!it.data().isValid()))
    00538   {
    00539      //kdDebug(7012) << "Property not found " << _name << endl;
    00540      return QVariant(); // No property set.
    00541   }
    00542
    00543   switch(t)
    00544   {
    00545     case QVariant::String:
    00546         return it.data();
    00547     case QVariant::Bool:
    00548     case QVariant::Int:
    00549         {
    00550            QString aValue = it.data().toString();
    00551            int val = 0;
    00552            if (aValue == "true" || aValue == "on" || aValue == "yes")
    00553               val = 1;
    00554            else
    00555            {
    00556               bool bOK;
    00557               val = aValue.toInt( &bOK );
    00558               if( !bOK )
    00559                  val = 0;
    00560            }
    00561            if (t == QVariant::Bool)
    00562            {
    00563                return QVariant((bool)val, 1);
    00564            }
    00565            return QVariant(val);
    00566         }
    00567     default:
    00568         // All others
    00569         KServiceReadProperty ksrp(_name, it.data().toString().utf8());
    00570         return ksrp.readPropertyEntry(_name, t);
    00571   }
    00572 }
    00573
    00574 QStringList KService::propertyNames() const
    00575 {
    00576   QStringList res;
    00577
    00578   QMap<QString,QVariant>::ConstIterator it = m_mapProps.begin();
    00579   for( ; it != m_mapProps.end(); ++it )
    00580     res.append( it.key() );
    00581
    00582   res.append( "Type" );
    00583   res.append( "Name" );
    00584   res.append( "Comment" );
    00585   res.append( "GenericName" );
    00586   res.append( "Icon" );
    00587   res.append( "Exec" );
    00588   res.append( "Terminal" );
    00589   res.append( "TerminalOptions" );
    00590   res.append( "Path" );
    00591   res.append( "ServiceTypes" );
    00592   res.append( "AllowAsDefault" );
    00593   res.append( "InitialPreference" );
    00594   res.append( "Library" );
    00595   res.append( "DesktopEntryPath" );
    00596   res.append( "DesktopEntryName" );
    00597   res.append( "Keywords" );
    00598   res.append( "Categories" );
    00599
    00600   return res;
    00601 }
    00602
    00603 KService::List KService::allServices()
    00604 {
    00605   return KServiceFactory::self()->allServices();
    00606 }
    00607
    00608 KService::Ptr KService::serviceByName( const QString& _name )
    00609 {
    00610   KService * s = KServiceFactory::self()->findServiceByName( _name );
    00611   return KService::Ptr( s );
    00612 }
    00613
    00614 KService::Ptr KService::serviceByDesktopPath( const QString& _name )
    00615 {
    00616   KService * s = KServiceFactory::self()->findServiceByDesktopPath( _name );
    00617   return KService::Ptr( s );
    00618 }
    00619
    00620 KService::Ptr KService::serviceByDesktopName( const QString& _name )
    00621 {
    00622   KService * s = KServiceFactory::self()->findServiceByDesktopName( _name.lower() );
    00623   if (!s && !_name.startsWith("kde-"))
    00624      s = KServiceFactory::self()->findServiceByDesktopName( "kde-"+_name.lower() );
    00625   return KService::Ptr( s );
    00626 }
    00627
    00628 KService::Ptr KService::serviceByMenuId( const QString& _name )
    00629 {
    00630   KService * s = KServiceFactory::self()->findServiceByMenuId( _name );
    00631   return KService::Ptr( s );
    00632 }
    00633
    00634 KService::Ptr KService::serviceByStorageId( const QString& _storageId )
    00635 {
    00636   KService::Ptr service = KService::serviceByMenuId( _storageId );
    00637   if (service)
    00638      return service;
    00639
    00640   service = KService::serviceByDesktopPath(_storageId);
    00641   if (service)
    00642      return service;
    00643
    00644   if (!QDir::isRelativePath(_storageId) && QFile::exists(_storageId))
    00645      return new KService(_storageId);
    00646
    00647   QString tmp = _storageId;
    00648   tmp = tmp.mid(tmp.findRev('/')+1); // Strip dir
    00649
    00650   if (tmp.endsWith(".desktop"))
    00651      tmp.truncate(tmp.length()-8);
    00652
    00653   if (tmp.endsWith(".kdelnk"))
    00654      tmp.truncate(tmp.length()-7);
    00655
    00656   service = KService::serviceByDesktopName(tmp);
    00657
    00658   return service;
    00659 }
    00660
    00661 KService::List KService::allInitServices()
    00662 {
    00663   return KServiceFactory::self()->allInitServices();
    00664 }
    00665
    00666 bool KService::substituteUid() const {
    00667   QVariant v = property("X-KDE-SubstituteUID", QVariant::Bool);
    00668   return v.isValid() && v.toBool();
    00669 }
    00670
    00671 QString KService::username() const {
    00672   // See also KDesktopFile::tryExec()
    00673   QString user;
    00674   QVariant v = property("X-KDE-Username", QVariant::String);
    00675   user = v.isValid() ? v.toString() : QString::null;
    00676   if (user.isEmpty())
    00677      user = ::getenv("ADMIN_ACCOUNT");
    00678   if (user.isEmpty())
    00679      user = "root";
    00680   return user;
    00681 }
    00682
    00683 bool KService::noDisplay() const {
    00684   QMap<QString,QVariant>::ConstIterator it = m_mapProps.find( "NoDisplay" );
    00685   if ( (it != m_mapProps.end()) && (it.data().isValid()))
    00686   {
    00687      QString aValue = it.data().toString().lower();
    00688      if (aValue == "true" || aValue == "on" || aValue == "yes")
    00689         return true;
    00690   }
    00691
    00692   it = m_mapProps.find( "OnlyShowIn" );
    00693   if ( (it != m_mapProps.end()) && (it.data().isValid()))
    00694   {
    00695      QString aValue = it.data().toString();
    00696      QStringList aList = QStringList::split(';', aValue);
    00697      if (!aList.contains("KDE"))
    00698         return true;
    00699   }
    00700
    00701   it = m_mapProps.find( "NotShowIn" );
    00702   if ( (it != m_mapProps.end()) && (it.data().isValid()))
    00703   {
    00704      QString aValue = it.data().toString();
    00705      QStringList aList = QStringList::split(';', aValue);
    00706      if (aList.contains("KDE"))
    00707         return true;
    00708   }
    00709
    00710   if (!kapp->authorizeControlModule(d->menuId))
    00711      return true;
    00712
    00713   return false;
    00714 }
    00715
    00716 QString KService::untranslatedGenericName() const {
    00717   QVariant v = property("UntranslatedGenericName", QVariant::String);
    00718   return v.isValid() ? v.toString() : QString::null;
    00719 }
    00720
    00721 QString KService::parentApp() const {
    00722   QMap<QString,QVariant>::ConstIterator it = m_mapProps.find( "X-KDE-ParentApp" );
    00723   if ( (it == m_mapProps.end()) || (!it.data().isValid()))
    00724   {
    00725      return QString::null;
    00726   }
    00727
    00728   return it.data().toString();
    00729 }
    00730
    00731 bool KService::allowMultipleFiles() const {
    00732   // Can we pass multiple files on the command line or do we have to start the application for every single file ?
    00733   if ( m_strExec.find( "%F" ) != -1 || m_strExec.find( "%U" ) != -1 ||
    00734        m_strExec.find( "%N" ) != -1 || m_strExec.find( "%D" ) != -1 )
    00735     return true;
    00736   else
    00737     return false;
    00738 }
    00739
    00740 QStringList KService::categories() const
    00741 {
    00742   return d->categories;
    00743 }
    00744
    00745 QString KService::menuId() const
    00746 {
    00747   return d->menuId;
    00748 }
    00749
    00750 void KService::setMenuId(const QString &menuId)
    00751 {
    00752   d->menuId = menuId;
    00753 }
    00754
    00755 QString KService::storageId() const
    00756 {
    00757   if (!d->menuId.isEmpty())
    00758      return d->menuId;
    00759   return entryPath();
    00760 }
    00761
    00762 QString KService::locateLocal()
    00763 {
    00764   if (d->menuId.isEmpty() || desktopEntryPath().startsWith(".hidden") ||
    00765       (QDir::isRelativePath(desktopEntryPath()) && d->categories.isEmpty()))
    00766      return KDesktopFile::locateLocal(desktopEntryPath());
    00767
    00768   return ::locateLocal("xdgdata-apps", d->menuId);
    00769 }
    00770
    00771 QString KService::newServicePath(bool showInMenu, const QString &suggestedName,
    00772                                 QString *menuId, const QStringList *reservedMenuIds)
    00773 {
    00774    QString base = suggestedName;
    00775    if (!showInMenu)
    00776      base.prepend("kde-");
    00777
    00778    QString result;
    00779    for(int i = 1; true; i++)
    00780    {
    00781       if (i == 1)
    00782          result = base + ".desktop";
    00783       else
    00784          result = base + QString("-%1.desktop").arg(i);
    00785
    00786       if (reservedMenuIds && reservedMenuIds->contains(result))
    00787          continue;
    00788
    00789       // Lookup service by menu-id
    00790       KService::Ptr s = serviceByMenuId(result);
    00791       if (s)
    00792          continue;
    00793
    00794       if (showInMenu)
    00795       {
    00796          if (!locate("xdgdata-apps", result).isEmpty())
    00797             continue;
    00798       }
    00799       else
    00800       {
    00801          QString file = result.mid(4); // Strip "kde-"
    00802          if (!locate("apps", ".hidden/"+file).isEmpty())
    00803             continue;
    00804       }
    00805
    00806       break;
    00807    }
    00808    if (menuId)
    00809       *menuId = result;
    00810
    00811    if (showInMenu)
    00812    {
    00813        return ::locateLocal("xdgdata-apps", result);
    00814    }
    00815    else
    00816    {
    00817        QString file = result.mid(4); // Strip "kde-"
    00818        return ::locateLocal("apps", ".hidden/"+file);
    00819    }
    00820 }
    00821
    00822
    00823 void KService::virtual_hook( int id, void* data )
    00824 { KSycocaEntry::virtual_hook( id, data ); }
    00825
    00826
    00827 void KService::rebuildKSycoca(QWidget *parent)
    00828 {
    00829   KServiceProgressDialog dlg(parent, "ksycoca_progress",
    00830                       i18n("Updating System Configuration"),
    00831                       i18n("Updating system configuration."));
    00832
    00833   QByteArray data;
    00834   DCOPClient *client = kapp->dcopClient();
    00835
    00836   int result = client->callAsync("kded", "kbuildsycoca", "recreate()",
    00837                data, &dlg, SLOT(slotFinished()));
    00838
    00839   if (result)
    00840   {
    00841      dlg.exec();
    00842   }
    00843 }
    00844
    00845 KServiceProgressDialog::KServiceProgressDialog(QWidget *parent, const char *name,
    00846                           const QString &caption, const QString &text)
    00847  : KProgressDialog(parent, name, caption, text, true)
    00848 {
    00849   connect(&m_timer, SIGNAL(timeout()), this, SLOT(slotProgress()));
    00850   progressBar()->setTotalSteps(20);
    00851   m_timeStep = 700;
    00852   m_timer.start(m_timeStep);
    00853   setAutoClose(false);
    00854 }
    00855
    00856 void
    00857 KServiceProgressDialog::slotProgress()
    00858 {
    00859   int p = progressBar()->progress();
    00860   if (p == 18)
    00861   {
    00862      progressBar()->reset();
    00863      progressBar()->setProgress(1);
    00864      m_timeStep = m_timeStep * 2;
    00865      m_timer.start(m_timeStep);
    00866   }
    00867   else
    00868   {
    00869      progressBar()->setProgress(p+1);
    00870   }
    00871 }
    00872
    00873 void
    00874 KServiceProgressDialog::slotFinished()
    00875 {
    00876   progressBar()->setProgress(20);
    00877   m_timer.stop();
    00878   QTimer::singleShot(1000, this, SLOT(close()));
    00879 }
    00880
    00881 #include "kservice_p.moc"

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:03 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003