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