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
00187
00188
00189 m_strLibrary = desktopGroup.readEntry( "X-KDE-Library" );
00190 entryMap.remove("X-KDE-Library");
00191 if (!m_strLibrary.isEmpty() && m_strType == "Application") {
00192 kWarning(7012) << "The desktop entry file" << entryPath
00193 << "has Type=" << m_strType
00194 << "but also has a X-KDE-Library key. This works for now,"
00195 " but makes user-preference handling difficult, so support for this might"
00196 " be removed at some point. Consider splitting it into two desktop files.";
00197 }
00198
00199 QStringList lstServiceTypes = desktopGroup.readEntry( "ServiceTypes", QStringList() );
00200 entryMap.remove("ServiceTypes");
00201 lstServiceTypes += desktopGroup.readEntry( "X-KDE-ServiceTypes", QStringList() );
00202 entryMap.remove("X-KDE-ServiceTypes");
00203 lstServiceTypes += desktopGroup.readXdgListEntry( "MimeType" );
00204 entryMap.remove("MimeType");
00205
00206 if ( m_strType == "Application" && !lstServiceTypes.contains("Application") )
00207
00208 lstServiceTypes += "Application";
00209
00210 m_initialPreference = desktopGroup.readEntry( "InitialPreference", 1 );
00211 entryMap.remove("InitialPreference");
00212
00213
00214
00215 m_serviceTypes.reserve(lstServiceTypes.size());
00216 QListIterator<QString> st_it(lstServiceTypes);
00217 while ( st_it.hasNext() ) {
00218 const QString st = st_it.next();
00219 if (st.isEmpty()) {
00220 kWarning(7012) << "The desktop entry file" << entryPath
00221 << "has an empty mimetype!";
00222 continue;
00223 }
00224 int initialPreference = m_initialPreference;
00225 if ( st_it.hasNext() ) {
00226
00227 bool isNumber;
00228 const int val = st_it.peekNext().toInt(&isNumber);
00229 if (isNumber) {
00230 initialPreference = val;
00231 st_it.next();
00232 }
00233 }
00234 m_serviceTypes.push_back(KService::ServiceTypeAndPreference(initialPreference, st));
00235 }
00236
00237 if (entryMap.contains("Actions")) {
00238 parseActions(config, q);
00239 }
00240
00241 QString dbusStartupType = desktopGroup.readEntry("X-DBUS-StartupType").toLower();
00242 entryMap.remove("X-DBUS-StartupType");
00243 if (dbusStartupType == "unique")
00244 m_DBUSStartusType = KService::DBusUnique;
00245 else if (dbusStartupType == "multi")
00246 m_DBUSStartusType = KService::DBusMulti;
00247 else if (dbusStartupType == "wait")
00248 m_DBUSStartusType = KService::DBusWait;
00249 else
00250 m_DBUSStartusType = KService::DBusNone;
00251
00252 m_strDesktopEntryName = _name.toLower();
00253
00254 m_bAllowAsDefault = desktopGroup.readEntry("AllowDefault", true);
00255 entryMap.remove("AllowDefault");
00256
00257
00258 QMap<QString,QString>::Iterator entry = entryMap.find("X-KDE-PluginInfo-Category");
00259 if (entry != entryMap.end()) {
00260 const QString& key = entry.key();
00261 m_mapProps.insert(key, QVariant(desktopGroup.readEntryUntranslated(key)));
00262 m_mapProps.insert(key + "-Translated", QVariant(*entry));
00263 entryMap.erase(entry);
00264 }
00265
00266
00267
00268
00269
00270 QMap<QString,QString>::ConstIterator it = entryMap.constBegin();
00271 for( ; it != entryMap.constEnd();++it) {
00272 const QString key = it.key();
00273
00274 if (!key.contains('[')) {
00275
00276 m_mapProps.insert(key, QVariant(*it));
00277 }
00278 }
00279 }
00280
00281 void KServicePrivate::parseActions(const KDesktopFile *config, KService* q)
00282 {
00283 const QStringList keys = config->readActions();
00284 if (keys.isEmpty())
00285 return;
00286
00287 QStringList::ConstIterator it = keys.begin();
00288 const QStringList::ConstIterator end = keys.end();
00289 for ( ; it != end; ++it ) {
00290 const QString group = *it;
00291 if (group == "_SEPARATOR_") {
00292 m_actions.append(KServiceAction(group, QString(), QString(), QString(), false));
00293 continue;
00294 }
00295
00296 if (config->hasActionGroup(group)) {
00297 const KConfigGroup cg = config->actionGroup(group);
00298 if ( !cg.hasKey( "Name" ) || !cg.hasKey( "Exec" ) ) {
00299 kWarning(7012) << "The action" << group << "in the desktop file" << q->entryPath()
00300 << "has no Name or no Exec key";
00301 } else {
00302 m_actions.append(KServiceAction(group,
00303 cg.readEntry("Name"),
00304 cg.readEntry("Icon"),
00305 cg.readEntry("Exec"),
00306 cg.readEntry("NoDisplay", false)));
00307 }
00308 } else {
00309 kWarning(7012) << "The desktop file" << q->entryPath()
00310 << "references the action" << group << "but doesn't define it";
00311 }
00312 }
00313 }
00314
00315 void KServicePrivate::load(QDataStream& s)
00316 {
00317 qint8 def, term;
00318 qint8 dst, initpref;
00319 QStringList dummyList;
00320
00321
00322
00323
00324
00325 s >> m_strType >> m_strName >> m_strExec >> m_strIcon
00326 >> term >> m_strTerminalOptions
00327 >> m_strPath >> m_strComment >> dummyList >> def >> m_mapProps
00328 >> m_strLibrary
00329 >> dst
00330 >> m_strDesktopEntryName
00331 >> initpref
00332 >> m_lstKeywords >> m_strGenName
00333 >> categories >> menuId >> m_actions >> m_serviceTypes;
00334
00335 m_bAllowAsDefault = (bool)def;
00336 m_bTerminal = (bool)term;
00337 m_DBUSStartusType = (KService::DBusStartupType) dst;
00338 m_initialPreference = initpref;
00339
00340 m_bValid = true;
00341 }
00342
00343 void KServicePrivate::save(QDataStream& s)
00344 {
00345 KSycocaEntryPrivate::save( s );
00346 qint8 def = m_bAllowAsDefault, initpref = m_initialPreference;
00347 qint8 term = m_bTerminal;
00348 qint8 dst = (qint8) m_DBUSStartusType;
00349
00350
00351
00352
00353
00354 s << m_strType << m_strName << m_strExec << m_strIcon
00355 << term << m_strTerminalOptions
00356 << m_strPath << m_strComment << QStringList() << def << m_mapProps
00357 << m_strLibrary
00358 << dst
00359 << m_strDesktopEntryName
00360 << initpref
00361 << m_lstKeywords << m_strGenName
00362 << categories << menuId << m_actions << m_serviceTypes;
00363 }
00364
00366
00367 KService::KService( const QString & _name, const QString &_exec, const QString &_icon)
00368 : KSycocaEntry(*new KServicePrivate(QString()))
00369 {
00370 Q_D(KService);
00371 d->m_strType = "Application";
00372 d->m_strName = _name;
00373 d->m_strExec = _exec;
00374 d->m_strIcon = _icon;
00375 d->m_bTerminal = false;
00376 d->m_bAllowAsDefault = true;
00377 d->m_initialPreference = 10;
00378 }
00379
00380
00381 KService::KService( const QString & _fullpath )
00382 : KSycocaEntry(*new KServicePrivate(_fullpath))
00383 {
00384 Q_D(KService);
00385
00386 KDesktopFile config( _fullpath );
00387 d->init(&config, this);
00388 }
00389
00390 KService::KService( const KDesktopFile *config )
00391 : KSycocaEntry(*new KServicePrivate(config->fileName()))
00392 {
00393 Q_D(KService);
00394
00395 d->init(config, this);
00396 }
00397
00398 KService::KService( QDataStream& _str, int _offset )
00399 : KSycocaEntry(*new KServicePrivate(_str, _offset))
00400 {
00401 }
00402
00403 KService::~KService()
00404 {
00405 }
00406
00407 bool KService::hasServiceType( const QString& serviceType ) const
00408 {
00409 Q_D(const KService);
00410
00411 if (!d->m_bValid) return false;
00412 const KServiceType::Ptr ptr = KServiceType::serviceType( serviceType );
00413
00414
00415 return hasMimeType( ptr.data() );
00416 }
00417
00418 bool KService::hasMimeType( const KServiceType* ptr ) const
00419 {
00420 Q_D(const KService);
00421 if (!ptr) return false;
00422 int serviceOffset = offset();
00423
00424
00425
00426 if ( serviceOffset )
00427 return KServiceFactory::self()->hasOffer( ptr->offset(), ptr->serviceOffersOffset(), serviceOffset );
00428
00429
00430
00431
00432 QVector<ServiceTypeAndPreference>::ConstIterator it = d->m_serviceTypes.begin();
00433 for( ; it != d->m_serviceTypes.end(); ++it ) {
00434 const QString& st = (*it).serviceType;
00435
00436 if ( st == ptr->name() )
00437 return true;
00438
00439 KServiceType::Ptr p = KServiceType::serviceType( st );
00440 if ( p && p->inherits( ptr->name() ) )
00441 return true;
00442
00443
00444
00445
00446 }
00447 return false;
00448 }
00449
00450 QVariant KServicePrivate::property( const QString& _name) const
00451 {
00452 return property( _name, QVariant::Invalid);
00453 }
00454
00455
00456
00457
00458 static QVariant makeStringVariant( const QString& string )
00459 {
00460
00461
00462 return string.isNull() ? QVariant() : QVariant( string );
00463 }
00464
00465 QVariant KService::property( const QString& _name, QVariant::Type t ) const
00466 {
00467 Q_D(const KService);
00468 return d->property(_name, t);
00469 }
00470
00471 QVariant KServicePrivate::property( const QString& _name, QVariant::Type t ) const
00472 {
00473 if ( _name == "Type" )
00474 return QVariant( m_strType );
00475 else if ( _name == "Name" )
00476 return QVariant( m_strName );
00477 else if ( _name == "Exec" )
00478 return makeStringVariant( m_strExec );
00479 else if ( _name == "Icon" )
00480 return makeStringVariant( m_strIcon );
00481 else if ( _name == "Terminal" )
00482 return QVariant( m_bTerminal );
00483 else if ( _name == "TerminalOptions" )
00484 return makeStringVariant( m_strTerminalOptions );
00485 else if ( _name == "Path" )
00486 return makeStringVariant( m_strPath );
00487 else if ( _name == "Comment" )
00488 return makeStringVariant( m_strComment );
00489 else if ( _name == "GenericName" )
00490 return makeStringVariant( m_strGenName );
00491 else if ( _name == "ServiceTypes" )
00492 return QVariant( serviceTypes() );
00493 else if ( _name == "AllowAsDefault" )
00494 return QVariant( m_bAllowAsDefault );
00495 else if ( _name == "InitialPreference" )
00496 return QVariant( m_initialPreference );
00497 else if ( _name == "Library" )
00498 return makeStringVariant( m_strLibrary );
00499 else if ( _name == "DesktopEntryPath" )
00500 return QVariant( path );
00501 else if ( _name == "DesktopEntryName")
00502 return QVariant( m_strDesktopEntryName );
00503 else if ( _name == "Categories")
00504 return QVariant( categories );
00505 else if ( _name == "Keywords")
00506 return QVariant( m_lstKeywords );
00507
00508
00509
00510 if (t == QVariant::Invalid)
00511 {
00512
00513
00514 t = KServiceTypeFactory::self()->findPropertyTypeByName(_name);
00515 if (t == QVariant::Invalid)
00516 {
00517 kDebug(7012) << "Request for unknown property '" << _name << "'\n";
00518 return QVariant();
00519 }
00520 }
00521
00522 QMap<QString,QVariant>::ConstIterator it = m_mapProps.find( _name );
00523 if ( (it == m_mapProps.end()) || (!it->isValid()))
00524 {
00525
00526 return QVariant();
00527 }
00528
00529 switch(t)
00530 {
00531 case QVariant::String:
00532 return *it;
00533 default:
00534
00535
00536
00537 return KConfigGroup::convertToQVariant(_name.toUtf8().constData(), it->toString().toUtf8(), t);
00538 }
00539 }
00540
00541 QStringList KServicePrivate::propertyNames() const
00542 {
00543 QStringList res;
00544
00545 QMap<QString,QVariant>::ConstIterator it = m_mapProps.begin();
00546 for( ; it != m_mapProps.end(); ++it )
00547 res.append( it.key() );
00548
00549 res.append( "Type" );
00550 res.append( "Name" );
00551 res.append( "Comment" );
00552 res.append( "GenericName" );
00553 res.append( "Icon" );
00554 res.append( "Exec" );
00555 res.append( "Terminal" );
00556 res.append( "TerminalOptions" );
00557 res.append( "Path" );
00558 res.append( "ServiceTypes" );
00559 res.append( "AllowAsDefault" );
00560 res.append( "InitialPreference" );
00561 res.append( "Library" );
00562 res.append( "DesktopEntryPath" );
00563 res.append( "DesktopEntryName" );
00564 res.append( "Keywords" );
00565 res.append( "Categories" );
00566
00567 return res;
00568 }
00569
00570 KService::List KService::allServices()
00571 {
00572 return KServiceFactory::self()->allServices();
00573 }
00574
00575 KService::Ptr KService::serviceByName( const QString& _name )
00576 {
00577 return KServiceFactory::self()->findServiceByName( _name );
00578 }
00579
00580 KService::Ptr KService::serviceByDesktopPath( const QString& _name )
00581 {
00582 return KServiceFactory::self()->findServiceByDesktopPath( _name );
00583 }
00584
00585 KService::Ptr KService::serviceByDesktopName( const QString& _name )
00586 {
00587
00588 QString name = _name.toLower();
00589 KService::Ptr s;
00590 if (!_name.startsWith("kde4-"))
00591 s = KServiceFactory::self()->findServiceByDesktopName( "kde4-" + name );
00592 if (!s)
00593 s = KServiceFactory::self()->findServiceByDesktopName( name );
00594
00595 return s;
00596 }
00597
00598 KService::Ptr KService::serviceByMenuId( const QString& _name )
00599 {
00600 return KServiceFactory::self()->findServiceByMenuId( _name );
00601 }
00602
00603 KService::Ptr KService::serviceByStorageId( const QString& _storageId )
00604 {
00605 KService::Ptr service = KService::serviceByMenuId( _storageId );
00606 if (service)
00607 return service;
00608
00609 service = KService::serviceByDesktopPath(_storageId);
00610 if (service)
00611 return service;
00612
00613 if (!QDir::isRelativePath(_storageId) && QFile::exists(_storageId))
00614 return KService::Ptr(new KService(_storageId));
00615
00616 QString tmp = _storageId;
00617 tmp = tmp.mid(tmp.lastIndexOf('/')+1);
00618
00619 if (tmp.endsWith(".desktop"))
00620 tmp.truncate(tmp.length()-8);
00621
00622 if (tmp.endsWith(".kdelnk"))
00623 tmp.truncate(tmp.length()-7);
00624
00625 service = KService::serviceByDesktopName(tmp);
00626
00627 return service;
00628 }
00629
00630 bool KService::substituteUid() const {
00631 QVariant v = property("X-KDE-SubstituteUID", QVariant::Bool);
00632 return v.isValid() && v.toBool();
00633 }
00634
00635 QString KService::username() const {
00636
00637 QString user;
00638 QVariant v = property("X-KDE-Username", QVariant::String);
00639 user = v.isValid() ? v.toString() : QString();
00640 if (user.isEmpty())
00641 user = QString::fromLocal8Bit(qgetenv("ADMIN_ACCOUNT"));
00642 if (user.isEmpty())
00643 user = "root";
00644 return user;
00645 }
00646
00647 bool KService::noDisplay() const {
00648 if ( qvariant_cast<bool>(property("NoDisplay", QVariant::Bool)) )
00649 return true;
00650
00651 Q_D(const KService);
00652
00653 QMap<QString,QVariant>::ConstIterator it = d->m_mapProps.find( "OnlyShowIn" );
00654 if ( (it != d->m_mapProps.end()) && (it->isValid()))
00655 {
00656 QString aValue = it->toString();
00657 QStringList aList = aValue.split(';');
00658 if (!aList.contains("KDE"))
00659 return true;
00660 }
00661
00662 it = d->m_mapProps.find( "NotShowIn" );
00663 if ( (it != d->m_mapProps.end()) && (it->isValid()))
00664 {
00665 QString aValue = it->toString();
00666 QStringList aList = aValue.split(';');
00667 if (aList.contains("KDE"))
00668 return true;
00669 }
00670
00671 if (!KAuthorized::authorizeControlModule( storageId() ) )
00672 return true;
00673
00674 return false;
00675 }
00676
00677 QString KService::untranslatedGenericName() const {
00678 QVariant v = property("UntranslatedGenericName", QVariant::String);
00679 return v.isValid() ? v.toString() : QString();
00680 }
00681
00682 QString KService::parentApp() const {
00683 Q_D(const KService);
00684 QMap<QString,QVariant>::ConstIterator it = d->m_mapProps.find( "X-KDE-ParentApp" );
00685 if ( (it == d->m_mapProps.end()) || (!it->isValid()))
00686 {
00687 return QString();
00688 }
00689
00690 return it->toString();
00691 }
00692
00693 QString KService::pluginKeyword() const
00694 {
00695 Q_D(const KService);
00696 QMap<QString,QVariant>::ConstIterator it = d->m_mapProps.find("X-KDE-PluginKeyword");
00697 if ((it == d->m_mapProps.end()) || (!it->isValid())) {
00698 return QString();
00699 }
00700
00701 return it->toString();
00702 }
00703
00704 QString KService::docPath() const
00705 {
00706 Q_D(const KService);
00707 QMap<QString,QVariant>::ConstIterator it = d->m_mapProps.find("X-DocPath");
00708 if ((it == d->m_mapProps.end()) || (!it->isValid())) {
00709 it = d->m_mapProps.find("DocPath");
00710 if ((it == d->m_mapProps.end()) || (!it->isValid())) {
00711 return QString();
00712 }
00713 }
00714
00715 return it->toString();
00716 }
00717
00718 bool KService::allowMultipleFiles() const {
00719 Q_D(const KService);
00720
00721 return (d->m_strExec.contains( "%F" ) || d->m_strExec.contains( "%U" ) ||
00722 d->m_strExec.contains( "%N" ) || d->m_strExec.contains( "%D" ));
00723 }
00724
00725 QStringList KService::categories() const
00726 {
00727 Q_D(const KService);
00728 return d->categories;
00729 }
00730
00731 QString KService::menuId() const
00732 {
00733 Q_D(const KService);
00734 return d->menuId;
00735 }
00736
00737 void KService::setMenuId(const QString &_menuId)
00738 {
00739 Q_D(KService);
00740 d->menuId = _menuId;
00741 }
00742
00743 QString KService::storageId() const
00744 {
00745 Q_D(const KService);
00746 return d->storageId();
00747 }
00748
00749 QString KService::locateLocal() const
00750 {
00751 Q_D(const KService);
00752 if (d->menuId.isEmpty() || entryPath().startsWith(".hidden") ||
00753 (QDir::isRelativePath(entryPath()) && d->categories.isEmpty()))
00754 return KDesktopFile::locateLocal(entryPath());
00755
00756 return KStandardDirs::locateLocal("xdgdata-apps", d->menuId);
00757 }
00758
00759 QString KService::newServicePath(bool showInMenu, const QString &suggestedName,
00760 QString *menuId, const QStringList *reservedMenuIds)
00761 {
00762 Q_UNUSED(showInMenu);
00763
00764 QString base = suggestedName;
00765 QString result;
00766 for(int i = 1; true; i++)
00767 {
00768 if (i == 1)
00769 result = base + ".desktop";
00770 else
00771 result = base + QString("-%1.desktop").arg(i);
00772
00773 if (reservedMenuIds && reservedMenuIds->contains(result))
00774 continue;
00775
00776
00777 KService::Ptr s = serviceByMenuId(result);
00778 if (s)
00779 continue;
00780
00781 if (!KStandardDirs::locate("xdgdata-apps", result).isEmpty())
00782 continue;
00783
00784 break;
00785 }
00786 if (menuId)
00787 *menuId = result;
00788
00789 return KStandardDirs::locateLocal("xdgdata-apps", result);
00790 }
00791
00792 bool KService::isApplication() const
00793 {
00794 Q_D(const KService);
00795 return d->m_strType == "Application";
00796 }
00797
00798 QString KService::type() const
00799 {
00800 Q_D(const KService);
00801 return d->m_strType;
00802 }
00803
00804 QString KService::exec() const
00805 {
00806 Q_D(const KService);
00807 if (d->m_strType == "Application" && d->m_strExec.isEmpty())
00808 {
00809 kWarning(7012) << "The desktop entry file " << entryPath()
00810 << " has Type=" << d->m_strType << " but has no Exec field." << endl;
00811 }
00812 return d->m_strExec;
00813 }
00814
00815 QString KService::library() const
00816 {
00817 Q_D(const KService);
00818 return d->m_strLibrary;
00819 }
00820
00821 QString KService::icon() const
00822 {
00823 Q_D(const KService);
00824 return d->m_strIcon;
00825 }
00826
00827 QString KService::terminalOptions() const
00828 {
00829 Q_D(const KService);
00830 return d->m_strTerminalOptions;
00831 }
00832
00833 bool KService::terminal() const
00834 {
00835 Q_D(const KService);
00836 return d->m_bTerminal;
00837 }
00838
00839
00840 QString KService::desktopEntryPath() const
00841 {
00842 return entryPath();
00843 }
00844
00845 QString KService::desktopEntryName() const
00846 {
00847 Q_D(const KService);
00848 return d->m_strDesktopEntryName;
00849 }
00850
00851 KService::DBusStartupType KService::dbusStartupType() const
00852 {
00853 Q_D(const KService);
00854 return d->m_DBUSStartusType;
00855 }
00856
00857 QString KService::path() const
00858 {
00859 Q_D(const KService);
00860 return d->m_strPath;
00861 }
00862
00863 QString KService::comment() const
00864 {
00865 Q_D(const KService);
00866 return d->m_strComment;
00867 }
00868
00869 QString KService::genericName() const
00870 {
00871 Q_D(const KService);
00872 return d->m_strGenName;
00873 }
00874
00875 QStringList KService::keywords() const
00876 {
00877 Q_D(const KService);
00878 return d->m_lstKeywords;
00879 }
00880
00881 QStringList KServicePrivate::serviceTypes() const
00882 {
00883 QStringList ret;
00884 QVector<KService::ServiceTypeAndPreference>::const_iterator it = m_serviceTypes.begin();
00885 for ( ; it < m_serviceTypes.end(); ++it ) {
00886 Q_ASSERT(!(*it).serviceType.isEmpty());
00887 ret.append((*it).serviceType);
00888 }
00889 return ret;
00890 }
00891
00892 QStringList KService::serviceTypes() const
00893 {
00894 Q_D(const KService);
00895 return d->serviceTypes();
00896 }
00897
00898 bool KService::allowAsDefault() const
00899 {
00900 Q_D(const KService);
00901 return d->m_bAllowAsDefault;
00902 }
00903
00904 int KService::initialPreference() const
00905 {
00906 Q_D(const KService);
00907 return d->m_initialPreference;
00908 }
00909
00910 void KService::setTerminal(bool b)
00911 {
00912 Q_D(KService);
00913 d->m_bTerminal = b;
00914 }
00915
00916 void KService::setTerminalOptions(const QString &options)
00917 {
00918 Q_D(KService);
00919 d->m_strTerminalOptions = options;
00920 }
00921
00922 QVector<KService::ServiceTypeAndPreference> & KService::_k_accessServiceTypes()
00923 {
00924 Q_D(KService);
00925 return d->m_serviceTypes;
00926 }
00927
00928 QList<KServiceAction> KService::actions() const
00929 {
00930 Q_D(const KService);
00931 return d->m_actions;
00932 }