/* This file is part of the KDE libraries Copyright (C) 1999 Sirtaj Singh Kang Copyright (C) 1999 Stephan Kulow Copyright (C) 1999 Waldo Bastian 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. */ #ifndef KSTANDARDDIRS_H #define KSTANDARDDIRS_H #include #include class KConfig; /** * @short Site-independent access to standard KDE directories. * @author Stephan Kulow and Sirtaj Singh Kang * * This is one of the most central classes in kdelibs: It knows where KDE-related files * reside on the user's hard disk. It's meant to be the only one that knows -- * so applications and the end user don't have to. * * Applications should always refer to a file with a resource type. * The application should leave it up to e.g. * KStandardDirs::findResource("apps", "Home.desktop") * to return the desired path /opt/kde/share/applnk/Home.desktop * or ::locate("data", "kgame/background.jpg") to return * /opt/kde/share/apps/kgame/background.jpg * * There are several toplevel prefixes under which files can be located. * One of them is the kdelibs install location, one is the application * install location, and one is $KDEHOME. * Under these toplevel prefixes there are several well-defined suffixes * where specific resource types can be found. * For example, for the resource type @c "html" the suffixes could be * @c share/doc/HTML and @c share/doc/kde/HTML. * The search algorithm tries to locate the file under each prefix-suffix * combination. * * It is also possible to register * absolute paths that KStandardDirs looks up after not finding anything * in the former steps. They can be useful if the user wants to provide * specific directories that aren't in his $KDEHOME directory, for * example for icons. * * Standard resources that kdelibs allocates are: * * @li @c autostart - Autostart directories (both XDG and kde-specific) * @li @c cache - Cached information (e.g. favicons, web-pages) * @li @c cgi - CGIs to run from kdehelp. * @li @c config - Configuration files. * @li @c data - Where applications store data. * @li @c emoticons - Emoticons themes * @li @c exe - Executables in $prefix/bin. findExe() for a function that takes $PATH into account. * @li @c html - HTML documentation. * @li @c icon - Icons, see KIconLoader. * @li @c kcfg - KConfigXT config files. * @li @c lib - Libraries. * @li @c locale - Translation files for KLocale. * @li @c mime - Mime types defined by KDE-specific .desktop files. * @li @c module - Module (dynamically loaded library). * @li @c qtplugins - Qt plugins (dynamically loaded objects for Qt) * @li @c services - Services. * @li @c servicetypes - Service types. * @li @c sound - Application sounds. * @li @c templates - Templates for the "Create new file" functionality. * @li @c wallpaper - Wallpapers. * @li @c tmp - Temporary files (specific for both current host and current user) * @li @c socket - UNIX Sockets (specific for both current host and current user) * @li @c xdgconf-menu - Freedesktop.org standard location for menu layout (.menu) files. * @li @c xdgdata-apps - Freedesktop.org standard location for application desktop files. * @li @c xdgdata-dirs - Freedesktop.org standard location for menu descriptions (.directory files). * @li @c xdgdata-mime - Freedesktop.org standard location for MIME type definitions. * @li @c xdgdata-icon - Freedesktop.org standard location for icons. * @li @c xdgdata-pixmap - Gnome-compatibility location for pixmaps. * * A type that is added by the class KApplication if you use it, is * @c appdata. This one makes the use of the type data a bit easier as it * appends the name of the application. * So while you had to ::locate("data", "appname/filename") so you can * also write ::locate("appdata", "filename") if your KApplication instance * is called @c "appname" (as set via KApplication's constructor or KAboutData, if * you use the global KStandardDirs object KGlobal::dirs()). * Please note though that you cannot use the @c "appdata" * type if you intend to use it in an applet for Kicker because 'appname' would * be @c "Kicker" instead of the applet's name. Therefore, for applets, you've got * to work around this by using ::locate("data", "appletname/filename"). * * KStandardDirs supports the following environment variables: * * @li @c KDEDIRS - This may set an additional number of directory prefixes to * search for resources. The directories should be separated * by ':'. The directories are searched in the order they are * specified. * @li @c KDEHOME - The directory where changes are saved to. This directory is * used to search for resources first. If @c KDEHOME is not * specified it defaults to @c "$HOME/.katana" * @li @c KDEROOTHOME - Like KDEHOME, but used for the root user. * If @c KDEROOTHOME is not set it defaults to the .katana directory in the * home directory of root, usually @c "/root/.katana". * Note that the setting of @c $HOME is ignored in this case. * * @see KGlobalSettings * * * On The Usage Of 'locate' and 'locateLocal' * * Typical KDE applications use resource files in one out of * three ways: * * 1) A resource file is read but is never written. A system * default is supplied but the user can override this * default in his local .kde directory: * * @code * // Code example * myFile = KStandardDirs::locate("appdata", "groups.lst"); * myData = myReadGroups(myFile); // myFile may be null * @endcode * * 2) A resource file is read and written. If the user has no * local version of the file the system default is used. * The resource file is always written to the users local * .kde directory. * * @code * // Code example * myFile = KStandardDirs::locate("appdata", "groups.lst") * myData = myReadGroups(myFile); * ... * doSomething(myData); * ... * myFile = KStandardDirs::locateLocal("appdata", "groups.lst"); * myWriteGroups(myFile, myData); * @endcode * * 3) A resource file is read and written. No system default * is used if the user has no local version of the file. * The resource file is always written to the users local * .kde directory. * * @code * // Code example * myFile = KStandardDirs::locateLocal("appdata", "groups.lst"); * myData = myReadGroups(myFile); * ... * doSomething(myData); * ... * myFile = KStandardDirs::locateLocal("appdata", "groups.lst"); * myWriteGroups(myFile, myData); * @endcode **/ class KDECORE_EXPORT KStandardDirs { public: /** * KStandardDirs' constructor. It just initializes the caches. * Note that you should normally not call this, but use KGlobal::dirs() * instead, in order to reuse the same KStandardDirs object as much as possible. * * Creating other KStandardDirs instances can be useful in other threads. * * Thread safety note: using a shared KStandardDirs instance (such as KGlobal::dirs()) * in multiple threads is thread-safe if you only call the readonly "lookup" methods * (findExe, resourceDirs, findDirs, findResourceDir, findAllResources, saveLocation, * relativeLocation). The methods that modify the object (all those starting with "add", * basically all non-const methods) are obviously not thread-safe; set things up * before creating threads. */ KStandardDirs(); enum SearchOption { NoSearchOptions = 0, Recursive = 1, NoDuplicates = 2, IgnoreExecBit = 4 }; Q_DECLARE_FLAGS( SearchOptions, SearchOption ) /** * KStandardDirs' destructor. */ virtual ~KStandardDirs(); /** * Adds another search dir to front of the @p fsstnd list. * * @li When compiling kdelibs, the prefix is added to this. * @li @c KDEDIRS is taken into account * @li Additional dirs may be loaded from kdeglobals. * * @param dir The directory to append relative paths to. */ void addPrefix( const QString& dir ); /** * Adds another search dir to front of the @c XDG_CONFIG_XXX list * of prefixes. * This prefix is only used for resources that start with @c "xdgconf-" * * @param dir The directory to append relative paths to. */ void addXdgConfigPrefix( const QString& dir ); /** * Adds another search dir to front of the @c XDG_DATA_XXX list * of prefixes. * This prefix is only used for resources that start with @c "xdgdata-" * * @param dir The directory to append relative paths to. */ void addXdgDataPrefix( const QString& dir ); /** * Adds suffixes for types. * * You may add as many as you need, but it is advised that there * is exactly one to make writing definite. * All basic types are added by addKDEDefaults(), * but for those you can add more relative paths as well. * * The later a suffix is added, the higher its priority. Note, that the * suffix should end with / but doesn't have to start with one (as prefixes * should end with one). So adding a suffix for app_pics would look * like KGlobal::dirs()->addResourceType("app_pics", "data", "app/pics"); * * @param type Specifies a short descriptive string to access * files of this type. * @param basetype Specifies an already known type, or 0 if none * @param relativename Specifies a directory relative to the basetype * @param priority if true, the directory is added before any other, * otherwise after * @return true if successful, false otherwise. */ bool addResourceType( const char *type, const char *basetype, const QString& relativename, bool priority = true ); /** * Adds absolute path at the beginning of the search path for * particular types (for example in case of icons where * the user specifies extra paths). * * You shouldn't need this * function in 99% of all cases besides adding user-given * paths. * * @param type Specifies a short descriptive string to access files * of this type. * @param absdir Points to directory where to look for this specific * type. Non-existent directories may be saved but pruned. * @param priority if true, the directory is added before any other, * otherwise after * @return true if successful, false otherwise. */ bool addResourceDir( const char *type, const QString& absdir, bool priority = true ); /** * Tries to find a resource in the following order: * @li All PREFIX/\ paths (most recent first). * @li All absolute paths (most recent first). * * The filename should be a filename relative to the base dir * for resources. So is a way to get the path to libkdecore.la * to findResource("lib", "libkdecore.la"). KStandardDirs will * then look into the subdir lib of all elements of all prefixes * ($KDEDIRS) for a file libkdecore.la and return the path to * the first one it finds (e.g. /opt/kde/lib/libkdecore.la). * You can use the program kde4-config to list all resource types: * @code * $ kde4-config --types * @endcode * * Example: * @code * QString iconfilename=KGlobal::dirs()->findResource("icon",QString("oxygen/22x22/apps/ktip.png")); * @endcode * * @param type The type of the wanted resource * @param filename A relative filename of the resource. * * @return A full path to the filename specified in the second * argument, or QString() if not found. */ QString findResource( const char *type, const QString& filename ) const; /** * Checks whether a resource is restricted as part of the KIOSK * framework. When a resource is restricted it means that user- * specific files in the resource are ignored. * * E.g. by restricting the @c "wallpaper" resource, only system-wide * installed wallpapers will be found by this class. Wallpapers * installed under the @c $KDEHOME directory will be ignored. * * @param type The type of the resource to check * @param relPath A relative path in the resource. * * @return True if the resource is restricted. */ bool isRestrictedResource( const char *type, const QString& relPath=QString() ) const; /** * Returns a number that identifies this version of the resource. * When a change is made to the resource this number will change. * * @param type The type of the wanted resource * @param filename A relative filename of the resource. * @param options If the flags includes Recursive, * all resources are taken into account * otherwise only the one returned by findResource(). * * @return A number identifying the current version of the * resource. */ quint32 calcResourceHash( const char *type, const QString& filename, SearchOptions options = NoSearchOptions) const; /** * Tries to find all directories whose names consist of the * specified type and a relative path. So * findDirs("apps", "Settings") would return * @li /home/joe/.kde/share/applnk/Settings/ * @li /opt/kde/share/applnk/Settings/ * * (from the most local to the most global) * * Note that it appends @c / to the end of the directories, * so you can use this right away as directory names. * * @param type The type of the base directory. * @param reldir Relative directory. * * @return A list of matching directories, or an empty * list if the resource specified is not found. */ QStringList findDirs( const char *type, const QString& reldir ) const; /** * Tries to find the directory the file is in. * It works the same as findResource(), but it doesn't * return the filename but the name of the directory. * * This way the application can access a couple of files * that have been installed into the same directory without * having to look for each file. * * findResourceDir("lib", "libkdecore.la") would return the * path of the subdir libkdecore.la is found first in * (e.g. /opt/kde/lib/) * * @param type The type of the wanted resource * @param filename A relative filename of the resource. * @return The directory where the file specified in the second * argument is located, or QString() if the type * of resource specified is unknown or the resource * cannot be found. */ QString findResourceDir( const char *type, const QString& filename) const; /** * Tries to find all resources with the specified type. * * The function will look into all specified directories * and return all filenames in these directories. * * The "most local" files are returned before the "more global" files. * * @param type The type of resource to locate directories for. * @param filter Only accept filenames that fit to filter. The filter * may consist of an optional directory and a QRegExp * wildcard expression. E.g. "images\*.jpg". * Use QString() if you do not want a filter. * @param options if the flags passed include Recursive, subdirectories * will also be search; if NoDuplicates is passed then only entries with * unique filenames will be returned eliminating duplicates. * * @return List of all the files whose filename matches the * specified filter. */ QStringList findAllResources( const char *type, const QString& filter = QString(), SearchOptions options = NoSearchOptions ) const; /** * Tries to find all resources with the specified type. * * The function will look into all specified directories * and return all filenames (full and relative paths) in * these directories. * * The "most local" files are returned before the "more global" files. * * @param type The type of resource to locate directories for. Can be icon, * lib, pixmap, .... To get a complete list, call * @code * kde4-config --types * @endcode * @param filter Only accept filenames that fit to filter. The filter * may consist of an optional directory and a QRegExp * wildcard expression. E.g. "images\*.jpg". * Use QString() if you do not want a filter. * @param options if the flags passed include Recursive, subdirectories * will also be search; if NoDuplicates is passed then only entries with * unique filenames will be returned eliminating duplicates. * * @param relPaths The list to store the relative paths into * These can be used later to ::locate() the file * * @return List of all the files whose filename matches the * specified filter. */ QStringList findAllResources( const char *type, const QString& filter, SearchOptions options, QStringList &relPaths) const; /** * Returns a QStringList list of pathnames in the system path. * * @param pstr The path which will be searched. If this is * null (default), the @c $PATH environment variable will * be searched. * * @return a QStringList list of pathnames in the system path. */ static QStringList systemPaths( const QString& pstr=QString() ); /** * Finds the executable in the system path. * * A valid executable must * be a file and have its executable bit set. * * @param appname The name of the executable file for which to search. * if this contains a path separator, it will be resolved * according to the current working directory * (shell-like behaviour). * @param pathstr The path which will be searched. If this is * null (default), the @c $PATH environment variable will * be searched. * @param options if the flags passed include IgnoreExecBit the path returned * may not have the executable bit set. * * @return The path of the executable. If it was not found, * it will return QString(). * @see findAllExe() */ static QString findExe( const QString& appname, const QString& pathstr = QString(), SearchOptions options = NoSearchOptions ); /** * Finds all occurrences of an executable in the system path. * * @param list will be filled with the pathnames of all the * executables found. Will be empty if the executable * was not found. * @param appname the name of the executable for which to * search. * @param pathstr the path list which will be searched. If this * is 0 (default), the @c $PATH environment variable will * be searched. * @param options if the flags passed include IgnoreExecBit the path returned * may not have the executable bit set. * * @return The number of executables found, 0 if none were found. * * @see findExe() */ static int findAllExe( QStringList& list, const QString& appname, const QString& pathstr=QString(), SearchOptions options = NoSearchOptions ); /** * Reads customized entries out of the given config object and add * them via addResourceDirs(). * * @param config The object the entries are read from. This should * contain global config files * @return @c true if new config paths have been added * from @p config. **/ bool addCustomized(KConfig *config); /** * This function is used internally by almost all other function as * it serves and fills the directories cache. * * @param type The type of resource * @return The list of possible directories for the specified @p type. * The function updates the cache if possible. If the resource * type specified is unknown, it will return an empty list. * Note, that the directories are assured to exist beside the save * location, which may not exist, but is returned anyway. */ QStringList resourceDirs(const char *type) const; /** * This function will return a list of all the types that KStandardDirs * supports. * * @return All types that KDE supports */ QStringList allTypes() const; /** * Finds a location to save files into for the given type * in the user's home directory. * * @param type The type of location to return. * @param suffix A subdirectory name. * Makes it easier for you to create subdirectories. * You can't pass filenames here, you _have_ to pass * directory names only and add possible filename in * that directory yourself. A directory name always has a * trailing slash ('/'). * @param create If set, saveLocation() will create the directories * needed (including those given by @p suffix). * * @return A path where resources of the specified type should be * saved, or QString() if the resource type is unknown. */ QString saveLocation(const char *type, const QString& suffix = QString(), bool create = true) const; /** * Converts an absolute path to a path relative to a certain * resource. * * If "abs = ::locate(resource, rel)" * then "rel = relativeLocation(resource, abs)" and vice versa. * * @param type The type of resource. * * @param absPath An absolute path to make relative. * * @return A relative path relative to resource @p type that * will find @p absPath. If no such relative path exists, @p absPath * will be returned unchanged. */ QString relativeLocation(const char *type, const QString &absPath); /** * Recursively creates still-missing directories in the given path. * * The resulting permissions will depend on the current umask setting. * permission = mode & ~umask. * * @param dir Absolute path of the directory to be made. * @param mode Directory permissions. * @return true if successful, false otherwise */ static bool makeDir(const QString& dir, int mode = 0755); /** * This returns a default relative path for the standard KDE * resource types. Below is a list of them so you get an idea * of what this is all about. * * @li @c data - @c share/apps * @li @c html - @c share/doc/HTML * @li @c icon - @c share/icon * @li @c config - @c share/config * @li @c pixmap - @c share/pixmaps * @li @c sound - @c share/sounds * @li @c locale - @c share/locale * @li @c services - @c share/kde4/services * @li @c servicetypes - @c share/kde4/servicetypes * @li @c mime - @c share/mimelnk * @li @c cgi - @c cgi-bin * @li @c wallpaper - @c share/wallpapers * @li @c templates - @c share/templates * @li @c exe - @c bin * @li @c lib - @c lib[suffix] * @li @c module - @c lib[suffix]/kde4 * @li @c qtplugins - @c lib[suffix]/kde4/plugins * @li @c kcfg - @c share/config.kcfg * @li @c emoticons - @c share/emoticons * @li @c xdgdata-apps - @c applications * @li @c xdgdata-icon - @c icons * @li @c xdgdata-pixmap - @c pixmaps * @li @c xdgdata-dirs - @c desktop-directories * @li @c xdgdata-mime - @c mime * @li @c xdgconf-menu - @c menus * * @returns Static default for the specified resource. You * should probably be using locate() or locateLocal() * instead. * @see locate() * @see locateLocal() */ /** * @internal (for use by sycoca only) */ QString kfsstnd_prefixes(); /** * @internal (for use by sycoca only) */ QString kfsstnd_xdg_conf_prefixes(); /** * @internal (for use by sycoca only) */ QString kfsstnd_xdg_data_prefixes(); /** * Returns the toplevel directory in which KStandardDirs * will store things. Most likely $HOME/.katana. * Don't use this function if you can use locateLocal() * @return the toplevel directory */ QString localkdedir() const; /** * @return @c $XDG_DATA_HOME * See also http://www.freedesktop.org/standards/basedir/draft/basedir-spec/basedir-spec.html */ QString localxdgdatadir() const; /** * @return @c $XDG_CONFIG_HOME * See also http://www.freedesktop.org/standards/basedir/draft/basedir-spec/basedir-spec.html */ QString localxdgconfdir() const; /** * @return the path where type was installed to by kdelibs. This is an absolute path and only * one out of many search paths */ static QString installPath(const char *type); /** * Checks for existence and accessability of a file or directory. * @param fullPath the path to check. IMPORTANT: must end with a slash if expected to be a directory * (and no slash for a file, obviously). * @return @c true if the directory exists, @c false otherwise */ bool exists(const QString &fullPath) const; /** * Expands all symbolic links and resolves references to * '/./', '/../' and extra '/' characters in @p dirname * and returns the canonicalized absolute pathname. * The resulting path will have no symbolic link, '/./' * or '/../' components. */ QString realPath(const QString &dirname) const; /** * Expands all symbolic links and resolves references to * '/./', '/../' and extra '/' characters in @p filename * and returns the canonicalized absolute pathname. * The resulting path will have no symbolic link, '/./' * or '/../' components. */ static QString realFilePath(const QString &filename); /** * This function is just for convenience. It simply calls * instance->dirs()->\link KStandardDirs::findResource() findResource\endlink(type, filename). * * @param type The type of the wanted resource, see KStandardDirs * @param filename A relative filename of the resource * @param cData The KComponentData object * * @return A full path to the filename specified in the second * argument, or QString() if not found **/ static QString locate( const char *type, const QString& filename, const KComponentData &cData = KGlobal::mainComponent() ); /** * This function is much like locate. However it returns a * filename suitable for writing to. No check is made if the * specified @p filename actually exists. Missing directories * are created. If @p filename is only a directory, without a * specific file, @p filename must have a trailing slash. * * @param type The type of the wanted resource, see KStandardDirs * @param filename A relative filename of the resource * @param cData The KComponentData object * * @return A full path to the filename specified in the second * argument, or QString() if not found **/ static QString locateLocal( const char *type, const QString& filename, const KComponentData &cData = KGlobal::mainComponent() ); /** * This function is much like locate. No check is made if the * specified filename actually exists. Missing directories * are created if @p createDir is true. If @p filename is only * a directory, without a specific file, @p filename must have * a trailing slash. * * @param type The type of the wanted resource, see KStandardDirs * @param filename A relative filename of the resource * @param createDir If @c true, missing directories are created, * if @c false, no directory is created * @param cData The KComponentData object * * @return A full path to the filename specified in the second * argument, or QString() if not found **/ static QString locateLocal( const char *type, const QString& filename, bool createDir, const KComponentData &cData = KGlobal::mainComponent() ); /** * Check, if a file may be accessed in a given mode. * This is a wrapper around the access() system call. * checkAccess() calls access() with the given parameters. * If this is OK, checkAccess() returns true. If not, and W_OK * is part of mode, it is checked if there is write access to * the directory. If yes, checkAccess() returns true. * In all other cases checkAccess() returns false. * * Other than access() this function EXPLICITLY ignores non-existent * files if checking for write access. * * @param pathname The full path of the file you want to test * @param mode The access mode, as in the access() system call. * @return Whether the access is allowed, true = Access allowed */ static bool checkAccess(const QString& pathname, int mode); private: // Disallow assignment and copy-construction KStandardDirs( const KStandardDirs& ); KStandardDirs& operator= ( const KStandardDirs& ); class KStandardDirsPrivate; KStandardDirsPrivate* const d; // Like their public counter parts but with an extra priority argument // If priority is true, the directory is added directly after // $KDEHOME/$XDG_DATA_HOME/$XDG_CONFIG_HOME void addPrefix( const QString& dir, bool priority ); void addXdgConfigPrefix( const QString& dir, bool priority ); void addXdgDataPrefix( const QString& dir, bool priority ); void addKDEDefaults(); void addResourcesFrom_krcdirs(); }; Q_DECLARE_OPERATORS_FOR_FLAGS(KStandardDirs::SearchOptions) #endif // KSTANDARDDIRS_H