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