• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kio/kio
 

kio/kio

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

kio/kio

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

kio/kio

Skip menu "kio/kio"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kio/kio by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |