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