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

tdeio/tdeio

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 <tdeapplication.h>
00042 #include <kdebug.h>
00043 #include <kdesktopfile.h>
00044 #include <tdeglobal.h>
00045 #include <kiconloader.h>
00046 #include <tdelocale.h>
00047 #include <tdeconfigbase.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 "tdesycoca.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 = "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-TDE-SubstituteUID") || 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 = TDEStandardDirs::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 #ifdef KDE4_MENU_SUFFIX
00252   if (kde4application) {
00253     m_strGenName += " [KDE4]";
00254   }
00255 #endif
00256   entryMap.remove("GenericName");
00257   TQString untranslatedGenericName = config->readEntryUntranslated( "GenericName" );
00258   if (!untranslatedGenericName.isEmpty())
00259     entryMap.insert("UntranslatedGenericName", untranslatedGenericName);
00260 
00261   m_lstKeywords = config->readListEntry("Keywords", ';');
00262   entryMap.remove("Keywords");
00263   d->categories = config->readListEntry("Categories", ';');
00264   entryMap.remove("Categories");
00265   m_strLibrary = config->readEntry( "X-TDE-Library" );
00266   entryMap.remove("X-TDE-Library");
00267   m_strInit = config->readEntry("X-TDE-Init" );
00268   entryMap.remove("X-TDE-Init");
00269 
00270   m_lstServiceTypes = config->readListEntry( "X-TDE-ServiceTypes" );
00271   entryMap.remove("X-TDE-ServiceTypes");
00272   // For compatibility with KDE 1.x
00273   if (!kde4application)
00274      m_lstServiceTypes += config->readListEntry( "MimeType", ';' );
00275   entryMap.remove("MimeType");
00276 
00277   if ( m_strType == "Application" && !m_lstServiceTypes.contains("Application") )
00278     // Applications implement the service type "Application" ;-)
00279     m_lstServiceTypes += "Application";
00280 
00281   TQString dcopServiceType = config->readEntry("X-DCOP-ServiceType").lower();
00282   entryMap.remove("X-DCOP-ServiceType");
00283   if (dcopServiceType == "unique")
00284      m_DCOPServiceType = DCOP_Unique;
00285   else if (dcopServiceType == "multi")
00286      m_DCOPServiceType = DCOP_Multi;
00287   else if (dcopServiceType == "wait")
00288      m_DCOPServiceType = DCOP_Wait;
00289   else
00290      m_DCOPServiceType = DCOP_None;
00291 
00292   m_strDesktopEntryName = name.lower();
00293   if (kde4application)
00294      m_strDesktopEntryName = "kde4-" + m_strDesktopEntryName;
00295 
00296   m_bAllowAsDefault = config->readBoolEntry( "AllowDefault", true );
00297   entryMap.remove("AllowDefault");
00298 
00299   m_initialPreference = config->readNumEntry( "X-TDE-InitialPreference", 1 );
00300   entryMap.remove("X-TDE-InitialPreference");
00301   if ( m_initialPreference == 1 )
00302      m_initialPreference = config->readNumEntry( "X-TDE-InitialPreference", 1 );
00303   entryMap.remove("X-TDE-InitialPreference");
00304 
00305   // Store all additional entries in the property map.
00306   // A TQMap<TQString,TQString> would be easier for this but we can't
00307   // brake BC, so we have to store it in m_mapProps.
00308 //  tqWarning("Path = %s", entryPath().latin1());
00309   TQMap<TQString,TQString>::ConstIterator it = entryMap.begin();
00310   for( ; it != entryMap.end();++it)
00311   {
00312      //tqDebug("   Key = %s Data = %s", it.key().latin1(), it.data().latin1());
00313       TQString key = it.key();
00314       if (kde4application && key=="OnlyShowIn" && it.data()=="KDE;")
00315          key = "NotShowIn";
00316       m_mapProps.insert( key, TQVariant( it.data()));
00317   }
00318 }
00319 
00320 KService::KService( TQDataStream& _str, int offset ) : KSycocaEntry( _str, offset )
00321 {
00322   d = new KServicePrivate;
00323   load( _str );
00324 }
00325 
00326 KService::~KService()
00327 {
00328   //debug("KService::~KService()");
00329   delete d;
00330 }
00331 
00332 TQPixmap KService::pixmap( TDEIcon::Group _group, int _force_size, int _state, TQString * _path ) const
00333 {
00334   TDEIconLoader *iconLoader=TDEGlobal::iconLoader();
00335   if (!iconLoader->extraDesktopThemesAdded())
00336   {
00337       TQPixmap pixmap=iconLoader->loadIcon( m_strIcon, _group, _force_size, _state, _path, true );
00338       if (!pixmap.isNull() ) return pixmap;
00339 
00340       iconLoader->addExtraDesktopThemes();
00341   }
00342 
00343   return iconLoader->loadIcon( m_strIcon, _group, _force_size, _state, _path );
00344 }
00345 
00346 void KService::load( TQDataStream& s )
00347 {
00348   // dummies are here because of fields that were removed, to keep bin compat.
00349   // Feel free to re-use, but fields for Applications only (not generic services)
00350   // should rather be added to application.desktop
00351   TQ_INT8 def, term, dummy1, dummy2;
00352   TQ_INT8 dst, initpref;
00353   TQString dummyStr1, dummyStr2;
00354   int dummyI1, dummyI2;
00355   TQ_UINT32 dummyUI32;
00356 
00357   // WARNING: IN KDE 3.x THIS NEEDS TO REMAIN COMPATIBLE WITH KDE 2.x!
00358   // !! This data structure should remain binary compatible at all times !!
00359   // You may add new fields at the end. Make sure to update the version
00360   // number in tdesycoca.h
00361   s >> m_strType >> m_strName >> m_strExec >> m_strIcon
00362     >> term >> m_strTerminalOptions
00363     >> m_strPath >> m_strComment >> m_lstServiceTypes >> def >> m_mapProps
00364     >> m_strLibrary >> dummyI1 >> dummyI2
00365     >> dst
00366     >> m_strDesktopEntryName
00367     >> dummy1 >> dummyStr1 >> initpref >> dummyStr2 >> dummy2
00368     >> m_lstKeywords >> m_strInit >> dummyUI32 >> m_strGenName
00369     >> d->categories >> d->menuId;
00370 
00371   m_bAllowAsDefault = def;
00372   m_bTerminal = term;
00373   m_DCOPServiceType = (DCOPServiceType_t) dst;
00374   m_initialPreference = initpref;
00375 
00376   m_bValid = true;
00377 }
00378 
00379 void KService::save( TQDataStream& s )
00380 {
00381   KSycocaEntry::save( s );
00382   TQ_INT8 def = m_bAllowAsDefault, initpref = m_initialPreference;
00383   TQ_INT8 term = m_bTerminal;
00384   TQ_INT8 dst = (TQ_INT8) m_DCOPServiceType;
00385   TQ_INT8 dummy1 = 0, dummy2 = 0; // see ::load
00386   TQString dummyStr1, dummyStr2;
00387   int dummyI1 = 0, dummyI2 = 0;
00388   TQ_UINT32 dummyUI32 = 0;
00389 
00390   // WARNING: IN KDE 3.x THIS NEEDS TO REMAIN COMPATIBLE WITH KDE 2.x!
00391   // !! This data structure should remain binary compatible at all times !!
00392   // You may add new fields at the end. Make sure to update the version
00393   // number in tdesycoca.h
00394   s << m_strType << m_strName << m_strExec << m_strIcon
00395     << term << m_strTerminalOptions
00396     << m_strPath << m_strComment << m_lstServiceTypes << def << m_mapProps
00397     << m_strLibrary << dummyI1 << dummyI2
00398     << dst
00399     << m_strDesktopEntryName
00400     << dummy1 << dummyStr1 << initpref << dummyStr2 << dummy2
00401     << m_lstKeywords << m_strInit << dummyUI32 << m_strGenName
00402     << d->categories << d->menuId;
00403 }
00404 
00405 bool KService::hasServiceType( const TQString& _servicetype ) const
00406 {
00407   if (!m_bValid) return false; // safety test
00408 
00409   //kdDebug(7012) << "Testing " << m_strDesktopEntryName << " for " << _servicetype << endl;
00410 
00411   KMimeType::Ptr mimePtr = KMimeType::mimeType( _servicetype );
00412   if ( mimePtr && mimePtr == KMimeType::defaultMimeTypePtr() )
00413       mimePtr = 0;
00414 
00415   bool isNumber;
00416   // For each service type we are associated with, if it doesn't
00417   // match then we try its parent service types.
00418   TQStringList::ConstIterator it = m_lstServiceTypes.begin();
00419   for( ; it != m_lstServiceTypes.end(); ++it )
00420   {
00421       (*it).toInt(&isNumber);
00422       if (isNumber)
00423          continue;
00424       //kdDebug(7012) << "    has " << (*it) << endl;
00425       KServiceType::Ptr ptr = KServiceType::serviceType( *it );
00426       if ( ptr && ptr->inherits( _servicetype ) )
00427           return true;
00428 
00429       // The mimetype inheritance ("is also") works the other way.
00430       // e.g. if we're looking for a handler for mimePtr==smb-workgroup
00431       // then a handler for inode/directory is ok.
00432       if ( mimePtr && mimePtr->is( *it ) )
00433           return true;
00434   }
00435   return false;
00436 }
00437 
00438 int KService::initialPreferenceForMimeType( const TQString& mimeType ) const
00439 {
00440   if (!m_bValid) return 0; // safety test
00441 
00442   bool isNumber;
00443 
00444   // For each service type we are associated with
00445   TQStringList::ConstIterator it = m_lstServiceTypes.begin();
00446   for( ; it != m_lstServiceTypes.end(); ++it )
00447   {
00448       (*it).toInt(&isNumber);
00449       if (isNumber)
00450          continue;
00451       //kdDebug(7012) << "    has " << (*it) << endl;
00452       KServiceType::Ptr ptr = KServiceType::serviceType( *it );
00453       if ( !ptr || !ptr->inherits( mimeType ) )
00454           continue;
00455 
00456       int initalPreference = m_initialPreference;
00457       ++it;
00458       if (it != m_lstServiceTypes.end())
00459       {
00460          int i = (*it).toInt(&isNumber);
00461          if (isNumber)
00462             initalPreference = i;
00463       }
00464       return initalPreference;
00465   }
00466 
00467   KMimeType::Ptr mimePtr = KMimeType::mimeType( mimeType );
00468   if ( mimePtr && mimePtr == KMimeType::defaultMimeTypePtr() )
00469       mimePtr = 0;
00470 
00471   // Try its parent service types.
00472   it = m_lstServiceTypes.begin();
00473   for( ; it != m_lstServiceTypes.end(); ++it )
00474   {
00475       (*it).toInt(&isNumber);
00476       if (isNumber)
00477          continue;
00478 
00479       // The mimetype inheritance ("is also") works the other way.
00480       // e.g. if we're looking for a handler for mimePtr==smb-workgroup
00481       // then a handler for inode/directory is ok.
00482       if ( !mimePtr || !mimePtr->is( *it ) )
00483           continue;
00484 
00485       int initalPreference = m_initialPreference;
00486       ++it;
00487       if (it != m_lstServiceTypes.end())
00488       {
00489          int i = (*it).toInt(&isNumber);
00490          if (isNumber)
00491             initalPreference = i;
00492       }
00493       return initalPreference;
00494   }
00495   return 0;
00496 }
00497 
00498 class KServiceReadProperty : public TDEConfigBase
00499 {
00500 public:
00501    KServiceReadProperty(const TQString &_key, const TQCString &_value)
00502     : key(_key), value(_value) { }
00503 
00504    bool internalHasGroup(const TQCString &) const { /*tqDebug("hasGroup(const TQCString &)");*/ return false; }
00505 
00506    TQStringList groupList() const { return TQStringList(); }
00507 
00508    TQMap<TQString,TQString> entryMap(const TQString &group) const
00509       { Q_UNUSED(group); return TQMap<TQString,TQString>(); }
00510 
00511    void reparseConfiguration() { }
00512 
00513    KEntryMap internalEntryMap( const TQString &pGroup) const
00514    { Q_UNUSED(pGroup); return KEntryMap(); }
00515 
00516    KEntryMap internalEntryMap() const { return KEntryMap(); }
00517 
00518    void putData(const KEntryKey &_key, const KEntry& _data, bool _checkGroup)
00519    { Q_UNUSED(_key); Q_UNUSED(_data); Q_UNUSED(_checkGroup); }
00520 
00521    KEntry lookupData(const KEntryKey &_key) const
00522    { Q_UNUSED(_key); KEntry entry; entry.mValue = value; return entry; }
00523 protected:
00524    TQString key;
00525    TQCString value;
00526 };
00527 
00528 TQVariant KService::property( const TQString& _name) const
00529 {
00530    return property( _name, TQVariant::Invalid);
00531 }
00532 
00533 // Return a string TQVariant if string isn't null, and invalid variant otherwise
00534 // (the variant must be invalid if the field isn't in the .desktop file)
00535 // This allows trader queries like "exist Library" to work.
00536 static TQVariant makeStringVariant( const TQString& string )
00537 {
00538     // Using isEmpty here would be wrong.
00539     // Empty is "specified but empty", null is "not specified" (in the .desktop file)
00540     return string.isNull() ? TQVariant() : TQVariant( string );
00541 }
00542 
00543 TQVariant KService::property( const TQString& _name, TQVariant::Type t ) const
00544 {
00545   if ( _name == "Type" )
00546     return TQVariant( m_strType ); // can't be null
00547   else if ( _name == "Name" )
00548     return TQVariant( m_strName ); // can't be null
00549   else if ( _name == "Exec" )
00550     return makeStringVariant( m_strExec );
00551   else if ( _name == "Icon" )
00552     return makeStringVariant( m_strIcon );
00553   else if ( _name == "Terminal" )
00554     return TQVariant( static_cast<int>(m_bTerminal) );
00555   else if ( _name == "TerminalOptions" )
00556     return makeStringVariant( m_strTerminalOptions );
00557   else if ( _name == "Path" )
00558     return makeStringVariant( m_strPath );
00559   else if ( _name == "Comment" )
00560     return makeStringVariant( m_strComment );
00561   else if ( _name == "GenericName" )
00562     return makeStringVariant( m_strGenName );
00563   else if ( _name == "ServiceTypes" )
00564     return TQVariant( m_lstServiceTypes );
00565   else if ( _name == "AllowAsDefault" )
00566     return TQVariant( static_cast<int>(m_bAllowAsDefault) );
00567   else if ( _name == "InitialPreference" )
00568     return TQVariant( m_initialPreference );
00569   else if ( _name == "Library" )
00570     return makeStringVariant( m_strLibrary );
00571   else if ( _name == "DesktopEntryPath" ) // can't be null
00572     return TQVariant( entryPath() );
00573   else if ( _name == "DesktopEntryName")
00574     return TQVariant( m_strDesktopEntryName ); // can't be null
00575   else if ( _name == "Categories")
00576     return TQVariant( d->categories );
00577   else if ( _name == "Keywords")
00578     return TQVariant( m_lstKeywords );
00579 
00580   // Ok we need to convert the property from a TQString to its real type.
00581   // Maybe the caller helped us.
00582   if (t == TQVariant::Invalid)
00583   {
00584     // No luck, let's ask KServiceTypeFactory what the type of this property
00585     // is supposed to be.
00586     t = KServiceTypeFactory::self()->findPropertyTypeByName(_name);
00587     if (t == TQVariant::Invalid)
00588     {
00589       kdDebug(7012) << "Request for unknown property '" << _name << "'\n";
00590       return TQVariant(); // Unknown property: Invalid variant.
00591     }
00592   }
00593 
00594   // Then we use a homebuild class based on TDEConfigBase to convert the TQString.
00595   // For some often used property types we do the conversion ourselves.
00596   TQMap<TQString,TQVariant>::ConstIterator it = m_mapProps.find( _name );
00597   if ( (it == m_mapProps.end()) || (!it.data().isValid()))
00598   {
00599      //kdDebug(7012) << "Property not found " << _name << endl;
00600      return TQVariant(); // No property set.
00601   }
00602 
00603   switch(t)
00604   {
00605     case TQVariant::String:
00606         return it.data();
00607     case TQVariant::Bool:
00608     case TQVariant::Int:
00609         {
00610            TQString aValue = it.data().toString();
00611            int val = 0;
00612            if (aValue == "true" || aValue == "on" || aValue == "yes")
00613               val = 1;
00614            else
00615            {
00616               bool bOK;
00617               val = aValue.toInt( &bOK );
00618               if( !bOK )
00619                  val = 0;
00620            }
00621            if (t == TQVariant::Bool)
00622            {
00623                return TQVariant((bool)val, 1);
00624            }
00625            return TQVariant(val);
00626         }
00627     default:
00628         // All others
00629         KServiceReadProperty ksrp(_name, it.data().toString().utf8());
00630         return ksrp.readPropertyEntry(_name, t);
00631   }
00632 }
00633 
00634 TQStringList KService::propertyNames() const
00635 {
00636   TQStringList res;
00637 
00638   TQMap<TQString,TQVariant>::ConstIterator it = m_mapProps.begin();
00639   for( ; it != m_mapProps.end(); ++it )
00640     res.append( it.key() );
00641 
00642   res.append( "Type" );
00643   res.append( "Name" );
00644   res.append( "Comment" );
00645   res.append( "GenericName" );
00646   res.append( "Icon" );
00647   res.append( "Exec" );
00648   res.append( "Terminal" );
00649   res.append( "TerminalOptions" );
00650   res.append( "Path" );
00651   res.append( "ServiceTypes" );
00652   res.append( "AllowAsDefault" );
00653   res.append( "InitialPreference" );
00654   res.append( "Library" );
00655   res.append( "DesktopEntryPath" );
00656   res.append( "DesktopEntryName" );
00657   res.append( "Keywords" );
00658   res.append( "Categories" );
00659 
00660   return res;
00661 }
00662 
00663 KService::List KService::allServices()
00664 {
00665   return KServiceFactory::self()->allServices();
00666 }
00667 
00668 KService::Ptr KService::serviceByName( const TQString& _name )
00669 {
00670   KService * s = KServiceFactory::self()->findServiceByName( _name );
00671   return KService::Ptr( s );
00672 }
00673 
00674 KService::Ptr KService::serviceByDesktopPath( const TQString& _name )
00675 {
00676   KService * s = KServiceFactory::self()->findServiceByDesktopPath( _name );
00677   return KService::Ptr( s );
00678 }
00679 
00680 KService::Ptr KService::serviceByDesktopName( const TQString& _name )
00681 {
00682   KService * s = KServiceFactory::self()->findServiceByDesktopName( _name.lower() );
00683   if (!s && !_name.startsWith("tde-"))
00684      s = KServiceFactory::self()->findServiceByDesktopName( "tde-"+_name.lower() );
00685   return KService::Ptr( s );
00686 }
00687 
00688 KService::Ptr KService::serviceByMenuId( const TQString& _name )
00689 {
00690   KService * s = KServiceFactory::self()->findServiceByMenuId( _name );
00691   return KService::Ptr( s );
00692 }
00693 
00694 KService::Ptr KService::serviceByStorageId( const TQString& _storageId )
00695 {
00696   KService::Ptr service = KService::serviceByMenuId( _storageId );
00697   if (service)
00698      return service;
00699 
00700   service = KService::serviceByDesktopPath(_storageId);
00701   if (service)
00702      return service;
00703 
00704   if (!TQDir::isRelativePath(_storageId) && TQFile::exists(_storageId))
00705      return new KService(_storageId);
00706 
00707   TQString tmp = _storageId;
00708   tmp = tmp.mid(tmp.findRev('/')+1); // Strip dir
00709 
00710   if (tmp.endsWith(".desktop"))
00711      tmp.truncate(tmp.length()-8);
00712 
00713   if (tmp.endsWith(".kdelnk"))
00714      tmp.truncate(tmp.length()-7);
00715 
00716   service = KService::serviceByDesktopName(tmp);
00717 
00718   return service;
00719 }
00720 
00721 KService::List KService::allInitServices()
00722 {
00723   return KServiceFactory::self()->allInitServices();
00724 }
00725 
00726 bool KService::substituteUid() const {
00727   bool suid = false;
00728   TQVariant v;
00729   v = property("X-TDE-SubstituteUID", TQVariant::Bool);
00730   if (v.isValid()) {
00731     if (v.toBool()) suid = true;
00732   }
00733   v = property("X-KDE-SubstituteUID", TQVariant::Bool);
00734   if (v.isValid()) {
00735     if (v.toBool()) suid = true;
00736   }
00737   return suid;
00738 }
00739 
00740 TQString KService::username() const {
00741   // See also KDesktopFile::tryExec()
00742   TQString user;
00743   TQVariant v = property("X-TDE-Username", TQVariant::String);
00744   user = v.isValid() ? v.toString() : TQString::null;
00745   if (user.isEmpty())
00746      user = ::getenv("ADMIN_ACCOUNT");
00747   if (user.isEmpty())
00748      user = "root";
00749   return user;
00750 }
00751 
00752 bool KService::noDisplay() const {
00753   TQMap<TQString,TQVariant>::ConstIterator it = m_mapProps.find( "NoDisplay" );
00754   if ( (it != m_mapProps.end()) && (it.data().isValid()))
00755   {
00756      TQString aValue = it.data().toString().lower();
00757      if (aValue == "true" || aValue == "on" || aValue == "yes")
00758         return true;
00759   }
00760 
00761   it = m_mapProps.find( "OnlyShowIn" );
00762   if ( (it != m_mapProps.end()) && (it.data().isValid()))
00763   {
00764      TQString aValue = it.data().toString();
00765      TQStringList aList = TQStringList::split(';', aValue);
00766 #ifdef WITH_OLD_XDG_STD
00767      if ((!aList.contains("TDE")) && (!aList.contains("KDE")))
00768         return true;
00769 #else
00770      if (!aList.contains("TDE"))
00771         return true;
00772 #endif
00773   }
00774 
00775   it = m_mapProps.find( "NotShowIn" );
00776   if ( (it != m_mapProps.end()) && (it.data().isValid()))
00777   {
00778      TQString aValue = it.data().toString();
00779      TQStringList aList = TQStringList::split(';', aValue);
00780 #ifdef WITH_OLD_XDG_STD
00781      if ((aList.contains("TDE")) || (aList.contains("KDE")))
00782         return true;
00783 #else
00784      if (aList.contains("TDE"))
00785         return true;
00786 #endif
00787   }
00788 
00789   if (!kapp->authorizeControlModule(d->menuId))
00790      return true;
00791 
00792   return false;
00793 }
00794 
00795 TQString KService::untranslatedGenericName() const {
00796   TQVariant v = property("UntranslatedGenericName", TQVariant::String);
00797   return v.isValid() ? v.toString() : TQString::null;
00798 }
00799 
00800 bool KService::SuSEunimportant() const {
00801   TQMap<TQString,TQVariant>::ConstIterator it = m_mapProps.find( "X-SuSE-Unimportant" );
00802   if ( (it == m_mapProps.end()) || (!it.data().isValid()))
00803   {
00804      return false;
00805   }
00806 
00807   TQString aValue = it.data().toString();
00808   if (aValue == "true" || aValue == "on" || aValue == "yes")
00809      return true;
00810   else
00811      return false;
00812 }
00813 
00814 TQString KService::parentApp() const {
00815   TQMap<TQString,TQVariant>::ConstIterator it = m_mapProps.find( "X-TDE-ParentApp" );
00816   if ( (it == m_mapProps.end()) || (!it.data().isValid()))
00817   {
00818      return TQString::null;
00819   }
00820 
00821   return it.data().toString();
00822 }
00823 
00824 bool KService::allowMultipleFiles() const {
00825   // Can we pass multiple files on the command line or do we have to start the application for every single file ?
00826   if ( m_strExec.find( "%F" ) != -1 || m_strExec.find( "%U" ) != -1 ||
00827        m_strExec.find( "%N" ) != -1 || m_strExec.find( "%D" ) != -1 )
00828     return true;
00829   else
00830     return false;
00831 }
00832 
00833 TQStringList KService::categories() const
00834 {
00835   return d->categories;
00836 }
00837 
00838 TQString KService::menuId() const
00839 {
00840   return d->menuId;
00841 }
00842 
00843 void KService::setMenuId(const TQString &menuId)
00844 {
00845   d->menuId = menuId;
00846 }
00847 
00848 TQString KService::storageId() const
00849 {
00850   if (!d->menuId.isEmpty())
00851      return d->menuId;
00852   return entryPath();
00853 }
00854 
00855 TQString KService::locateLocal()
00856 {
00857   if (d->menuId.isEmpty() || desktopEntryPath().startsWith(".hidden") ||
00858       (TQDir::isRelativePath(desktopEntryPath()) && d->categories.isEmpty()))
00859      return KDesktopFile::locateLocal(desktopEntryPath());
00860 
00861   return ::locateLocal("xdgdata-apps", d->menuId);
00862 }
00863 
00864 TQString KService::newServicePath(bool showInMenu, const TQString &suggestedName,
00865                                 TQString *menuId, const TQStringList *reservedMenuIds)
00866 {
00867    TQString base = suggestedName;
00868    if (!showInMenu)
00869      base.prepend("tde-");
00870 
00871    TQString result;
00872    for(int i = 1; true; i++)
00873    {
00874       if (i == 1)
00875          result = base + ".desktop";
00876       else
00877          result = base + TQString("-%1.desktop").arg(i);
00878 
00879       if (reservedMenuIds && reservedMenuIds->contains(result))
00880          continue;
00881 
00882       // Lookup service by menu-id
00883       KService::Ptr s = serviceByMenuId(result);
00884       if (s)
00885          continue;
00886 
00887       if (showInMenu)
00888       {
00889          if (!locate("xdgdata-apps", result).isEmpty())
00890             continue;
00891       }
00892       else
00893       {
00894          TQString file = result.mid(4); // Strip "tde-"
00895          if (!locate("apps", ".hidden/"+file).isEmpty())
00896             continue;
00897       }
00898 
00899       break;
00900    }
00901    if (menuId)
00902       *menuId = result;
00903 
00904    if (showInMenu)
00905    {
00906        return ::locateLocal("xdgdata-apps", result);
00907    }
00908    else
00909    {
00910        TQString file = result.mid(4); // Strip "tde-"
00911        return ::locateLocal("apps", ".hidden/"+file);
00912    }
00913 }
00914 
00915 
00916 void KService::virtual_hook( int id, void* data )
00917 { KSycocaEntry::virtual_hook( id, data ); }
00918 
00919 
00920 void KService::rebuildKSycoca(TQWidget *parent)
00921 {
00922   KServiceProgressDialog dlg(parent, "tdesycoca_progress",
00923                       i18n("Updating System Configuration"),
00924                       i18n("Updating system configuration."));
00925 
00926   TQByteArray data;
00927   DCOPClient *client = kapp->dcopClient();
00928 
00929   int result = client->callAsync("kded", "tdebuildsycoca", "recreate()",
00930                data, TQT_TQOBJECT(&dlg), TQT_SLOT(slotFinished()));
00931 
00932   if (result)
00933   {
00934      dlg.exec();
00935   }
00936 }
00937 
00938 KServiceProgressDialog::KServiceProgressDialog(TQWidget *parent, const char *name,
00939                           const TQString &caption, const TQString &text)
00940  : KProgressDialog(parent, name, caption, text, true)
00941 {
00942   connect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotProgress()));
00943   progressBar()->setTotalSteps(20);
00944   m_timeStep = 700;
00945   m_timer.start(m_timeStep);
00946   setAutoClose(false);
00947 }
00948 
00949 void
00950 KServiceProgressDialog::slotProgress()
00951 {
00952   int p = progressBar()->progress();
00953   if (p == 18)
00954   {
00955      progressBar()->reset();
00956      progressBar()->setProgress(1);
00957      m_timeStep = m_timeStep * 2;
00958      m_timer.start(m_timeStep);
00959   }
00960   else
00961   {
00962      progressBar()->setProgress(p+1);
00963   }
00964 }
00965 
00966 void
00967 KServiceProgressDialog::slotFinished()
00968 {
00969   progressBar()->setProgress(20);
00970   m_timer.stop();
00971   TQTimer::singleShot(1000, this, TQT_SLOT(close()));
00972 }
00973 
00974 #include "kservice_p.moc"

tdeio/tdeio

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

tdeio/tdeio

Skip menu "tdeio/tdeio"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeio/tdeio by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.