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