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;
419 const int serviceOffset =
offset();
429 QVector<ServiceTypeAndPreference>::ConstIterator it = d->m_serviceTypes.begin();
430 for( ; it != d->m_serviceTypes.end(); ++it ) {
431 const QString& st = (*it).serviceType;
433 if ( st == ptr->
name() )
443 #ifndef KDE_NO_DEPRECATED
446 if (!ptr)
return false;
456 int serviceOffset =
offset();
457 if ( serviceOffset ) {
461 if (serviceOffersOffset == -1)
467 QVector<ServiceTypeAndPreference>::ConstIterator it = d->m_serviceTypes.begin();
468 for( ; it != d->m_serviceTypes.end(); ++it ) {
469 const QString& st = (*it).serviceType;
483 return property( _name, QVariant::Invalid);
499 return d->property(_name, t);
504 if ( _name == QLatin1String(
"Type") )
506 else if ( _name == QLatin1String(
"Name") )
508 else if ( _name == QLatin1String(
"Exec") )
510 else if ( _name == QLatin1String(
"Icon") )
512 else if ( _name == QLatin1String(
"Terminal") )
514 else if ( _name == QLatin1String(
"TerminalOptions") )
516 else if ( _name == QLatin1String(
"Path") )
518 else if ( _name == QLatin1String(
"Comment") )
520 else if ( _name == QLatin1String(
"GenericName") )
522 else if ( _name == QLatin1String(
"ServiceTypes") )
524 else if ( _name == QLatin1String(
"AllowAsDefault") )
526 else if ( _name == QLatin1String(
"InitialPreference") )
528 else if ( _name == QLatin1String(
"Library") )
530 else if ( _name == QLatin1String(
"DesktopEntryPath") )
532 else if ( _name == QLatin1String(
"DesktopEntryName"))
534 else if ( _name == QLatin1String(
"Categories"))
536 else if ( _name == QLatin1String(
"Keywords"))
541 if (t == QVariant::Invalid)
546 if (t == QVariant::Invalid)
554 if ( (it ==
m_mapProps.end()) || (!it->isValid()))
562 case QVariant::String:
568 return KConfigGroup::convertToQVariant(_name.toUtf8().constData(), it->toString().toUtf8(), t);
578 res.append( it.key() );
580 res.append( QString::fromLatin1(
"Type") );
581 res.append( QString::fromLatin1(
"Name") );
582 res.append( QString::fromLatin1(
"Comment") );
583 res.append( QString::fromLatin1(
"GenericName") );
584 res.append( QString::fromLatin1(
"Icon") );
585 res.append( QString::fromLatin1(
"Exec") );
586 res.append( QString::fromLatin1(
"Terminal") );
587 res.append( QString::fromLatin1(
"TerminalOptions") );
588 res.append( QString::fromLatin1(
"Path") );
589 res.append( QString::fromLatin1(
"ServiceTypes") );
590 res.append( QString::fromLatin1(
"AllowAsDefault") );
591 res.append( QString::fromLatin1(
"InitialPreference") );
592 res.append( QString::fromLatin1(
"Library") );
593 res.append( QString::fromLatin1(
"DesktopEntryPath") );
594 res.append( QString::fromLatin1(
"DesktopEntryName") );
595 res.append( QString::fromLatin1(
"Keywords") );
596 res.append( QString::fromLatin1(
"Categories") );
606 #ifndef KDE_NO_DEPRECATED
623 if (!_name.startsWith(QLatin1String(
"kde4-")))
646 if (!QDir::isRelativePath(_storageId) && QFile::exists(_storageId))
650 tmp = tmp.mid(tmp.lastIndexOf(QLatin1Char(
'/'))+1);
652 if (tmp.endsWith(QLatin1String(
".desktop")))
653 tmp.truncate(tmp.length()-8);
655 if (tmp.endsWith(QLatin1String(
".kdelnk")))
656 tmp.truncate(tmp.length()-7);
664 QVariant v =
property(QLatin1String(
"X-KDE-SubstituteUID"), QVariant::Bool);
665 return v.isValid() && v.toBool();
672 user = v.isValid() ? v.toString() :
QString();
674 user = QString::fromLocal8Bit(qgetenv(
"ADMIN_ACCOUNT"));
676 user = QString::fromLatin1(
"root");
685 if ( (it != d->m_mapProps.end()) && (it->isValid()))
687 const QStringList aList = it->toString().split(QLatin1Char(
';'));
688 if (!aList.contains(QString::fromLatin1(
"KDE")))
692 it = d->m_mapProps.find( QString::fromLatin1(
"NotShowIn") );
693 if ( (it != d->m_mapProps.end()) && (it->isValid()))
695 const QStringList aList = it->toString().split(QLatin1Char(
';'));
696 if (aList.contains(QString::fromLatin1(
"KDE")))
703 if ( qvariant_cast<bool>(
property(QString::fromLatin1(
"NoDisplay"), QVariant::Bool)) )
716 QVariant v =
property(QString::fromLatin1(
"UntranslatedGenericName"), QVariant::String);
717 return v.isValid() ? v.toString() :
QString();
723 if ( (it == d->m_mapProps.end()) || (!it->isValid()))
728 return it->toString();
735 if ((it == d->m_mapProps.end()) || (!it->isValid())) {
739 return it->toString();
746 if ((it == d->m_mapProps.end()) || (!it->isValid())) {
747 it = d->m_mapProps.find(QString::fromLatin1(
"DocPath"));
748 if ((it == d->m_mapProps.end()) || (!it->isValid())) {
753 return it->toString();
759 return (d->m_strExec.contains( QLatin1String(
"%F") ) || d->m_strExec.contains( QLatin1String(
"%U") ) ||
760 d->m_strExec.contains( QLatin1String(
"%N") ) || d->m_strExec.contains( QLatin1String(
"%D") ));
766 return d->categories;
784 return d->storageId();
790 if (d->menuId.isEmpty() ||
entryPath().startsWith(QLatin1String(
".hidden")) ||
791 (QDir::isRelativePath(
entryPath()) && d->categories.isEmpty()))
800 Q_UNUSED(showInMenu);
804 for(
int i = 1;
true; i++)
807 result = base + QString::fromLatin1(
".desktop");
809 result = base + QString::fromLatin1(
"-%1.desktop").arg(i);
811 if (reservedMenuIds && reservedMenuIds->contains(result))
833 return d->m_strType == QLatin1String(
"Application");
836 #ifndef KDE_NO_DEPRECATED
847 if (d->m_strType == QLatin1String(
"Application") && d->m_strExec.isEmpty())
850 <<
" has Type=" << d->m_strType <<
" but has no Exec field." << endl;
858 return d->m_strLibrary;
870 return d->m_strTerminalOptions;
876 return d->m_bTerminal;
880 #ifndef KDE_NO_DEPRECATED
890 return d->m_strDesktopEntryName;
896 return d->m_DBUSStartusType;
908 return d->m_strComment;
914 return d->m_strGenName;
920 return d->m_lstKeywords;
926 QVector<KService::ServiceTypeAndPreference>::const_iterator it =
m_serviceTypes.begin();
928 Q_ASSERT(!(*it).serviceType.isEmpty());
929 ret.append((*it).serviceType);
937 return d->serviceTypes();
944 QVector<KService::ServiceTypeAndPreference>::const_iterator it = d->m_serviceTypes.begin();
945 for ( ; it < d->m_serviceTypes.end(); ++it ) {
946 const QString sv = (*it).serviceType;
956 return d->m_bAllowAsDefault;
962 return d->m_initialPreference;
974 d->m_strTerminalOptions = options;
980 return d->m_serviceTypes;