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 <qstring.h>
00035 #include <qfile.h>
00036 #include <qdir.h>
00037 #include <qtl.h>
00038 #include <qfile.h>
00039
00040 #include <ksimpleconfig.h>
00041 #include <kstddirs.h>
00042 #include <kapplication.h>
00043 #include <kdebug.h>
00044 #include <kdesktopfile.h>
00045 #include <kglobal.h>
00046 #include <kiconloader.h>
00047 #include <klocale.h>
00048 #include <kconfigbase.h>
00049 #include <kstandarddirs.h>
00050 #include <dcopclient.h>
00051
00052 #include "kservicefactory.h"
00053 #include "kservicetypefactory.h"
00054 #include "kservicetype.h"
00055 #include "kuserprofile.h"
00056 #include "ksycoca.h"
00057
00058 class KService::KServicePrivate
00059 {
00060 public:
00061 QStringList categories;
00062 QString menuId;
00063 };
00064
00065 KService::KService( const QString & _name, const QString &_exec, const QString &_icon)
00066 : KSycocaEntry( QString::null)
00067 {
00068 d = new KServicePrivate;
00069 m_bValid = true;
00070 m_bDeleted = false;
00071 m_strType = "Application";
00072 m_strName = _name;
00073 m_strExec = _exec;
00074 m_strIcon = _icon;
00075 m_bTerminal = false;
00076 m_bAllowAsDefault = true;
00077 m_initialPreference = 10;
00078 }
00079
00080
00081 KService::KService( const QString & _fullpath )
00082 : KSycocaEntry( _fullpath)
00083 {
00084 KDesktopFile config( _fullpath );
00085
00086 init(&config);
00087 }
00088
00089 KService::KService( KDesktopFile *config )
00090 : KSycocaEntry( config->fileName())
00091 {
00092 init(config);
00093 }
00094
00095 void
00096 KService::init( KDesktopFile *config )
00097 {
00098 d = new KServicePrivate;
00099 m_bValid = true;
00100
00101 bool absPath = !QDir::isRelativePath(entryPath());
00102
00103 config->setDesktopGroup();
00104
00105 QMap<QString, QString> entryMap = config->entryMap(config->group());
00106
00107 entryMap.remove("Encoding");
00108 entryMap.remove("Version");
00109
00110 m_bDeleted = config->readBoolEntry( "Hidden", false );
00111 entryMap.remove("Hidden");
00112 if (m_bDeleted)
00113 {
00114
00115 m_bValid = false;
00116 return;
00117 } else if(!absPath) {
00118 QStringList list=KGlobal::dirs()->findAllResources(QFile::encodeName(config->resource()), entryPath());
00119 bool ok=false;
00120 for(QStringList::ConstIterator it=list.fromLast(); !ok && it!=list.end(); it--) {
00121 if(!access(QFile::encodeName(*it), R_OK))
00122 ok=true;
00123 }
00124 if(!ok) {
00125 m_bValid = false;
00126 return;
00127 }
00128 }
00129
00130 m_strName = config->readEntry( "Name" );
00131 entryMap.remove("Name");
00132 if ( m_strName.isEmpty() )
00133 {
00134 if (config->readEntry( "Exec" ).isEmpty())
00135 {
00136
00137
00138 m_bValid = false;
00139 return;
00140 }
00141
00142 m_strName = entryPath();
00143 int i = m_strName.findRev('/');
00144 m_strName = m_strName.mid(i+1);
00145 i = m_strName.findRev('.');
00146 if (i != -1)
00147 m_strName = m_strName.left(i);
00148 }
00149
00150 m_strType = config->readEntry( "Type" );
00151 entryMap.remove("Type");
00152 if ( m_strType.isEmpty() )
00153 {
00154
00155
00156
00157
00158
00159 m_strType = "Application";
00160 } else if ( m_strType != "Application" && m_strType != "Service" )
00161 {
00162 kdWarning(7012) << "The desktop entry file " << entryPath()
00163 << " has Type=" << m_strType
00164 << " instead of \"Application\" or \"Service\"" << endl;
00165 m_bValid = false;
00166 return;
00167 }
00168
00169
00170 if (!config->tryExec()) {
00171
00172 m_bDeleted = true;
00173 m_bValid = false;
00174 return;
00175 }
00176
00177 QString resource = config->resource();
00178
00179 if ( (m_strType == "Application") &&
00180 (!resource.isEmpty()) &&
00181 (resource != "apps") &&
00182 !absPath)
00183 {
00184 kdWarning(7012) << "The desktop entry file " << entryPath()
00185 << " has Type=" << m_strType << " but is located under \"" << resource
00186 << "\" instead of \"apps\"" << endl;
00187 m_bValid = false;
00188 return;
00189 }
00190
00191 if ( (m_strType == "Service") &&
00192 (!resource.isEmpty()) &&
00193 (resource != "services") &&
00194 !absPath)
00195 {
00196 kdWarning(7012) << "The desktop entry file " << entryPath()
00197 << " has Type=" << m_strType << " but is located under \"" << resource
00198 << "\" instead of \"services\"" << endl;
00199 m_bValid = false;
00200 return;
00201 }
00202
00203 QString name = entryPath();
00204 int pos = name.findRev('/');
00205 if (pos != -1)
00206 name = name.mid(pos+1);
00207 pos = name.find('.');
00208 if (pos != -1)
00209 name = name.left(pos);
00210
00211 m_strExec = config->readPathEntry( "Exec" );
00212 entryMap.remove("Exec");
00213
00214 m_strIcon = config->readEntry( "Icon", "unknown" );
00215 entryMap.remove("Icon");
00216 m_bTerminal = (config->readBoolEntry( "Terminal" ));
00217 entryMap.remove("Terminal");
00218 m_strTerminalOptions = config->readEntry( "TerminalOptions" );
00219 entryMap.remove("TerminalOptions");
00220 m_strPath = config->readPathEntry( "Path" );
00221 entryMap.remove("Path");
00222 m_strComment = config->readEntry( "Comment" );
00223 entryMap.remove("Comment");
00224 m_strGenName = config->readEntry( "GenericName" );
00225 entryMap.remove("GenericName");
00226 QString untranslatedGenericName = config->readEntryUntranslated( "GenericName" );
00227 if (!untranslatedGenericName.isEmpty())
00228 entryMap.insert("UntranslatedGenericName", untranslatedGenericName);
00229
00230 m_lstKeywords = config->readListEntry("Keywords");
00231 entryMap.remove("Keywords");
00232 d->categories = config->readListEntry("Categories", ';');
00233 entryMap.remove("Categories");
00234 m_strLibrary = config->readEntry( "X-KDE-Library" );
00235 entryMap.remove("X-KDE-Library");
00236 m_strInit = config->readEntry("X-KDE-Init" );
00237 entryMap.remove("X-KDE-Init");
00238
00239 m_lstServiceTypes = config->readListEntry( "ServiceTypes" );
00240 entryMap.remove("ServiceTypes");
00241
00242 m_lstServiceTypes += config->readListEntry( "MimeType", ';' );
00243 entryMap.remove("MimeType");
00244
00245 if ( m_strType == "Application" && !m_lstServiceTypes.contains("Application") )
00246
00247 m_lstServiceTypes += "Application";
00248
00249 QString dcopServiceType = config->readEntry("X-DCOP-ServiceType").lower();
00250 entryMap.remove("X-DCOP-ServiceType");
00251 if (dcopServiceType == "unique")
00252 m_DCOPServiceType = DCOP_Unique;
00253 else if (dcopServiceType == "multi")
00254 m_DCOPServiceType = DCOP_Multi;
00255 else if (dcopServiceType == "wait")
00256 m_DCOPServiceType = DCOP_Wait;
00257 else
00258 m_DCOPServiceType = DCOP_None;
00259
00260 m_strDesktopEntryName = name.lower();
00261
00262 m_bAllowAsDefault = config->readBoolEntry( "AllowDefault", true );
00263 entryMap.remove("AllowDefault");
00264
00265 m_initialPreference = config->readNumEntry( "InitialPreference", 1 );
00266 entryMap.remove("InitialPreference");
00267
00268
00269
00270
00271
00272 QMap<QString,QString>::ConstIterator it = entryMap.begin();
00273 for( ; it != entryMap.end();++it)
00274 {
00275
00276 m_mapProps.insert( it.key(), QVariant( it.data()));
00277 }
00278 }
00279
00280 KService::KService( QDataStream& _str, int offset ) : KSycocaEntry( _str, offset )
00281 {
00282 d = new KServicePrivate;
00283 load( _str );
00284 }
00285
00286 KService::~KService()
00287 {
00288
00289 delete d;
00290 }
00291
00292 QPixmap KService::pixmap( KIcon::Group _group, int _force_size, int _state, QString * _path ) const
00293 {
00294 KIconLoader *iconLoader=KGlobal::iconLoader();
00295 if (!iconLoader->extraDesktopThemesAdded())
00296 {
00297 QPixmap pixmap=iconLoader->loadIcon( m_strIcon, _group, _force_size, _state, _path, true );
00298 if (!pixmap.isNull() ) return pixmap;
00299
00300 iconLoader->addExtraDesktopThemes();
00301 }
00302
00303 return iconLoader->loadIcon( m_strIcon, _group, _force_size, _state, _path );
00304 }
00305
00306 void KService::load( QDataStream& s )
00307 {
00308
00309
00310
00311 Q_INT8 def, term, dummy1, dummy2;
00312 Q_INT8 dst, initpref;
00313 QString dummyStr1, dummyStr2;
00314 int dummyI1, dummyI2;
00315 Q_UINT32 dummyUI32;
00316
00317
00318
00319
00320
00321 s >> m_strType >> m_strName >> m_strExec >> m_strIcon
00322 >> term >> m_strTerminalOptions
00323 >> m_strPath >> m_strComment >> m_lstServiceTypes >> def >> m_mapProps
00324 >> m_strLibrary >> dummyI1 >> dummyI2
00325 >> dst
00326 >> m_strDesktopEntryName
00327 >> dummy1 >> dummyStr1 >> initpref >> dummyStr2 >> dummy2
00328 >> m_lstKeywords >> m_strInit >> dummyUI32 >> m_strGenName
00329 >> d->categories >> d->menuId;
00330
00331 m_bAllowAsDefault = def;
00332 m_bTerminal = term;
00333 m_DCOPServiceType = (DCOPServiceType_t) dst;
00334 m_initialPreference = initpref;
00335
00336 m_bValid = true;
00337 }
00338
00339 void KService::save( QDataStream& s )
00340 {
00341 KSycocaEntry::save( s );
00342 Q_INT8 def = m_bAllowAsDefault, initpref = m_initialPreference;
00343 Q_INT8 term = m_bTerminal;
00344 Q_INT8 dst = (Q_INT8) m_DCOPServiceType;
00345 Q_INT8 dummy1 = 0, dummy2 = 0;
00346 QString dummyStr1, dummyStr2;
00347 int dummyI1 = 0, dummyI2 = 0;
00348 Q_UINT32 dummyUI32 = 0;
00349
00350
00351
00352
00353
00354 s << m_strType << m_strName << m_strExec << m_strIcon
00355 << term << m_strTerminalOptions
00356 << m_strPath << m_strComment << m_lstServiceTypes << def << m_mapProps
00357 << m_strLibrary << dummyI1 << dummyI2
00358 << dst
00359 << m_strDesktopEntryName
00360 << dummy1 << dummyStr1 << initpref << dummyStr2 << dummy2
00361 << m_lstKeywords << m_strInit << dummyUI32 << m_strGenName
00362 << d->categories << d->menuId;
00363 }
00364
00365 bool KService::hasServiceType( const QString& _servicetype ) const
00366 {
00367 if (!m_bValid) return false;
00368
00369
00370
00371 KMimeType::Ptr mimePtr = KMimeType::mimeType( _servicetype );
00372 if ( mimePtr && mimePtr == KMimeType::defaultMimeTypePtr() )
00373 mimePtr = 0;
00374
00375 bool isNumber;
00376
00377
00378 QStringList::ConstIterator it = m_lstServiceTypes.begin();
00379 for( ; it != m_lstServiceTypes.end(); ++it )
00380 {
00381 (*it).toInt(&isNumber);
00382 if (isNumber)
00383 continue;
00384
00385 KServiceType::Ptr ptr = KServiceType::serviceType( *it );
00386 if ( ptr && ptr->inherits( _servicetype ) )
00387 return true;
00388
00389
00390
00391
00392 if ( mimePtr && mimePtr->is( *it ) )
00393 return true;
00394 }
00395 return false;
00396 }
00397
00398 int KService::initialPreferenceForMimeType( const QString& mimeType ) const
00399 {
00400 if (!m_bValid) return 0;
00401
00402 bool isNumber;
00403
00404
00405 QStringList::ConstIterator it = m_lstServiceTypes.begin();
00406 for( ; it != m_lstServiceTypes.end(); ++it )
00407 {
00408 (*it).toInt(&isNumber);
00409 if (isNumber)
00410 continue;
00411
00412 KServiceType::Ptr ptr = KServiceType::serviceType( *it );
00413 if ( !ptr || !ptr->inherits( mimeType ) )
00414 continue;
00415
00416 int initalPreference = m_initialPreference;
00417 ++it;
00418 if (it != m_lstServiceTypes.end())
00419 {
00420 int i = (*it).toInt(&isNumber);
00421 if (isNumber)
00422 initalPreference = i;
00423 }
00424 return initalPreference;
00425 }
00426
00427 KMimeType::Ptr mimePtr = KMimeType::mimeType( mimeType );
00428 if ( mimePtr && mimePtr == KMimeType::defaultMimeTypePtr() )
00429 mimePtr = 0;
00430
00431
00432 it = m_lstServiceTypes.begin();
00433 for( ; it != m_lstServiceTypes.end(); ++it )
00434 {
00435 (*it).toInt(&isNumber);
00436 if (isNumber)
00437 continue;
00438
00439
00440
00441
00442 if ( !mimePtr || !mimePtr->is( *it ) )
00443 continue;
00444
00445 int initalPreference = m_initialPreference;
00446 ++it;
00447 if (it != m_lstServiceTypes.end())
00448 {
00449 int i = (*it).toInt(&isNumber);
00450 if (isNumber)
00451 initalPreference = i;
00452 }
00453 return initalPreference;
00454 }
00455 return 0;
00456 }
00457
00458 class KServiceReadProperty : public KConfigBase
00459 {
00460 public:
00461 KServiceReadProperty(const QString &_key, const QCString &_value)
00462 : key(_key), value(_value) { }
00463
00464 bool internalHasGroup(const QCString &) const { return false; }
00465
00466 QStringList groupList() const { return QStringList(); }
00467
00468 QMap<QString,QString> entryMap(const QString &group) const
00469 { Q_UNUSED(group); return QMap<QString,QString>(); }
00470
00471 void reparseConfiguration() { }
00472
00473 KEntryMap internalEntryMap( const QString &pGroup) const
00474 { Q_UNUSED(pGroup); return KEntryMap(); }
00475
00476 KEntryMap internalEntryMap() const { return KEntryMap(); }
00477
00478 void putData(const KEntryKey &_key, const KEntry& _data, bool _checkGroup)
00479 { Q_UNUSED(_key); Q_UNUSED(_data); Q_UNUSED(_checkGroup); }
00480
00481 KEntry lookupData(const KEntryKey &_key) const
00482 { Q_UNUSED(_key); KEntry entry; entry.mValue = value; return entry; }
00483 protected:
00484 QString key;
00485 QCString value;
00486 };
00487
00488 QVariant KService::property( const QString& _name) const
00489 {
00490 return property( _name, QVariant::Invalid);
00491 }
00492
00493
00494
00495
00496 static QVariant makeStringVariant( const QString& string )
00497 {
00498
00499
00500 return string.isNull() ? QVariant() : QVariant( string );
00501 }
00502
00503 QVariant KService::property( const QString& _name, QVariant::Type t ) const
00504 {
00505 if ( _name == "Type" )
00506 return QVariant( m_strType );
00507 else if ( _name == "Name" )
00508 return QVariant( m_strName );
00509 else if ( _name == "Exec" )
00510 return makeStringVariant( m_strExec );
00511 else if ( _name == "Icon" )
00512 return makeStringVariant( m_strIcon );
00513 else if ( _name == "Terminal" )
00514 return QVariant( static_cast<int>(m_bTerminal) );
00515 else if ( _name == "TerminalOptions" )
00516 return makeStringVariant( m_strTerminalOptions );
00517 else if ( _name == "Path" )
00518 return makeStringVariant( m_strPath );
00519 else if ( _name == "Comment" )
00520 return makeStringVariant( m_strComment );
00521 else if ( _name == "GenericName" )
00522 return makeStringVariant( m_strGenName );
00523 else if ( _name == "ServiceTypes" )
00524 return QVariant( m_lstServiceTypes );
00525 else if ( _name == "AllowAsDefault" )
00526 return QVariant( static_cast<int>(m_bAllowAsDefault) );
00527 else if ( _name == "InitialPreference" )
00528 return QVariant( m_initialPreference );
00529 else if ( _name == "Library" )
00530 return makeStringVariant( m_strLibrary );
00531 else if ( _name == "DesktopEntryPath" )
00532 return QVariant( entryPath() );
00533 else if ( _name == "DesktopEntryName")
00534 return QVariant( m_strDesktopEntryName );
00535 else if ( _name == "Categories")
00536 return QVariant( d->categories );
00537 else if ( _name == "Keywords")
00538 return QVariant( m_lstKeywords );
00539
00540
00541
00542 if (t == QVariant::Invalid)
00543 {
00544
00545
00546 t = KServiceTypeFactory::self()->findPropertyTypeByName(_name);
00547 if (t == QVariant::Invalid)
00548 {
00549 kdDebug(7012) << "Request for unknown property '" << _name << "'\n";
00550 return QVariant();
00551 }
00552 }
00553
00554
00555
00556 QMap<QString,QVariant>::ConstIterator it = m_mapProps.find( _name );
00557 if ( (it == m_mapProps.end()) || (!it.data().isValid()))
00558 {
00559
00560 return QVariant();
00561 }
00562
00563 switch(t)
00564 {
00565 case QVariant::String:
00566 return it.data();
00567 case QVariant::Bool:
00568 case QVariant::Int:
00569 {
00570 QString aValue = it.data().toString();
00571 int val = 0;
00572 if (aValue == "true" || aValue == "on" || aValue == "yes")
00573 val = 1;
00574 else
00575 {
00576 bool bOK;
00577 val = aValue.toInt( &bOK );
00578 if( !bOK )
00579 val = 0;
00580 }
00581 if (t == QVariant::Bool)
00582 {
00583 return QVariant((bool)val, 1);
00584 }
00585 return QVariant(val);
00586 }
00587 default:
00588
00589 KServiceReadProperty ksrp(_name, it.data().toString().utf8());
00590 return ksrp.readPropertyEntry(_name, t);
00591 }
00592 }
00593
00594 QStringList KService::propertyNames() const
00595 {
00596 QStringList res;
00597
00598 QMap<QString,QVariant>::ConstIterator it = m_mapProps.begin();
00599 for( ; it != m_mapProps.end(); ++it )
00600 res.append( it.key() );
00601
00602 res.append( "Type" );
00603 res.append( "Name" );
00604 res.append( "Comment" );
00605 res.append( "GenericName" );
00606 res.append( "Icon" );
00607 res.append( "Exec" );
00608 res.append( "Terminal" );
00609 res.append( "TerminalOptions" );
00610 res.append( "Path" );
00611 res.append( "ServiceTypes" );
00612 res.append( "AllowAsDefault" );
00613 res.append( "InitialPreference" );
00614 res.append( "Library" );
00615 res.append( "DesktopEntryPath" );
00616 res.append( "DesktopEntryName" );
00617 res.append( "Keywords" );
00618 res.append( "Categories" );
00619
00620 return res;
00621 }
00622
00623 KService::List KService::allServices()
00624 {
00625 return KServiceFactory::self()->allServices();
00626 }
00627
00628 KService::Ptr KService::serviceByName( const QString& _name )
00629 {
00630 KService * s = KServiceFactory::self()->findServiceByName( _name );
00631 return KService::Ptr( s );
00632 }
00633
00634 KService::Ptr KService::serviceByDesktopPath( const QString& _name )
00635 {
00636 KService * s = KServiceFactory::self()->findServiceByDesktopPath( _name );
00637 return KService::Ptr( s );
00638 }
00639
00640 KService::Ptr KService::serviceByDesktopName( const QString& _name )
00641 {
00642 KService * s = KServiceFactory::self()->findServiceByDesktopName( _name.lower() );
00643 if (!s && !_name.startsWith("kde-"))
00644 s = KServiceFactory::self()->findServiceByDesktopName( "kde-"+_name.lower() );
00645 return KService::Ptr( s );
00646 }
00647
00648 KService::Ptr KService::serviceByMenuId( const QString& _name )
00649 {
00650 KService * s = KServiceFactory::self()->findServiceByMenuId( _name );
00651 return KService::Ptr( s );
00652 }
00653
00654 KService::Ptr KService::serviceByStorageId( const QString& _storageId )
00655 {
00656 KService::Ptr service = KService::serviceByMenuId( _storageId );
00657 if (service)
00658 return service;
00659
00660 service = KService::serviceByDesktopPath(_storageId);
00661 if (service)
00662 return service;
00663
00664 if (!QDir::isRelativePath(_storageId) && QFile::exists(_storageId))
00665 return new KService(_storageId);
00666
00667 QString tmp = _storageId;
00668 tmp = tmp.mid(tmp.findRev('/')+1);
00669
00670 if (tmp.endsWith(".desktop"))
00671 tmp.truncate(tmp.length()-8);
00672
00673 if (tmp.endsWith(".kdelnk"))
00674 tmp.truncate(tmp.length()-7);
00675
00676 service = KService::serviceByDesktopName(tmp);
00677
00678 return service;
00679 }
00680
00681 KService::List KService::allInitServices()
00682 {
00683 return KServiceFactory::self()->allInitServices();
00684 }
00685
00686 bool KService::substituteUid() const {
00687 QVariant v = property("X-KDE-SubstituteUID", QVariant::Bool);
00688 return v.isValid() && v.toBool();
00689 }
00690
00691 QString KService::username() const {
00692
00693 QString user;
00694 QVariant v = property("X-KDE-Username", QVariant::String);
00695 user = v.isValid() ? v.toString() : QString::null;
00696 if (user.isEmpty())
00697 user = ::getenv("ADMIN_ACCOUNT");
00698 if (user.isEmpty())
00699 user = "root";
00700 return user;
00701 }
00702
00703 bool KService::noDisplay() const {
00704 QMap<QString,QVariant>::ConstIterator it = m_mapProps.find( "NoDisplay" );
00705 if ( (it != m_mapProps.end()) && (it.data().isValid()))
00706 {
00707 QString aValue = it.data().toString().lower();
00708 if (aValue == "true" || aValue == "on" || aValue == "yes")
00709 return true;
00710 }
00711
00712 it = m_mapProps.find( "OnlyShowIn" );
00713 if ( (it != m_mapProps.end()) && (it.data().isValid()))
00714 {
00715 QString aValue = it.data().toString();
00716 QStringList aList = QStringList::split(';', aValue);
00717 if (!aList.contains("KDE"))
00718 return true;
00719 }
00720
00721 it = m_mapProps.find( "NotShowIn" );
00722 if ( (it != m_mapProps.end()) && (it.data().isValid()))
00723 {
00724 QString aValue = it.data().toString();
00725 QStringList aList = QStringList::split(';', aValue);
00726 if (aList.contains("KDE"))
00727 return true;
00728 }
00729
00730 if (!kapp->authorizeControlModule(d->menuId))
00731 return true;
00732
00733 return false;
00734 }
00735
00736 QString KService::untranslatedGenericName() const {
00737 QVariant v = property("UntranslatedGenericName", QVariant::String);
00738 return v.isValid() ? v.toString() : QString::null;
00739 }
00740
00741 QString KService::parentApp() const {
00742 QMap<QString,QVariant>::ConstIterator it = m_mapProps.find( "X-KDE-ParentApp" );
00743 if ( (it == m_mapProps.end()) || (!it.data().isValid()))
00744 {
00745 return QString::null;
00746 }
00747
00748 return it.data().toString();
00749 }
00750
00751 bool KService::allowMultipleFiles() const {
00752
00753 if ( m_strExec.find( "%F" ) != -1 || m_strExec.find( "%U" ) != -1 ||
00754 m_strExec.find( "%N" ) != -1 || m_strExec.find( "%D" ) != -1 )
00755 return true;
00756 else
00757 return false;
00758 }
00759
00760 QStringList KService::categories() const
00761 {
00762 return d->categories;
00763 }
00764
00765 QString KService::menuId() const
00766 {
00767 return d->menuId;
00768 }
00769
00770 void KService::setMenuId(const QString &menuId)
00771 {
00772 d->menuId = menuId;
00773 }
00774
00775 QString KService::storageId() const
00776 {
00777 if (!d->menuId.isEmpty())
00778 return d->menuId;
00779 return entryPath();
00780 }
00781
00782 QString KService::locateLocal()
00783 {
00784 if (d->menuId.isEmpty() || desktopEntryPath().startsWith(".hidden") ||
00785 (QDir::isRelativePath(desktopEntryPath()) && d->categories.isEmpty()))
00786 return KDesktopFile::locateLocal(desktopEntryPath());
00787
00788 return ::locateLocal("xdgdata-apps", d->menuId);
00789 }
00790
00791 QString KService::newServicePath(bool showInMenu, const QString &suggestedName,
00792 QString *menuId, const QStringList *reservedMenuIds)
00793 {
00794 QString base = suggestedName;
00795 if (!showInMenu)
00796 base.prepend("kde-");
00797
00798 QString result;
00799 for(int i = 1; true; i++)
00800 {
00801 if (i == 1)
00802 result = base + ".desktop";
00803 else
00804 result = base + QString("-%1.desktop").arg(i);
00805
00806 if (reservedMenuIds && reservedMenuIds->contains(result))
00807 continue;
00808
00809
00810 KService::Ptr s = serviceByMenuId(result);
00811 if (s)
00812 continue;
00813
00814 if (showInMenu)
00815 {
00816 if (!locate("xdgdata-apps", result).isEmpty())
00817 continue;
00818 }
00819 else
00820 {
00821 QString file = result.mid(4);
00822 if (!locate("apps", ".hidden/"+file).isEmpty())
00823 continue;
00824 }
00825
00826 break;
00827 }
00828 if (menuId)
00829 *menuId = result;
00830
00831 if (showInMenu)
00832 {
00833 return ::locateLocal("xdgdata-apps", result);
00834 }
00835 else
00836 {
00837 QString file = result.mid(4);
00838 return ::locateLocal("apps", ".hidden/"+file);
00839 }
00840 }
00841
00842
00843 void KService::virtual_hook( int id, void* data )
00844 { KSycocaEntry::virtual_hook( id, data ); }
00845
00846
00847 void KService::rebuildKSycoca(QWidget *parent)
00848 {
00849 KServiceProgressDialog dlg(parent, "ksycoca_progress",
00850 i18n("Updating System Configuration"),
00851 i18n("Updating system configuration."));
00852
00853 QByteArray data;
00854 DCOPClient *client = kapp->dcopClient();
00855
00856 int result = client->callAsync("kded", "kbuildsycoca", "recreate()",
00857 data, &dlg, SLOT(slotFinished()));
00858
00859 if (result)
00860 {
00861 dlg.exec();
00862 }
00863 }
00864
00865 KServiceProgressDialog::KServiceProgressDialog(QWidget *parent, const char *name,
00866 const QString &caption, const QString &text)
00867 : KProgressDialog(parent, name, caption, text, true)
00868 {
00869 connect(&m_timer, SIGNAL(timeout()), this, SLOT(slotProgress()));
00870 progressBar()->setTotalSteps(20);
00871 m_timeStep = 700;
00872 m_timer.start(m_timeStep);
00873 setAutoClose(false);
00874 }
00875
00876 void
00877 KServiceProgressDialog::slotProgress()
00878 {
00879 int p = progressBar()->progress();
00880 if (p == 18)
00881 {
00882 progressBar()->reset();
00883 progressBar()->setProgress(1);
00884 m_timeStep = m_timeStep * 2;
00885 m_timer.start(m_timeStep);
00886 }
00887 else
00888 {
00889 progressBar()->setProgress(p+1);
00890 }
00891 }
00892
00893 void
00894 KServiceProgressDialog::slotFinished()
00895 {
00896 progressBar()->setProgress(20);
00897 m_timer.stop();
00898 QTimer::singleShot(1000, this, SLOT(close()));
00899 }
00900
00901 #include "kservice_p.moc"