00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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");
00115 entryMap.remove("Version");
00116
00117 m_bDeleted = config->readBoolEntry( "Hidden", false );
00118 entryMap.remove("Hidden");
00119 if (m_bDeleted)
00120 {
00121
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
00133
00134 m_bValid = false;
00135 return;
00136 }
00137
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
00151
00152
00153
00154
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
00166 if (!config->tryExec()) {
00167
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" ));
00243 entryMap.remove("Terminal");
00244 m_strTerminalOptions = config->readEntry( "TerminalOptions" );
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
00273 if (!kde4application)
00274 m_lstServiceTypes += config->readListEntry( "MimeType", ';' );
00275 entryMap.remove("MimeType");
00276
00277 if ( m_strType == "Application" && !m_lstServiceTypes.contains("Application") )
00278
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
00306
00307
00308
00309 TQMap<TQString,TQString>::ConstIterator it = entryMap.begin();
00310 for( ; it != entryMap.end();++it)
00311 {
00312
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
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
00349
00350
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
00358
00359
00360
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;
00386 TQString dummyStr1, dummyStr2;
00387 int dummyI1 = 0, dummyI2 = 0;
00388 TQ_UINT32 dummyUI32 = 0;
00389
00390
00391
00392
00393
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;
00408
00409
00410
00411 KMimeType::Ptr mimePtr = KMimeType::mimeType( _servicetype );
00412 if ( mimePtr && mimePtr == KMimeType::defaultMimeTypePtr() )
00413 mimePtr = 0;
00414
00415 bool isNumber;
00416
00417
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
00425 KServiceType::Ptr ptr = KServiceType::serviceType( *it );
00426 if ( ptr && ptr->inherits( _servicetype ) )
00427 return true;
00428
00429
00430
00431
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;
00441
00442 bool isNumber;
00443
00444
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
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
00472 it = m_lstServiceTypes.begin();
00473 for( ; it != m_lstServiceTypes.end(); ++it )
00474 {
00475 (*it).toInt(&isNumber);
00476 if (isNumber)
00477 continue;
00478
00479
00480
00481
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 { 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
00534
00535
00536 static TQVariant makeStringVariant( const TQString& string )
00537 {
00538
00539
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 );
00547 else if ( _name == "Name" )
00548 return TQVariant( m_strName );
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" )
00572 return TQVariant( entryPath() );
00573 else if ( _name == "DesktopEntryName")
00574 return TQVariant( m_strDesktopEntryName );
00575 else if ( _name == "Categories")
00576 return TQVariant( d->categories );
00577 else if ( _name == "Keywords")
00578 return TQVariant( m_lstKeywords );
00579
00580
00581
00582 if (t == TQVariant::Invalid)
00583 {
00584
00585
00586 t = KServiceTypeFactory::self()->findPropertyTypeByName(_name);
00587 if (t == TQVariant::Invalid)
00588 {
00589 kdDebug(7012) << "Request for unknown property '" << _name << "'\n";
00590 return TQVariant();
00591 }
00592 }
00593
00594
00595
00596 TQMap<TQString,TQVariant>::ConstIterator it = m_mapProps.find( _name );
00597 if ( (it == m_mapProps.end()) || (!it.data().isValid()))
00598 {
00599
00600 return TQVariant();
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
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("kde-"))
00684 s = KServiceFactory::self()->findServiceByDesktopName( "kde-"+_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);
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
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
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("kde-");
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
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);
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);
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"