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

kio

kservice.cpp

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

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