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