00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kservice.h"
00021 #include "kservice_p.h"
00022
00023 #include <sys/types.h>
00024 #include <sys/stat.h>
00025
00026 #include <stddef.h>
00027 #include <unistd.h>
00028 #include <stdlib.h>
00029
00030 #include <QtCore/QCharRef>
00031 #include <QtCore/QFile>
00032 #include <QtCore/QDir>
00033 #include <QtCore/QMap>
00034
00035 #include <kauthorized.h>
00036 #include <kdebug.h>
00037 #include <kdesktopfile.h>
00038 #include <kglobal.h>
00039 #include <kconfiggroup.h>
00040 #include <kstandarddirs.h>
00041
00042 #include "kservicefactory.h"
00043 #include "kservicetypefactory.h"
00044
00045 QDataStream &operator<<(QDataStream &s, const KService::ServiceTypeAndPreference &st)
00046 {
00047 s << st.preference << st.serviceType;
00048 return s;
00049 }
00050 QDataStream &operator>>(QDataStream &s, KService::ServiceTypeAndPreference &st)
00051 {
00052 s >> st.preference >> st.serviceType;
00053 return s;
00054 }
00055
00056 void KServicePrivate::init( const KDesktopFile *config, KService* q )
00057 {
00058 const QString entryPath = q->entryPath();
00059 bool absPath = !QDir::isRelativePath(entryPath);
00060
00061
00062 const KConfigGroup desktopGroup = const_cast<KDesktopFile*>(config)->desktopGroup();
00063 QMap<QString, QString> entryMap = desktopGroup.entryMap();
00064
00065 entryMap.remove("Encoding");
00066 entryMap.remove("Version");
00067
00068 q->setDeleted( desktopGroup.readEntry("Hidden", false) );
00069 entryMap.remove("Hidden");
00070 if ( q->isDeleted() ) {
00071 m_bValid = false;
00072 return;
00073 }
00074
00075 m_strName = config->readName();
00076 entryMap.remove("Name");
00077 if ( m_strName.isEmpty() )
00078 {
00079
00080 m_strName = entryPath;
00081 int i = m_strName.lastIndexOf('/');
00082 m_strName = m_strName.mid(i+1);
00083 i = m_strName.lastIndexOf('.');
00084 if (i != -1)
00085 m_strName = m_strName.left(i);
00086 }
00087
00088 m_strType = config->readType();
00089 entryMap.remove("Type");
00090 if ( m_strType.isEmpty() )
00091 {
00092
00093
00094
00095
00096
00097 m_strType = "Application";
00098 } else if ( m_strType != "Application" && m_strType != "Service" )
00099 {
00100 kWarning(7012) << "The desktop entry file " << entryPath
00101 << " has Type=" << m_strType
00102 << " instead of \"Application\" or \"Service\"" << endl;
00103 m_bValid = false;
00104 return;
00105 }
00106
00107
00108
00109 m_strExec = desktopGroup.readEntry( "Exec", QString() );
00110 entryMap.remove("Exec");
00111
00112 if ( m_strType == "Application" ) {
00113
00114 if (m_strExec.isEmpty()) {
00115 kWarning(7012) << "The desktop entry file " << entryPath
00116 << " has Type=" << m_strType
00117 << " but no Exec line" << endl;
00118 m_bValid = false;
00119 return;
00120 }
00121 }
00122
00123
00124 if (!config->tryExec()) {
00125 q->setDeleted( true );
00126 m_bValid = false;
00127 return;
00128 }
00129
00130 QString resource = config->resource();
00131
00132 if ( (m_strType == "Application") &&
00133 (!resource.isEmpty()) &&
00134 (resource != "apps") &&
00135 !absPath)
00136 {
00137 kWarning(7012) << "The desktop entry file " << entryPath
00138 << " has Type=" << m_strType << " but is located under \"" << resource
00139 << "\" instead of \"apps\"" << endl;
00140 m_bValid = false;
00141 return;
00142 }
00143
00144 if ( (m_strType == "Service") &&
00145 (!resource.isEmpty()) &&
00146 (resource != "services") &&
00147 !absPath)
00148 {
00149 kWarning(7012) << "The desktop entry file " << entryPath
00150 << " has Type=" << m_strType << " but is located under \"" << resource
00151 << "\" instead of \"services\"";
00152 m_bValid = false;
00153 return;
00154 }
00155
00156 QString _name = entryPath;
00157 int pos = _name.lastIndexOf('/');
00158 if (pos != -1)
00159 _name = _name.mid(pos+1);
00160 pos = _name.indexOf('.');
00161 if (pos != -1)
00162 _name = _name.left(pos);
00163
00164 m_strIcon = config->readIcon();
00165 entryMap.remove("Icon");
00166 m_bTerminal = desktopGroup.readEntry( "Terminal", false);
00167 entryMap.remove("Terminal");
00168 m_strTerminalOptions = desktopGroup.readEntry( "TerminalOptions" );
00169 entryMap.remove("TerminalOptions");
00170 m_strPath = config->readPath();
00171 entryMap.remove("Path");
00172 m_strComment = config->readComment();
00173 entryMap.remove("Comment");
00174 m_strGenName = config->readGenericName();
00175 entryMap.remove("GenericName");
00176 QString _untranslatedGenericName = desktopGroup.readEntryUntranslated( "GenericName" );
00177 if (!_untranslatedGenericName.isEmpty())
00178 entryMap.insert("UntranslatedGenericName", _untranslatedGenericName);
00179
00180 m_lstKeywords = desktopGroup.readEntry("Keywords", QStringList());
00181 entryMap.remove("Keywords");
00182 m_lstKeywords += desktopGroup.readEntry("X-KDE-Keywords", QStringList());
00183 entryMap.remove("X-KDE-Keywords");
00184 categories = desktopGroup.readXdgListEntry("Categories");
00185 entryMap.remove("Categories");
00186 m_strLibrary = desktopGroup.readEntry( "X-KDE-Library" );
00187 entryMap.remove("X-KDE-Library");
00188
00189 QStringList lstServiceTypes = desktopGroup.readEntry( "ServiceTypes", QStringList() );
00190 entryMap.remove("ServiceTypes");
00191 lstServiceTypes += desktopGroup.readEntry( "X-KDE-ServiceTypes", QStringList() );
00192 entryMap.remove("X-KDE-ServiceTypes");
00193 lstServiceTypes += desktopGroup.readXdgListEntry( "MimeType" );
00194 entryMap.remove("MimeType");
00195
00196 if ( m_strType == "Application" && !lstServiceTypes.contains("Application") )
00197
00198 lstServiceTypes += "Application";
00199
00200 m_initialPreference = desktopGroup.readEntry( "InitialPreference", 1 );
00201 entryMap.remove("InitialPreference");
00202
00203
00204
00205 m_serviceTypes.reserve(lstServiceTypes.size());
00206 QListIterator<QString> st_it(lstServiceTypes);
00207 while ( st_it.hasNext() ) {
00208 const QString st = st_it.next();
00209 if (st.isEmpty()) {
00210 kWarning(7012) << "The desktop entry file" << entryPath
00211 << "has an empty mimetype!";
00212 continue;
00213 }
00214 int initialPreference = m_initialPreference;
00215 if ( st_it.hasNext() ) {
00216
00217 bool isNumber;
00218 const int val = st_it.peekNext().toInt(&isNumber);
00219 if (isNumber) {
00220 initialPreference = val;
00221 st_it.next();
00222 }
00223 }
00224 m_serviceTypes.push_back(KService::ServiceTypeAndPreference(initialPreference, st));
00225 }
00226
00227 if (entryMap.contains("Actions")) {
00228 parseActions(config, q);
00229 }
00230
00231 QString dbusStartupType = desktopGroup.readEntry("X-DBUS-StartupType").toLower();
00232 entryMap.remove("X-DBUS-StartupType");
00233 if (dbusStartupType == "unique")
00234 m_DBUSStartusType = KService::DBusUnique;
00235 else if (dbusStartupType == "multi")
00236 m_DBUSStartusType = KService::DBusMulti;
00237 else if (dbusStartupType == "wait")
00238 m_DBUSStartusType = KService::DBusWait;
00239 else
00240 m_DBUSStartusType = KService::DBusNone;
00241
00242 m_strDesktopEntryName = _name.toLower();
00243
00244 m_bAllowAsDefault = desktopGroup.readEntry("AllowDefault", true);
00245 entryMap.remove("AllowDefault");
00246
00247
00248 QMap<QString,QString>::Iterator entry = entryMap.find("X-KDE-PluginInfo-Category");
00249 if (entry != entryMap.end()) {
00250 const QString& key = entry.key();
00251 m_mapProps.insert(key, QVariant(desktopGroup.readEntryUntranslated(key)));
00252 m_mapProps.insert(key + "-Translated", QVariant(*entry));
00253 entryMap.erase(entry);
00254 }
00255
00256
00257
00258
00259
00260 QMap<QString,QString>::ConstIterator it = entryMap.begin();
00261 for( ; it != entryMap.end();++it) {
00262 const QString key = it.key();
00263
00264 if (!key.contains('[')) {
00265
00266 m_mapProps.insert(key, QVariant(*it));
00267 }
00268 }
00269 }
00270
00271 void KServicePrivate::parseActions(const KDesktopFile *config, KService* q)
00272 {
00273 const QStringList keys = config->readActions();
00274 if (keys.isEmpty())
00275 return;
00276
00277 QStringList::ConstIterator it = keys.begin();
00278 const QStringList::ConstIterator end = keys.end();
00279 for ( ; it != end; ++it ) {
00280 const QString group = *it;
00281 if (group == "_SEPARATOR_") {
00282 m_actions.append(KServiceAction(group, QString(), QString(), QString(), false));
00283 continue;
00284 }
00285
00286 if (config->hasActionGroup(group)) {
00287 const KConfigGroup cg = config->actionGroup(group);
00288 if ( !cg.hasKey( "Name" ) || !cg.hasKey( "Exec" ) ) {
00289 kWarning(7012) << "The action" << group << "in the desktop file" << q->entryPath()
00290 << "has no Name or no Exec key";
00291 } else {
00292 m_actions.append(KServiceAction(group,
00293 cg.readEntry("Name"),
00294 cg.readEntry("Icon"),
00295 cg.readEntry("Exec"),
00296 cg.readEntry("NoDisplay", false)));
00297 }
00298 } else {
00299 kWarning(7012) << "The desktop file" << q->entryPath()
00300 << "references the action" << group << "but doesn't define it";
00301 }
00302 }
00303 }
00304
00305 void KServicePrivate::load(QDataStream& s)
00306 {
00307 qint8 def, term;
00308 qint8 dst, initpref;
00309 QStringList dummyList;
00310
00311
00312
00313
00314
00315 s >> m_strType >> m_strName >> m_strExec >> m_strIcon
00316 >> term >> m_strTerminalOptions
00317 >> m_strPath >> m_strComment >> dummyList >> def >> m_mapProps
00318 >> m_strLibrary
00319 >> dst
00320 >> m_strDesktopEntryName
00321 >> initpref
00322 >> m_lstKeywords >> m_strGenName
00323 >> categories >> menuId >> m_actions >> m_serviceTypes;
00324
00325 m_bAllowAsDefault = (bool)def;
00326 m_bTerminal = (bool)term;
00327 m_DBUSStartusType = (KService::DBusStartupType) dst;
00328 m_initialPreference = initpref;
00329
00330 m_bValid = true;
00331 }
00332
00333 void KServicePrivate::save(QDataStream& s)
00334 {
00335 KSycocaEntryPrivate::save( s );
00336 qint8 def = m_bAllowAsDefault, initpref = m_initialPreference;
00337 qint8 term = m_bTerminal;
00338 qint8 dst = (qint8) m_DBUSStartusType;
00339
00340
00341
00342
00343
00344 s << m_strType << m_strName << m_strExec << m_strIcon
00345 << term << m_strTerminalOptions
00346 << m_strPath << m_strComment << QStringList() << def << m_mapProps
00347 << m_strLibrary
00348 << dst
00349 << m_strDesktopEntryName
00350 << initpref
00351 << m_lstKeywords << m_strGenName
00352 << categories << menuId << m_actions << m_serviceTypes;
00353 }
00354
00356
00357 KService::KService( const QString & _name, const QString &_exec, const QString &_icon)
00358 : KSycocaEntry(*new KServicePrivate(QString()))
00359 {
00360 Q_D(KService);
00361 d->m_strType = "Application";
00362 d->m_strName = _name;
00363 d->m_strExec = _exec;
00364 d->m_strIcon = _icon;
00365 d->m_bTerminal = false;
00366 d->m_bAllowAsDefault = true;
00367 d->m_initialPreference = 10;
00368 }
00369
00370
00371 KService::KService( const QString & _fullpath )
00372 : KSycocaEntry(*new KServicePrivate(_fullpath))
00373 {
00374 Q_D(KService);
00375
00376 KDesktopFile config( _fullpath );
00377 d->init(&config, this);
00378 }
00379
00380 KService::KService( const KDesktopFile *config )
00381 : KSycocaEntry(*new KServicePrivate(config->fileName()))
00382 {
00383 Q_D(KService);
00384
00385 d->init(config, this);
00386 }
00387
00388 KService::KService( QDataStream& _str, int _offset )
00389 : KSycocaEntry(*new KServicePrivate(_str, _offset))
00390 {
00391 }
00392
00393 KService::~KService()
00394 {
00395 }
00396
00397 bool KService::hasServiceType( const QString& serviceType ) const
00398 {
00399 Q_D(const KService);
00400
00401 if (!d->m_bValid) return false;
00402 const KServiceType::Ptr ptr = KServiceType::serviceType( serviceType );
00403
00404
00405 return hasMimeType( ptr.data() );
00406 }
00407
00408 bool KService::hasMimeType( const KServiceType* ptr ) const
00409 {
00410 Q_D(const KService);
00411 if (!ptr) return false;
00412 int serviceOffset = offset();
00413
00414
00415
00416 if ( serviceOffset )
00417 return KServiceFactory::self()->hasOffer( ptr->offset(), ptr->serviceOffersOffset(), serviceOffset );
00418
00419
00420
00421
00422 QVector<ServiceTypeAndPreference>::ConstIterator it = d->m_serviceTypes.begin();
00423 for( ; it != d->m_serviceTypes.end(); ++it ) {
00424 const QString& st = (*it).serviceType;
00425
00426 if ( st == ptr->name() )
00427 return true;
00428
00429 KServiceType::Ptr p = KServiceType::serviceType( st );
00430 if ( p && p->inherits( ptr->name() ) )
00431 return true;
00432
00433
00434
00435
00436 }
00437 return false;
00438 }
00439
00440 QVariant KServicePrivate::property( const QString& _name) const
00441 {
00442 return property( _name, QVariant::Invalid);
00443 }
00444
00445
00446
00447
00448 static QVariant makeStringVariant( const QString& string )
00449 {
00450
00451
00452 return string.isNull() ? QVariant() : QVariant( string );
00453 }
00454
00455 QVariant KService::property( const QString& _name, QVariant::Type t ) const
00456 {
00457 Q_D(const KService);
00458 return d->property(_name, t);
00459 }
00460
00461 QVariant KServicePrivate::property( const QString& _name, QVariant::Type t ) const
00462 {
00463 if ( _name == "Type" )
00464 return QVariant( m_strType );
00465 else if ( _name == "Name" )
00466 return QVariant( m_strName );
00467 else if ( _name == "Exec" )
00468 return makeStringVariant( m_strExec );
00469 else if ( _name == "Icon" )
00470 return makeStringVariant( m_strIcon );
00471 else if ( _name == "Terminal" )
00472 return QVariant( m_bTerminal );
00473 else if ( _name == "TerminalOptions" )
00474 return makeStringVariant( m_strTerminalOptions );
00475 else if ( _name == "Path" )
00476 return makeStringVariant( m_strPath );
00477 else if ( _name == "Comment" )
00478 return makeStringVariant( m_strComment );
00479 else if ( _name == "GenericName" )
00480 return makeStringVariant( m_strGenName );
00481 else if ( _name == "ServiceTypes" )
00482 return QVariant( serviceTypes() );
00483 else if ( _name == "AllowAsDefault" )
00484 return QVariant( m_bAllowAsDefault );
00485 else if ( _name == "InitialPreference" )
00486 return QVariant( m_initialPreference );
00487 else if ( _name == "Library" )
00488 return makeStringVariant( m_strLibrary );
00489 else if ( _name == "DesktopEntryPath" )
00490 return QVariant( path );
00491 else if ( _name == "DesktopEntryName")
00492 return QVariant( m_strDesktopEntryName );
00493 else if ( _name == "Categories")
00494 return QVariant( categories );
00495 else if ( _name == "Keywords")
00496 return QVariant( m_lstKeywords );
00497
00498
00499
00500 if (t == QVariant::Invalid)
00501 {
00502
00503
00504 t = KServiceTypeFactory::self()->findPropertyTypeByName(_name);
00505 if (t == QVariant::Invalid)
00506 {
00507 kDebug(7012) << "Request for unknown property '" << _name << "'\n";
00508 return QVariant();
00509 }
00510 }
00511
00512 QMap<QString,QVariant>::ConstIterator it = m_mapProps.find( _name );
00513 if ( (it == m_mapProps.end()) || (!it->isValid()))
00514 {
00515
00516 return QVariant();
00517 }
00518
00519 switch(t)
00520 {
00521 case QVariant::String:
00522 return *it;
00523 default:
00524
00525
00526
00527 return KConfigGroup::convertToQVariant(_name.toUtf8().constData(), it->toString().toUtf8(), t);
00528 }
00529 }
00530
00531 QStringList KServicePrivate::propertyNames() const
00532 {
00533 QStringList res;
00534
00535 QMap<QString,QVariant>::ConstIterator it = m_mapProps.begin();
00536 for( ; it != m_mapProps.end(); ++it )
00537 res.append( it.key() );
00538
00539 res.append( "Type" );
00540 res.append( "Name" );
00541 res.append( "Comment" );
00542 res.append( "GenericName" );
00543 res.append( "Icon" );
00544 res.append( "Exec" );
00545 res.append( "Terminal" );
00546 res.append( "TerminalOptions" );
00547 res.append( "Path" );
00548 res.append( "ServiceTypes" );
00549 res.append( "AllowAsDefault" );
00550 res.append( "InitialPreference" );
00551 res.append( "Library" );
00552 res.append( "DesktopEntryPath" );
00553 res.append( "DesktopEntryName" );
00554 res.append( "Keywords" );
00555 res.append( "Categories" );
00556
00557 return res;
00558 }
00559
00560 KService::List KService::allServices()
00561 {
00562 return KServiceFactory::self()->allServices();
00563 }
00564
00565 KService::Ptr KService::serviceByName( const QString& _name )
00566 {
00567 return KServiceFactory::self()->findServiceByName( _name );
00568 }
00569
00570 KService::Ptr KService::serviceByDesktopPath( const QString& _name )
00571 {
00572 return KServiceFactory::self()->findServiceByDesktopPath( _name );
00573 }
00574
00575 KService::Ptr KService::serviceByDesktopName( const QString& _name )
00576 {
00577
00578 QString name = _name.toLower();
00579 KService::Ptr s;
00580 if (!_name.startsWith("kde4-"))
00581 s = KServiceFactory::self()->findServiceByDesktopName( "kde4-" + name );
00582 if (!s)
00583 s = KServiceFactory::self()->findServiceByDesktopName( name );
00584
00585 return s;
00586 }
00587
00588 KService::Ptr KService::serviceByMenuId( const QString& _name )
00589 {
00590 return KServiceFactory::self()->findServiceByMenuId( _name );
00591 }
00592
00593 KService::Ptr KService::serviceByStorageId( const QString& _storageId )
00594 {
00595 KService::Ptr service = KService::serviceByMenuId( _storageId );
00596 if (service)
00597 return service;
00598
00599 service = KService::serviceByDesktopPath(_storageId);
00600 if (service)
00601 return service;
00602
00603 if (!QDir::isRelativePath(_storageId) && QFile::exists(_storageId))
00604 return KService::Ptr(new KService(_storageId));
00605
00606 QString tmp = _storageId;
00607 tmp = tmp.mid(tmp.lastIndexOf('/')+1);
00608
00609 if (tmp.endsWith(".desktop"))
00610 tmp.truncate(tmp.length()-8);
00611
00612 if (tmp.endsWith(".kdelnk"))
00613 tmp.truncate(tmp.length()-7);
00614
00615 service = KService::serviceByDesktopName(tmp);
00616
00617 return service;
00618 }
00619
00620 bool KService::substituteUid() const {
00621 QVariant v = property("X-KDE-SubstituteUID", QVariant::Bool);
00622 return v.isValid() && v.toBool();
00623 }
00624
00625 QString KService::username() const {
00626
00627 QString user;
00628 QVariant v = property("X-KDE-Username", QVariant::String);
00629 user = v.isValid() ? v.toString() : QString();
00630 if (user.isEmpty())
00631 user = QString::fromLocal8Bit(qgetenv("ADMIN_ACCOUNT"));
00632 if (user.isEmpty())
00633 user = "root";
00634 return user;
00635 }
00636
00637 bool KService::noDisplay() const {
00638 if ( qvariant_cast<bool>(property("NoDisplay", QVariant::Bool)) )
00639 return true;
00640
00641 Q_D(const KService);
00642
00643 QMap<QString,QVariant>::ConstIterator it = d->m_mapProps.find( "OnlyShowIn" );
00644 if ( (it != d->m_mapProps.end()) && (it->isValid()))
00645 {
00646 QString aValue = it->toString();
00647 QStringList aList = aValue.split(';');
00648 if (!aList.contains("KDE"))
00649 return true;
00650 }
00651
00652 it = d->m_mapProps.find( "NotShowIn" );
00653 if ( (it != d->m_mapProps.end()) && (it->isValid()))
00654 {
00655 QString aValue = it->toString();
00656 QStringList aList = aValue.split(';');
00657 if (aList.contains("KDE"))
00658 return true;
00659 }
00660
00661 if (!KAuthorized::authorizeControlModule(d->menuId))
00662 return true;
00663
00664 return false;
00665 }
00666
00667 QString KService::untranslatedGenericName() const {
00668 QVariant v = property("UntranslatedGenericName", QVariant::String);
00669 return v.isValid() ? v.toString() : QString();
00670 }
00671
00672 QString KService::parentApp() const {
00673 Q_D(const KService);
00674 QMap<QString,QVariant>::ConstIterator it = d->m_mapProps.find( "X-KDE-ParentApp" );
00675 if ( (it == d->m_mapProps.end()) || (!it->isValid()))
00676 {
00677 return QString();
00678 }
00679
00680 return it->toString();
00681 }
00682
00683 QString KService::pluginKeyword() const
00684 {
00685 Q_D(const KService);
00686 QMap<QString,QVariant>::ConstIterator it = d->m_mapProps.find("X-KDE-PluginKeyword");
00687 if ((it == d->m_mapProps.end()) || (!it->isValid())) {
00688 return QString();
00689 }
00690
00691 return it->toString();
00692 }
00693
00694 bool KService::allowMultipleFiles() const {
00695 Q_D(const KService);
00696
00697 return (d->m_strExec.contains( "%F" ) || d->m_strExec.contains( "%U" ) ||
00698 d->m_strExec.contains( "%N" ) || d->m_strExec.contains( "%D" ));
00699 }
00700
00701 QStringList KService::categories() const
00702 {
00703 Q_D(const KService);
00704 return d->categories;
00705 }
00706
00707 QString KService::menuId() const
00708 {
00709 Q_D(const KService);
00710 return d->menuId;
00711 }
00712
00713 void KService::setMenuId(const QString &_menuId)
00714 {
00715 Q_D(KService);
00716 d->menuId = _menuId;
00717 }
00718
00719 QString KService::storageId() const
00720 {
00721 Q_D(const KService);
00722 if (!d->menuId.isEmpty())
00723 return d->menuId;
00724 return entryPath();
00725 }
00726
00727 QString KService::locateLocal() const
00728 {
00729 Q_D(const KService);
00730 if (d->menuId.isEmpty() || entryPath().startsWith(".hidden") ||
00731 (QDir::isRelativePath(entryPath()) && d->categories.isEmpty()))
00732 return KDesktopFile::locateLocal(entryPath());
00733
00734 return KStandardDirs::locateLocal("xdgdata-apps", d->menuId);
00735 }
00736
00737 QString KService::newServicePath(bool showInMenu, const QString &suggestedName,
00738 QString *menuId, const QStringList *reservedMenuIds)
00739 {
00740 Q_UNUSED(showInMenu);
00741
00742 QString base = suggestedName;
00743 QString result;
00744 for(int i = 1; true; i++)
00745 {
00746 if (i == 1)
00747 result = base + ".desktop";
00748 else
00749 result = base + QString("-%1.desktop").arg(i);
00750
00751 if (reservedMenuIds && reservedMenuIds->contains(result))
00752 continue;
00753
00754
00755 KService::Ptr s = serviceByMenuId(result);
00756 if (s)
00757 continue;
00758
00759 if (!KStandardDirs::locate("xdgdata-apps", result).isEmpty())
00760 continue;
00761
00762 break;
00763 }
00764 if (menuId)
00765 *menuId = result;
00766
00767 return KStandardDirs::locateLocal("xdgdata-apps", result);
00768 }
00769
00770 bool KService::isApplication() const
00771 {
00772 Q_D(const KService);
00773 return d->m_strType == "Application";
00774 }
00775
00776 QString KService::type() const
00777 {
00778 Q_D(const KService);
00779 return d->m_strType;
00780 }
00781
00782 QString KService::exec() const
00783 {
00784 Q_D(const KService);
00785 if (d->m_strType == "Application" && d->m_strExec.isEmpty())
00786 {
00787 kWarning(7012) << "The desktop entry file " << entryPath()
00788 << " has Type=" << d->m_strType << " but has no Exec field." << endl;
00789 }
00790 return d->m_strExec;
00791 }
00792
00793 QString KService::library() const
00794 {
00795 Q_D(const KService);
00796 return d->m_strLibrary;
00797 }
00798
00799 QString KService::icon() const
00800 {
00801 Q_D(const KService);
00802 return d->m_strIcon;
00803 }
00804
00805 QString KService::terminalOptions() const
00806 {
00807 Q_D(const KService);
00808 return d->m_strTerminalOptions;
00809 }
00810
00811 bool KService::terminal() const
00812 {
00813 Q_D(const KService);
00814 return d->m_bTerminal;
00815 }
00816
00817
00818 QString KService::desktopEntryPath() const
00819 {
00820 return entryPath();
00821 }
00822
00823 QString KService::desktopEntryName() const
00824 {
00825 Q_D(const KService);
00826 return d->m_strDesktopEntryName;
00827 }
00828
00829 KService::DBusStartupType KService::dbusStartupType() const
00830 {
00831 Q_D(const KService);
00832 return d->m_DBUSStartusType;
00833 }
00834
00835 QString KService::path() const
00836 {
00837 Q_D(const KService);
00838 return d->m_strPath;
00839 }
00840
00841 QString KService::comment() const
00842 {
00843 Q_D(const KService);
00844 return d->m_strComment;
00845 }
00846
00847 QString KService::genericName() const
00848 {
00849 Q_D(const KService);
00850 return d->m_strGenName;
00851 }
00852
00853 QStringList KService::keywords() const
00854 {
00855 Q_D(const KService);
00856 return d->m_lstKeywords;
00857 }
00858
00859 QStringList KServicePrivate::serviceTypes() const
00860 {
00861 QStringList ret;
00862 QVector<KService::ServiceTypeAndPreference>::const_iterator it = m_serviceTypes.begin();
00863 for ( ; it < m_serviceTypes.end(); ++it ) {
00864 Q_ASSERT(!(*it).serviceType.isEmpty());
00865 ret.append((*it).serviceType);
00866 }
00867 return ret;
00868 }
00869
00870 QStringList KService::serviceTypes() const
00871 {
00872 Q_D(const KService);
00873 return d->serviceTypes();
00874 }
00875
00876 bool KService::allowAsDefault() const
00877 {
00878 Q_D(const KService);
00879 return d->m_bAllowAsDefault;
00880 }
00881
00882 int KService::initialPreference() const
00883 {
00884 Q_D(const KService);
00885 return d->m_initialPreference;
00886 }
00887
00888 void KService::setTerminal(bool b)
00889 {
00890 Q_D(KService);
00891 d->m_bTerminal = b;
00892 }
00893
00894 void KService::setTerminalOptions(const QString &options)
00895 {
00896 Q_D(KService);
00897 d->m_strTerminalOptions = options;
00898 }
00899
00900 QVector<KService::ServiceTypeAndPreference> & KService::_k_accessServiceTypes()
00901 {
00902 Q_D(KService);
00903 return d->m_serviceTypes;
00904 }
00905
00906 QList<KServiceAction> KService::actions() const
00907 {
00908 Q_D(const KService);
00909 return d->m_actions;
00910 }