diff options
Diffstat (limited to 'tdecore/kdesktopfile.cpp')
-rw-r--r-- | tdecore/kdesktopfile.cpp | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/tdecore/kdesktopfile.cpp b/tdecore/kdesktopfile.cpp new file mode 100644 index 000000000..431a65578 --- /dev/null +++ b/tdecore/kdesktopfile.cpp @@ -0,0 +1,367 @@ +/* + This file is part of the KDE libraries + Copyright (c) 1999 Pietro Iglio <iglio@kde.org> + Copyright (c) 1999 Preston Brown <pbrown@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// $Id$ + +#include <stdlib.h> +#include <unistd.h> + +#include <tqfile.h> +#include <tqdir.h> +#include <tqtextstream.h> + +#include <kdebug.h> +#include "kurl.h" +#include "kconfigbackend.h" +#include "kapplication.h" +#include "kstandarddirs.h" +#include "kmountpoint.h" +#include "kcatalogue.h" +#include "klocale.h" + +#include "kdesktopfile.h" +#include "kdesktopfile.moc" + +KDesktopFile::KDesktopFile(const TQString &fileName, bool bReadOnly, + const char * resType) + : KConfig(TQString::tqfromLatin1(""), bReadOnly, false) +{ + // KConfigBackEnd will try to locate the filename that is provided + // based on the resource type specified, _only_ if the filename + // is not an absolute path. + backEnd->changeFileName(fileName, resType, false); + setReadOnly(bReadOnly); + reparseConfiguration(); + setDesktopGroup(); +} + +KDesktopFile::~KDesktopFile() +{ + // no need to do anything +} + +TQString KDesktopFile::locateLocal(const TQString &path) +{ + TQString local; + if (path.endsWith(".directory")) + { + local = path; + if (!TQDir::isRelativePath(local)) + { + // Relative wrt apps? + local = KGlobal::dirs()->relativeLocation("apps", path); + } + + if (TQDir::isRelativePath(local)) + { + local = ::locateLocal("apps", local); // Relative to apps + } + else + { + // XDG Desktop menu items come with absolute paths, we need to + // extract their relative path and then build a local path. + local = KGlobal::dirs()->relativeLocation("xdgdata-dirs", local); + if (!TQDir::isRelativePath(local)) + { + // Hm, that didn't work... + // What now? Use filename only and hope for the best. + local = path.mid(path.findRev('/')+1); + } + local = ::locateLocal("xdgdata-dirs", local); + } + } + else + { + if (TQDir::isRelativePath(path)) + { + local = ::locateLocal("apps", path); // Relative to apps + } + else + { + // XDG Desktop menu items come with absolute paths, we need to + // extract their relative path and then build a local path. + local = KGlobal::dirs()->relativeLocation("xdgdata-apps", path); + if (!TQDir::isRelativePath(local)) + { + // What now? Use filename only and hope for the best. + local = path.mid(path.findRev('/')+1); + } + local = ::locateLocal("xdgdata-apps", local); + } + } + return local; +} + +bool KDesktopFile::isDesktopFile(const TQString& path) +{ + int len = path.length(); + + if(len > 8 && path.right(8) == TQString::tqfromLatin1(".desktop")) + return true; + else if(len > 7 && path.right(7) == TQString::tqfromLatin1(".kdelnk")) + return true; + else + return false; +} + +bool KDesktopFile::isAuthorizedDesktopFile(const TQString& path) +{ + if (!kapp || kapp->authorize("run_desktop_files")) + return true; + + if (path.isEmpty()) + return false; // Empty paths are not ok. + + if (TQDir::isRelativePath(path)) + return true; // Relative paths are ok. + + KStandardDirs *dirs = KGlobal::dirs(); + if (TQDir::isRelativePath( dirs->relativeLocation("apps", path) )) + return true; + if (TQDir::isRelativePath( dirs->relativeLocation("xdgdata-apps", path) )) + return true; + if (TQDir::isRelativePath( dirs->relativeLocation("services", path) )) + return true; + if (dirs->relativeLocation("data", path).startsWith("kdesktop/Desktop")) + return true; + + kdWarning() << "Access to '" << path << "' denied because of 'run_desktop_files' restriction." << endl; + return false; +} + +TQString KDesktopFile::translatedEntry(const char* key) const +{ + if (hasTranslatedKey(key)) + return readEntry(key); + + if (hasKey(key)) { + TQString value = readEntryUntranslated(key); + TQString fName = fileName(); + fName = fName.mid(fName.findRev('/')+1); + TQString po_lookup_key = TQString::tqfromLatin1(key) + "(" + fName + "): " + value; + TQString po_value = KGlobal::locale()->translate(po_lookup_key.utf8().data()); + + if (po_value == po_lookup_key) + return value; + + return po_value; + } + + return TQString::null; +} + +TQString KDesktopFile::readType() const +{ + return readEntry("Type"); +} + +TQString KDesktopFile::readIcon() const +{ + return readEntry("Icon"); +} + +TQString KDesktopFile::readName() const +{ + return translatedEntry("Name"); +} + +TQString KDesktopFile::readComment() const +{ + return translatedEntry("Comment"); +} + +TQString KDesktopFile::readGenericName() const +{ + return translatedEntry("GenericName"); +} + +TQString KDesktopFile::readPath() const +{ + return readPathEntry("Path"); +} + +TQString KDesktopFile::readDevice() const +{ + return readEntry("Dev"); +} + +TQString KDesktopFile::readURL() const +{ + if (hasDeviceType()) { + TQString device = readDevice(); + KMountPoint::List mountPoints = KMountPoint::possibleMountPoints(); + + for(KMountPoint::List::ConstIterator it = mountPoints.begin(); + it != mountPoints.end(); ++it) + { + KMountPoint *mp = *it; + if (mp->mountedFrom() == device) + { + KURL u; + u.setPath( mp->mountPoint() ); + return u.url(); + } + } + return TQString::null; + } else { + TQString url = readPathEntry("URL"); + if ( !url.isEmpty() && !TQDir::isRelativePath(url) ) + { + // Handle absolute paths as such (i.e. we need to escape them) + KURL u; + u.setPath( url ); + return u.url(); + } + return url; + } +} + +TQStringList KDesktopFile::readActions() const +{ + return readListEntry("Actions", ';'); +} + +void KDesktopFile::setActionGroup(const TQString &group) +{ + setGroup(TQString::tqfromLatin1("Desktop Action ") + group); +} + +bool KDesktopFile::hasActionGroup(const TQString &group) const +{ + return hasGroup(TQString::tqfromLatin1("Desktop Action ") + group); +} + +bool KDesktopFile::hasLinkType() const +{ + return readEntry("Type") == TQString::tqfromLatin1("Link"); +} + +bool KDesktopFile::hasApplicationType() const +{ + return readEntry("Type") == TQString::tqfromLatin1("Application"); +} + +bool KDesktopFile::hasMimeTypeType() const +{ + return readEntry("Type") == TQString::tqfromLatin1("MimeType"); +} + +bool KDesktopFile::hasDeviceType() const +{ + return readEntry("Type") == TQString::tqfromLatin1("FSDev") || + readEntry("Type") == TQString::tqfromLatin1("FSDevice"); +} + +bool KDesktopFile::tryExec() const +{ + // Test for TryExec and "X-KDE-AuthorizeAction" + TQString te = readPathEntry("TryExec"); + + if (!te.isEmpty()) { + if (!TQDir::isRelativePath(te)) { + if (::access(TQFile::encodeName(te), X_OK)) + return false; + } else { + // !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!! + // Environment PATH may contain filenames in 8bit locale cpecified + // encoding (Like a filenames). + TQStringList dirs = TQStringList::split(':', TQFile::decodeName(::getenv("PATH"))); + TQStringList::Iterator it(dirs.begin()); + bool match = false; + for (; it != dirs.end(); ++it) { + TQString fName = *it + "/" + te; + if (::access(TQFile::encodeName(fName), X_OK) == 0) + { + match = true; + break; + } + } + // didn't match at all + if (!match) + return false; + } + } + TQStringList list = readListEntry("X-KDE-AuthorizeAction"); + if (kapp && !list.isEmpty()) + { + for(TQStringList::ConstIterator it = list.begin(); + it != list.end(); + ++it) + { + if (!kapp->authorize((*it).stripWhiteSpace())) + return false; + } + } + + // See also KService::username() + bool su = readBoolEntry("X-KDE-SubstituteUID"); + if (su) + { + TQString user = readEntry("X-KDE-Username"); + if (user.isEmpty()) + user = ::getenv("ADMIN_ACCOUNT"); + if (user.isEmpty()) + user = "root"; + if (!kapp->authorize("user/"+user)) + return false; + } + + return true; +} + +/** + * @return the filename as passed to the constructor. + */ +TQString +KDesktopFile::fileName() const { return backEnd->fileName(); } + +/** + * @return the resource type as passed to the constructor. + */ +TQString +KDesktopFile::resource() const { return backEnd->resource(); } + +TQStringList +KDesktopFile::sortOrder() const +{ + return readListEntry("SortOrder"); +} + +void KDesktopFile::virtual_hook( int id, void* data ) +{ KConfig::virtual_hook( id, data ); } + +TQString KDesktopFile::readDocPath() const +{ + // Depreciated, remove in KDE4 or 5? + // See: http://www.freedesktop.org/Standards/desktop-entry-spec + if(hasKey( "DocPath" )) + return readPathEntry( "DocPath" ); + + return readPathEntry( "X-DocPath" ); +} + +KDesktopFile* KDesktopFile::copyTo(const TQString &file) const +{ + KDesktopFile *config = new KDesktopFile(TQString::null, false); + KConfig::copyTo(file, config); + config->setDesktopGroup(); + return config; +} |