25 #include <sys/types.h>
32 #include <QtCore/QCharRef>
33 #include <QtCore/QFile>
34 #include <QtCore/QDir>
35 #include <QtCore/QMap>
66 bool absPath = !QDir::isRelativePath(entryPath);
72 entryMap.remove(QLatin1String(
"Encoding"));
73 entryMap.remove(QLatin1String(
"Version"));
76 entryMap.remove(QLatin1String(
"Hidden"));
83 entryMap.remove(QLatin1String(
"Name"));
88 int i =
m_strName.lastIndexOf(QLatin1Char(
'/'));
90 i =
m_strName.lastIndexOf(QLatin1Char(
'.'));
96 entryMap.remove(QLatin1String(
"Type"));
104 m_strType = QString::fromLatin1(
"Application");
105 }
else if (
m_strType != QLatin1String(
"Application") &&
m_strType != QLatin1String(
"Service")) {
108 <<
" instead of \"Application\" or \"Service\"" << endl;
116 entryMap.remove(QLatin1String(
"Exec"));
118 if (
m_strType == QLatin1String(
"Application")) {
123 <<
" but no Exec line" << endl;
136 const QByteArray resource = config->
resource();
138 if ( (
m_strType == QLatin1String(
"Application")) &&
139 (!resource.isEmpty()) &&
140 (resource !=
"apps") &&
144 <<
" has Type=" <<
m_strType <<
" but is located under \"" << resource
145 <<
"\" instead of \"apps\"" << endl;
150 if ( (
m_strType == QLatin1String(
"Service")) &&
151 (!resource.isEmpty()) &&
152 (resource !=
"services") &&
156 <<
" has Type=" <<
m_strType <<
" but is located under \"" << resource
157 <<
"\" instead of \"services\"";
163 int pos = _name.lastIndexOf(QLatin1Char(
'/'));
165 _name = _name.mid(pos+1);
166 pos = _name.indexOf(QLatin1Char(
'.'));
168 _name = _name.left(pos);
171 entryMap.remove(QLatin1String(
"Icon"));
173 entryMap.remove(QLatin1String(
"Terminal"));
175 entryMap.remove(QLatin1String(
"TerminalOptions"));
177 entryMap.remove(QLatin1String(
"Path"));
179 entryMap.remove(QLatin1String(
"Comment"));
181 entryMap.remove(QLatin1String(
"GenericName"));
183 if (!_untranslatedGenericName.isEmpty())
184 entryMap.insert(QLatin1String(
"UntranslatedGenericName"), _untranslatedGenericName);
187 entryMap.remove(QLatin1String(
"Keywords"));
189 entryMap.remove(QLatin1String(
"X-KDE-Keywords"));
191 entryMap.remove(QLatin1String(
"Categories"));
196 entryMap.remove(QLatin1String(
"X-KDE-Library"));
200 <<
"but also has a X-KDE-Library key. This works for now,"
201 " but makes user-preference handling difficult, so support for this might"
202 " be removed at some point. Consider splitting it into two desktop files.";
206 entryMap.remove(QLatin1String(
"ServiceTypes"));
208 entryMap.remove(QLatin1String(
"X-KDE-ServiceTypes"));
210 entryMap.remove(QLatin1String(
"MimeType"));
212 if (
m_strType == QLatin1String(
"Application") && !lstServiceTypes.contains(QLatin1String(
"Application")) )
214 lstServiceTypes += QString::fromLatin1(
"Application");
217 entryMap.remove(QLatin1String(
"InitialPreference"));
222 QListIterator<QString> st_it(lstServiceTypes);
223 while ( st_it.hasNext() ) {
224 const QString st = st_it.next();
227 <<
"has an empty mimetype!";
231 if ( st_it.hasNext() ) {
234 const int val = st_it.peekNext().toInt(&isNumber);
236 initialPreference = val;
243 if (entryMap.contains(QLatin1String(
"Actions"))) {
247 QString dbusStartupType = desktopGroup.
readEntry(
"X-DBUS-StartupType").toLower();
248 entryMap.remove(QLatin1String(
"X-DBUS-StartupType"));
249 if (dbusStartupType == QLatin1String(
"unique"))
251 else if (dbusStartupType == QLatin1String(
"multi"))
253 else if (dbusStartupType == QLatin1String(
"wait"))
261 entryMap.remove(QLatin1String(
"AllowDefault"));
265 if (entry != entryMap.end()) {
266 const QString& key = entry.key();
269 entryMap.erase(entry);
277 for( ; it != entryMap.constEnd();++it) {
280 if (!key.contains(QLatin1Char(
'['))) {
293 QStringList::ConstIterator it = keys.begin();
294 const QStringList::ConstIterator end = keys.end();
295 for ( ; it != end; ++it ) {
297 if (group == QLatin1String(
"_SEPARATOR_")) {
306 <<
"has no Name or no Exec key";
316 <<
"references the action" << group <<
"but doesn't define it";
377 d->m_strType = QString::fromLatin1(
"Application");
378 d->m_strName = _name;
379 d->m_strExec = _exec;
380 d->m_strIcon = _icon;
381 d->m_bTerminal =
false;
382 d->m_bAllowAsDefault =
true;
383 d->m_initialPreference = 10;
393 d->init(&config,
this);
401 d->init(config,
this);
417 if (!d->m_bValid)
return false;
421 const int serviceOffset =
offset();
431 QVector<ServiceTypeAndPreference>::ConstIterator it = d->m_serviceTypes.begin();
432 for( ; it != d->m_serviceTypes.end(); ++it ) {
433 const QString& st = (*it).serviceType;
435 if ( st == ptr->
name() )
445 #ifndef KDE_NO_DEPRECATED
448 if (!ptr)
return false;
458 int serviceOffset =
offset();
459 if ( serviceOffset ) {
463 if (serviceOffersOffset == -1)
469 QVector<ServiceTypeAndPreference>::ConstIterator it = d->m_serviceTypes.begin();
470 for( ; it != d->m_serviceTypes.end(); ++it ) {
471 const QString& st = (*it).serviceType;
485 return property( _name, QVariant::Invalid);
501 return d->property(_name, t);
506 if ( _name == QLatin1String(
"Type") )
508 else if ( _name == QLatin1String(
"Name") )
510 else if ( _name == QLatin1String(
"Exec") )
512 else if ( _name == QLatin1String(
"Icon") )
514 else if ( _name == QLatin1String(
"Terminal") )
516 else if ( _name == QLatin1String(
"TerminalOptions") )
518 else if ( _name == QLatin1String(
"Path") )
520 else if ( _name == QLatin1String(
"Comment") )
522 else if ( _name == QLatin1String(
"GenericName") )
524 else if ( _name == QLatin1String(
"ServiceTypes") )
526 else if ( _name == QLatin1String(
"AllowAsDefault") )
528 else if ( _name == QLatin1String(
"InitialPreference") )
530 else if ( _name == QLatin1String(
"Library") )
532 else if ( _name == QLatin1String(
"DesktopEntryPath") )
534 else if ( _name == QLatin1String(
"DesktopEntryName"))
536 else if ( _name == QLatin1String(
"Categories"))
538 else if ( _name == QLatin1String(
"Keywords"))
543 if (t == QVariant::Invalid)
548 if (t == QVariant::Invalid)
556 if ( (it ==
m_mapProps.end()) || (!it->isValid()))
564 case QVariant::String:
570 return KConfigGroup::convertToQVariant(_name.toUtf8().constData(), it->toString().toUtf8(), t);
580 res.append( it.key() );
582 res.append( QString::fromLatin1(
"Type") );
583 res.append( QString::fromLatin1(
"Name") );
584 res.append( QString::fromLatin1(
"Comment") );
585 res.append( QString::fromLatin1(
"GenericName") );
586 res.append( QString::fromLatin1(
"Icon") );
587 res.append( QString::fromLatin1(
"Exec") );
588 res.append( QString::fromLatin1(
"Terminal") );
589 res.append( QString::fromLatin1(
"TerminalOptions") );
590 res.append( QString::fromLatin1(
"Path") );
591 res.append( QString::fromLatin1(
"ServiceTypes") );
592 res.append( QString::fromLatin1(
"AllowAsDefault") );
593 res.append( QString::fromLatin1(
"InitialPreference") );
594 res.append( QString::fromLatin1(
"Library") );
595 res.append( QString::fromLatin1(
"DesktopEntryPath") );
596 res.append( QString::fromLatin1(
"DesktopEntryName") );
597 res.append( QString::fromLatin1(
"Keywords") );
598 res.append( QString::fromLatin1(
"Categories") );
608 #ifndef KDE_NO_DEPRECATED
625 if (!_name.startsWith(QLatin1String(
"kde4-")))
648 if (!QDir::isRelativePath(_storageId) && QFile::exists(_storageId))
652 tmp = tmp.mid(tmp.lastIndexOf(QLatin1Char(
'/'))+1);
654 if (tmp.endsWith(QLatin1String(
".desktop")))
655 tmp.truncate(tmp.length()-8);
657 if (tmp.endsWith(QLatin1String(
".kdelnk")))
658 tmp.truncate(tmp.length()-7);
666 QVariant v =
property(QLatin1String(
"X-KDE-SubstituteUID"), QVariant::Bool);
667 return v.isValid() && v.toBool();
674 user = v.isValid() ? v.toString() :
QString();
676 user = QString::fromLocal8Bit(qgetenv(
"ADMIN_ACCOUNT"));
678 user = QString::fromLatin1(
"root");
687 if ( (it != d->m_mapProps.end()) && (it->isValid()))
689 const QStringList aList = it->toString().split(QLatin1Char(
';'));
690 if (!aList.contains(QString::fromLatin1(
"KDE")))
694 it = d->m_mapProps.find( QString::fromLatin1(
"NotShowIn") );
695 if ( (it != d->m_mapProps.end()) && (it->isValid()))
697 const QStringList aList = it->toString().split(QLatin1Char(
';'));
698 if (aList.contains(QString::fromLatin1(
"KDE")))
705 if ( qvariant_cast<bool>(
property(QString::fromLatin1(
"NoDisplay"), QVariant::Bool)) )
718 QVariant v =
property(QString::fromLatin1(
"UntranslatedGenericName"), QVariant::String);
719 return v.isValid() ? v.toString() :
QString();
725 if ( (it == d->m_mapProps.end()) || (!it->isValid()))
730 return it->toString();
737 if ((it == d->m_mapProps.end()) || (!it->isValid())) {
741 return it->toString();
748 if ((it == d->m_mapProps.end()) || (!it->isValid())) {
749 it = d->m_mapProps.find(QString::fromLatin1(
"DocPath"));
750 if ((it == d->m_mapProps.end()) || (!it->isValid())) {
755 return it->toString();
761 return (d->m_strExec.contains( QLatin1String(
"%F") ) || d->m_strExec.contains( QLatin1String(
"%U") ) ||
762 d->m_strExec.contains( QLatin1String(
"%N") ) || d->m_strExec.contains( QLatin1String(
"%D") ));
768 return d->categories;
786 return d->storageId();
792 if (d->menuId.isEmpty() ||
entryPath().startsWith(QLatin1String(
".hidden")) ||
793 (QDir::isRelativePath(
entryPath()) && d->categories.isEmpty()))
802 Q_UNUSED(showInMenu);
806 for(
int i = 1;
true; i++)
809 result = base + QString::fromLatin1(
".desktop");
811 result = base + QString::fromLatin1(
"-%1.desktop").arg(i);
813 if (reservedMenuIds && reservedMenuIds->contains(result))
835 return d->m_strType == QLatin1String(
"Application");
838 #ifndef KDE_NO_DEPRECATED
849 if (d->m_strType == QLatin1String(
"Application") && d->m_strExec.isEmpty())
852 <<
" has Type=" << d->m_strType <<
" but has no Exec field." << endl;
860 return d->m_strLibrary;
872 return d->m_strTerminalOptions;
878 return d->m_bTerminal;
882 #ifndef KDE_NO_DEPRECATED
892 return d->m_strDesktopEntryName;
898 return d->m_DBUSStartusType;
910 return d->m_strComment;
916 return d->m_strGenName;
922 return d->m_lstKeywords;
928 QVector<KService::ServiceTypeAndPreference>::const_iterator it =
m_serviceTypes.begin();
930 Q_ASSERT(!(*it).serviceType.isEmpty());
931 ret.append((*it).serviceType);
939 return d->serviceTypes();
946 QVector<KService::ServiceTypeAndPreference>::const_iterator it = d->m_serviceTypes.begin();
947 for ( ; it < d->m_serviceTypes.end(); ++it ) {
948 const QString sv = (*it).serviceType;
958 return d->m_bAllowAsDefault;
964 return d->m_initialPreference;
976 d->m_strTerminalOptions = options;
983 if (!exec.isEmpty()) {
992 return d->m_serviceTypes;